Skip to content

Commit 2479b1f

Browse files
authored
Support for http4k (#20)
* Support for http4k * Update README
1 parent e471300 commit 2479b1f

File tree

6 files changed

+222
-57
lines changed

6 files changed

+222
-57
lines changed

README.md

Lines changed: 67 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,17 @@ The goal of this project is to provide a simple OAuth2 library which can be impl
44

55
Configuring the oauth2 server for any framework should be simple and understandable.
66
It encourages to adapt to existing implementations instead the other way around.
7-
# Maven
7+
8+
# Frameworks
9+
## Setup
10+
### Maven
11+
First define the version to be used and set it as a property
12+
```xml
13+
<properties>
14+
<myndocs.oauth.version>0.2.0</myndocs.oauth.version>
15+
</properties>
16+
```
17+
818
Include the following repository in order to download the artifacts
919
```xml
1020
<repositories>
@@ -15,40 +25,39 @@ Include the following repository in order to download the artifacts
1525
</repositories>
1626
```
1727

18-
Setting the version in properties
19-
```xml
20-
<properties>
21-
<myndocs.oauth.version>0.2.0</myndocs.oauth.version>
22-
</properties>
23-
```
24-
# Frameworks
25-
## Ktor
26-
Include the following dependencies
27-
28+
For the frameworks examples we need at least the following dependencies:
2829
```xml
2930
<dependency>
3031
<groupId>nl.myndocs</groupId>
3132
<artifactId>oauth2-server-core</artifactId>
3233
<version>${myndocs.oauth.version}</version>
3334
</dependency>
35+
36+
<!-- In memory dependencies -->
3437
<dependency>
3538
<groupId>nl.myndocs</groupId>
36-
<artifactId>oauth2-server-ktor</artifactId>
39+
<artifactId>oauth2-server-client-inmemory</artifactId>
3740
<version>${myndocs.oauth.version}</version>
3841
</dependency>
3942
<dependency>
4043
<groupId>nl.myndocs</groupId>
41-
<artifactId>oauth2-server-client-inmemory</artifactId>
44+
<artifactId>oauth2-server-identity-inmemory</artifactId>
4245
<version>${myndocs.oauth.version}</version>
4346
</dependency>
4447
<dependency>
4548
<groupId>nl.myndocs</groupId>
46-
<artifactId>oauth2-server-identity-inmemory</artifactId>
49+
<artifactId>oauth2-server-token-store-inmemory</artifactId>
4750
<version>${myndocs.oauth.version}</version>
4851
</dependency>
52+
```
53+
54+
## Ktor
55+
The following dependency is required along with the dependencies described in Setup
56+
57+
```xml
4958
<dependency>
5059
<groupId>nl.myndocs</groupId>
51-
<artifactId>oauth2-server-token-store-inmemory</artifactId>
60+
<artifactId>oauth2-server-ktor</artifactId>
5261
<version>${myndocs.oauth.version}</version>
5362
</dependency>
5463
```
@@ -83,33 +92,13 @@ embeddedServer(Netty, 8080) {
8392
```
8493

8594
## Javalin
86-
Include the following dependencies
95+
The following dependency is required along with the dependencies described in Setup
8796
```xml
88-
<dependency>
89-
<groupId>nl.myndocs</groupId>
90-
<artifactId>oauth2-server-core</artifactId>
91-
<version>${myndocs.oauth.version}</version>
92-
</dependency>
93-
<dependency>
94-
<groupId>nl.myndocs</groupId>
95-
<artifactId>oauth2-server-client-inmemory</artifactId>
96-
<version>${myndocs.oauth.version}</version>
97-
</dependency>
9897
<dependency>
9998
<groupId>nl.myndocs</groupId>
10099
<artifactId>oauth2-server-javalin</artifactId>
101100
<version>${myndocs.oauth.version}</version>
102101
</dependency>
103-
<dependency>
104-
<groupId>nl.myndocs</groupId>
105-
<artifactId>oauth2-server-identity-inmemory</artifactId>
106-
<version>${myndocs.oauth.version}</version>
107-
</dependency>
108-
<dependency>
109-
<groupId>nl.myndocs</groupId>
110-
<artifactId>oauth2-server-token-store-inmemory</artifactId>
111-
<version>${myndocs.oauth.version}</version>
112-
</dependency>
113102
```
114103

115104
In memory example for Javalin:
@@ -143,33 +132,13 @@ Javalin.create().apply {
143132
```
144133

145134
## Spark java
146-
Include the following dependencies
135+
The following dependency is required along with the dependencies described in Setup
147136
```xml
148-
<dependency>
149-
<groupId>nl.myndocs</groupId>
150-
<artifactId>oauth2-server-core</artifactId>
151-
<version>${myndocs.oauth.version}</version>
152-
</dependency>
153-
<dependency>
154-
<groupId>nl.myndocs</groupId>
155-
<artifactId>oauth2-server-client-inmemory</artifactId>
156-
<version>${myndocs.oauth.version}</version>
157-
</dependency>
158137
<dependency>
159138
<groupId>nl.myndocs</groupId>
160139
<artifactId>oauth2-server-sparkjava</artifactId>
161140
<version>${myndocs.oauth.version}</version>
162141
</dependency>
163-
<dependency>
164-
<groupId>nl.myndocs</groupId>
165-
<artifactId>oauth2-server-identity-inmemory</artifactId>
166-
<version>${myndocs.oauth.version}</version>
167-
</dependency>
168-
<dependency>
169-
<groupId>nl.myndocs</groupId>
170-
<artifactId>oauth2-server-token-store-inmemory</artifactId>
171-
<version>${myndocs.oauth.version}</version>
172-
</dependency>
173142
```
174143

175144
In memory example for Spark java:
@@ -198,7 +167,48 @@ Oauth2Server.configureOauth2Server {
198167
}
199168
}
200169
```
170+
## http4k
171+
The following dependency is required along with the dependencies described in Setup
172+
```xml
173+
<dependency>
174+
<groupId>nl.myndocs</groupId>
175+
<artifactId>oauth2-server-http4k</artifactId>
176+
<version>${myndocs.oauth.version}</version>
177+
</dependency>
178+
```
179+
180+
In memory example for http4k:
181+
```kotlin
182+
val app: HttpHandler = routes(
183+
"/ping" bind GET to { _: Request -> Response(Status.OK).body("pong!") }
184+
) `enable oauth2` {
185+
tokenService = Oauth2TokenServiceBuilder.build {
186+
identityService = InMemoryIdentity()
187+
.identity {
188+
username = "foo"
189+
password = "bar"
190+
}
191+
clientService = InMemoryClient()
192+
.client {
193+
clientId = "testapp"
194+
clientSecret = "testpass"
195+
scopes = setOf("trusted")
196+
redirectUris = setOf("http://localhost:8080/callback")
197+
authorizedGrantTypes = setOf(
198+
AuthorizedGrantType.AUTHORIZATION_CODE,
199+
AuthorizedGrantType.PASSWORD,
200+
AuthorizedGrantType.IMPLICIT,
201+
AuthorizedGrantType.REFRESH_TOKEN
202+
)
203+
}
204+
tokenStore = InMemoryTokenStore()
205+
}
206+
}
207+
208+
app.asServer(Jetty(9000)).start()
209+
```
201210

211+
**Note:** `/ping` is only added for demonstration for own defined routes.
202212
# Custom implementation
203213
## Identity service
204214
Users can be authenticate through the identity service. In OAuth2 terms this would be the resource owner.

oauth2-server-http4k/pom.xml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>kotlin-oauth2-server</artifactId>
7+
<groupId>nl.myndocs</groupId>
8+
<version>0.2.1-SNAPSHOT</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<artifactId>oauth2-server-http4k</artifactId>
13+
14+
<dependencies>
15+
<dependency>
16+
<groupId>org.http4k</groupId>
17+
<artifactId>http4k-core</artifactId>
18+
<version>3.37.1</version>
19+
</dependency>
20+
<dependency>
21+
<groupId>nl.myndocs</groupId>
22+
<artifactId>oauth2-server-core</artifactId>
23+
<version>${project.version}</version>
24+
<scope>provided</scope>
25+
</dependency>
26+
<dependency>
27+
<groupId>nl.myndocs</groupId>
28+
<artifactId>oauth2-server-json</artifactId>
29+
<version>${project.version}</version>
30+
<classifier>shaded</classifier>
31+
</dependency>
32+
</dependencies>
33+
34+
<repositories>
35+
<repository>
36+
<id>http4k</id>
37+
<url>http://dl.bintray.com/http4k</url>
38+
</repository>
39+
</repositories>
40+
</project>
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package nl.myndocs.oauth2.http4k
2+
3+
import nl.myndocs.oauth2.config.ConfigurationBuilder
4+
import nl.myndocs.oauth2.http4k.request.Http4kCallContext
5+
import nl.myndocs.oauth2.http4k.response.ResponseBuilder
6+
import org.http4k.core.Method
7+
import org.http4k.core.Request
8+
import org.http4k.routing.RoutingHttpHandler
9+
import org.http4k.routing.bind
10+
import org.http4k.routing.routes
11+
12+
infix fun RoutingHttpHandler.`enable oauth2`(configurationCallback: ConfigurationBuilder.Configuration.() -> Unit): RoutingHttpHandler {
13+
val configuration = ConfigurationBuilder.build(configurationCallback)
14+
15+
val callRouter = configuration.callRouter
16+
17+
return routes(
18+
this,
19+
callRouter.tokenEndpoint bind Method.POST to { request: Request ->
20+
val responseBuilder = ResponseBuilder()
21+
val callContext = Http4kCallContext(request, responseBuilder)
22+
callRouter.route(callContext, configuration.authorizerFactory(callContext))
23+
24+
responseBuilder.build()
25+
},
26+
callRouter.authorizeEndpoint bind Method.GET to { request: Request ->
27+
val responseBuilder = ResponseBuilder()
28+
val callContext = Http4kCallContext(request, responseBuilder)
29+
callRouter.route(callContext, configuration.authorizerFactory(callContext))
30+
31+
responseBuilder.build()
32+
},
33+
callRouter.userInfoEndpoint bind Method.GET to { request: Request ->
34+
val responseBuilder = ResponseBuilder()
35+
val callContext = Http4kCallContext(request, responseBuilder)
36+
callRouter.route(callContext, configuration.authorizerFactory(callContext))
37+
38+
responseBuilder.build()
39+
}
40+
)
41+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package nl.myndocs.oauth2.http4k.request
2+
3+
import nl.myndocs.oauth2.http4k.response.ResponseBuilder
4+
import nl.myndocs.oauth2.json.JsonMapper
5+
import nl.myndocs.oauth2.request.CallContext
6+
import org.http4k.core.Request
7+
import org.http4k.core.body.form
8+
import org.http4k.core.queries
9+
10+
class Http4kCallContext(val request: Request, val responseBuilder: ResponseBuilder) : CallContext {
11+
override val path: String = request.uri.path
12+
override val method: String = request.method.name
13+
override val headers: Map<String, String> = request.headers
14+
.toMap()
15+
.filterValues { it != null }
16+
.map { it.key.toLowerCase() to it.value!! }
17+
.toMap()
18+
override val queryParameters: Map<String, String> = request.uri.queries()
19+
.toMap()
20+
.filterValues { it != null }
21+
.mapValues { it.value!! }
22+
.map { it.key.toLowerCase() to it.value }
23+
.toMap()
24+
25+
override val formParameters: Map<String, String> = request.form()
26+
.toMap()
27+
.filterValues { it != null }
28+
.mapValues { it.value!! }
29+
.map { it.key.toLowerCase() to it.value }
30+
.toMap()
31+
32+
override fun respondStatus(statusCode: Int) {
33+
responseBuilder.statusCode = statusCode
34+
}
35+
36+
override fun respondHeader(name: String, value: String) {
37+
responseBuilder.headers[name] = value
38+
}
39+
40+
override fun respondJson(content: Any) {
41+
responseBuilder.body = JsonMapper.toJson(content)
42+
}
43+
44+
override fun redirect(uri: String) {
45+
responseBuilder.statusCode = 302
46+
responseBuilder.headers["Location"] = uri
47+
}
48+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package nl.myndocs.oauth2.http4k.response
2+
3+
import org.http4k.core.Response
4+
import org.http4k.core.Status
5+
6+
class ResponseBuilder(
7+
var statusCode: Int = 200,
8+
var headers: MutableMap<String, String> = mutableMapOf(),
9+
var body: String = ""
10+
) {
11+
12+
fun build(): Response {
13+
var response = Response(
14+
Status(statusCode, "")
15+
)
16+
17+
for (header in headers) {
18+
response = response.header(header.key, header.value)
19+
}
20+
21+
response = response.body(body)
22+
23+
return response
24+
}
25+
}

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
<module>oauth2-server-token-store-inmemory</module>
2525
<module>oauth2-server-javalin</module>
2626
<module>oauth2-server-sparkjava</module>
27+
<module>oauth2-server-http4k</module>
2728
</modules>
2829

2930
<dependencies>

0 commit comments

Comments
 (0)