Skip to content

Commit a4c4915

Browse files
authored
Merge pull request #22 from adhesivee/release/0.2.1
Release/0.2.1
2 parents 51327f5 + cea4944 commit a4c4915

File tree

15 files changed

+246
-84
lines changed

15 files changed

+246
-84
lines changed

README.md

Lines changed: 68 additions & 58 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.1</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.
@@ -247,4 +257,4 @@ fun revokeRefreshToken(token: String)
247257

248258
```
249259

250-
When `AccessToken` is passed to `storeAccessToken` and it contains a `RefreshToken`, then `storeAccessToken` is also responsible for saving the refresh token.
260+
When `AccessToken` is passed to `storeAccessToken` and it contains a `RefreshToken`, then `storeAccessToken` is also responsible for saving the refresh token.

oauth2-server-client-inmemory/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<artifactId>kotlin-oauth2-server</artifactId>
77
<groupId>nl.myndocs</groupId>
8-
<version>0.2.0</version>
8+
<version>0.2.1</version>
99
</parent>
1010
<modelVersion>4.0.0</modelVersion>
1111

oauth2-server-core/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<artifactId>kotlin-oauth2-server</artifactId>
77
<groupId>nl.myndocs</groupId>
8-
<version>0.2.0</version>
8+
<version>0.2.1</version>
99
</parent>
1010
<modelVersion>4.0.0</modelVersion>
1111

oauth2-server-core/src/main/java/nl/myndocs/oauth2/Oauth2TokenService.kt

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,7 @@ class Oauth2TokenService(
4444
throw InvalidRequestException(INVALID_REQUEST_FIELD_MESSAGE.format("password"))
4545
}
4646

47-
val requestedClient = clientService.clientOf(
48-
passwordGrantRequest.clientId!!
49-
)!!
47+
val requestedClient = clientService.clientOf(passwordGrantRequest.clientId!!) ?: throw InvalidClientException()
5048

5149
val authorizedGrantType = AuthorizedGrantType.PASSWORD
5250
if (!requestedClient.authorizedGrantTypes.contains(authorizedGrantType)) {
@@ -134,7 +132,7 @@ class Oauth2TokenService(
134132
throw InvalidGrantException()
135133
}
136134

137-
val client = clientService.clientOf(refreshToken.clientId)!!
135+
val client = clientService.clientOf(refreshToken.clientId) ?: throw InvalidClientException()
138136

139137
val authorizedGrantType = AuthorizedGrantType.REFRESH_TOKEN
140138
if (!client.authorizedGrantTypes.contains(authorizedGrantType)) {
@@ -293,9 +291,10 @@ class Oauth2TokenService(
293291
}
294292

295293
override fun userInfo(accessToken: String): UserInfo {
296-
val storedAccessToken = tokenStore.accessToken(accessToken)!!
297-
val client = clientService.clientOf(storedAccessToken.clientId)!!
298-
val identity = identityService.identityOf(client, storedAccessToken.username)!!
294+
val storedAccessToken = tokenStore.accessToken(accessToken) ?: throw InvalidGrantException()
295+
val client = clientService.clientOf(storedAccessToken.clientId) ?: throw InvalidClientException()
296+
val identity = identityService.identityOf(client, storedAccessToken.username)
297+
?: throw InvalidIdentityException()
299298

300299
return UserInfo(
301300
identity,
@@ -305,17 +304,15 @@ class Oauth2TokenService(
305304
}
306305

307306
private fun throwExceptionIfUnverifiedClient(clientRequest: ClientRequest) {
308-
if (clientRequest.clientId == null) {
309-
throw InvalidRequestException(INVALID_REQUEST_FIELD_MESSAGE.format("client_id"))
310-
}
307+
val clientId = clientRequest.clientId
308+
?: throw InvalidRequestException(INVALID_REQUEST_FIELD_MESSAGE.format("client_id"))
311309

312-
if (clientRequest.clientSecret == null) {
313-
throw InvalidRequestException(INVALID_REQUEST_FIELD_MESSAGE.format("client_secret"))
314-
}
310+
val clientSecret = clientRequest.clientSecret
311+
?: throw InvalidRequestException(INVALID_REQUEST_FIELD_MESSAGE.format("client_secret"))
315312

316-
val client = clientService.clientOf(clientRequest.clientId!!) ?: throw InvalidClientException()
313+
val client = clientService.clientOf(clientId) ?: throw InvalidClientException()
317314

318-
if (!clientService.validClient(client, clientRequest.clientSecret!!)) {
315+
if (!clientService.validClient(client, clientSecret)) {
319316
throw InvalidClientException()
320317
}
321318
}

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</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+
}

0 commit comments

Comments
 (0)