Skip to content

Commit 6ad42ac

Browse files
authored
Merge pull request #49 from myndocs/release/0.4.0
Release/0.4.0
2 parents 30f4671 + 5ec6118 commit 6ad42ac

39 files changed

+989
-750
lines changed

README.md

+70-186
Original file line numberDiff line numberDiff line change
@@ -51,210 +51,94 @@ For the frameworks examples we need at least the following dependencies:
5151
</dependency>
5252
```
5353

54-
## Ktor
55-
The following dependency is required along with the dependencies described in Setup
56-
57-
```xml
58-
<dependency>
59-
<groupId>nl.myndocs</groupId>
60-
<artifactId>oauth2-server-ktor</artifactId>
61-
<version>${myndocs.oauth.version}</version>
62-
</dependency>
63-
```
64-
65-
In memory example for Ktor:
54+
### Framework implementation
55+
The following frameworks are supported:
56+
- [Ktor](docs/ktor.md)
57+
- [Javalin](docs/javalin.md)
58+
- [http4k](docs/http4k.md)
59+
- [Sparkjava](docs/sparkjava.md)
60+
61+
## Configuration
62+
### Routing
63+
Default endpoints are configured:
64+
65+
| Type | Relative url |
66+
| ----- | ------------- |
67+
| token | /oauth/token |
68+
| authorize | /oauth/authorize |
69+
| token info | /oauth/tokeninfo |
70+
71+
These values can be overridden:
6672
```kotlin
67-
embeddedServer(Netty, 8080) {
68-
install(Oauth2ServerFeature) {
69-
tokenService = Oauth2TokenServiceBuilder.build {
70-
identityService = InMemoryIdentity()
71-
.identity {
72-
username = "foo"
73-
password = "bar"
74-
}
75-
clientService = InMemoryClient()
76-
.client {
77-
clientId = "testapp"
78-
clientSecret = "testpass"
79-
scopes = setOf("trusted")
80-
redirectUris = setOf("https://localhost:8080/callback")
81-
authorizedGrantTypes = setOf(
82-
AuthorizedGrantType.AUTHORIZATION_CODE,
83-
AuthorizedGrantType.PASSWORD,
84-
AuthorizedGrantType.IMPLICIT,
85-
AuthorizedGrantType.REFRESH_TOKEN
86-
)
87-
}
88-
tokenStore = InMemoryTokenStore()
89-
}
90-
}
91-
}.start(wait = true)
73+
tokenEndpoint = "/custom/token"
74+
authorizationEndpoint = "/custom/authorize"
75+
tokenInfoEndpoint = "/custom/tokeninfo"
9276
```
9377

94-
## Javalin
95-
The following dependency is required along with the dependencies described in Setup
96-
```xml
97-
<dependency>
98-
<groupId>nl.myndocs</groupId>
99-
<artifactId>oauth2-server-javalin</artifactId>
100-
<version>${myndocs.oauth.version}</version>
101-
</dependency>
102-
```
78+
### In memory
79+
In memory implementations are provided to easily setup the project.
10380

104-
In memory example for Javalin:
81+
#### Identity
82+
On the `InMemoryIdentity` identities can be registered. These are normally your users:
10583
```kotlin
106-
Javalin.create().apply {
107-
enableOauthServer {
108-
tokenService = Oauth2TokenServiceBuilder.build {
109-
identityService = InMemoryIdentity()
110-
.identity {
111-
username = "foo"
112-
password = "bar"
113-
}
114-
clientService = InMemoryClient()
115-
.client {
116-
clientId = "testapp"
117-
clientSecret = "testpass"
118-
scopes = setOf("trusted")
119-
redirectUris = setOf("https://localhost:7000/callback")
120-
authorizedGrantTypes = setOf(
121-
AuthorizedGrantType.AUTHORIZATION_CODE,
122-
AuthorizedGrantType.PASSWORD,
123-
AuthorizedGrantType.IMPLICIT,
124-
AuthorizedGrantType.REFRESH_TOKEN
125-
)
126-
}
127-
tokenStore = InMemoryTokenStore()
128-
}
129-
84+
identityService = InMemoryIdentity()
85+
.identity {
86+
username = "foo-1"
87+
password = "bar"
13088
}
131-
}.start(7000)
132-
```
133-
134-
## Spark java
135-
The following dependency is required along with the dependencies described in Setup
136-
```xml
137-
<dependency>
138-
<groupId>nl.myndocs</groupId>
139-
<artifactId>oauth2-server-sparkjava</artifactId>
140-
<version>${myndocs.oauth.version}</version>
141-
</dependency>
142-
```
143-
144-
In memory example for Spark java:
145-
```kotlin
146-
Oauth2Server.configureOauth2Server {
147-
tokenService = Oauth2TokenServiceBuilder.build {
148-
identityService = InMemoryIdentity()
149-
.identity {
150-
username = "foo"
151-
password = "bar"
152-
}
153-
clientService = InMemoryClient()
154-
.client {
155-
clientId = "testapp"
156-
clientSecret = "testpass"
157-
scopes = setOf("trusted")
158-
redirectUris = setOf("https://localhost:4567/callback")
159-
authorizedGrantTypes = setOf(
160-
AuthorizedGrantType.AUTHORIZATION_CODE,
161-
AuthorizedGrantType.PASSWORD,
162-
AuthorizedGrantType.IMPLICIT,
163-
AuthorizedGrantType.REFRESH_TOKEN
164-
)
165-
}
166-
tokenStore = InMemoryTokenStore()
89+
.identity {
90+
username = "foo-2"
91+
password = "bar"
16792
}
168-
}
169-
```
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>
17893
```
17994

180-
In memory example for http4k:
95+
#### Client
96+
On the `InMemoryClient` clients can be registered:
18197
```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-
}
98+
clientService = InMemoryClient()
99+
.client {
100+
clientId = "app1-client"
101+
clientSecret = "testpass"
102+
scopes = setOf("admin")
103+
redirectUris = setOf("https://localhost:8080/callback")
104+
authorizedGrantTypes = setOf(
105+
AuthorizedGrantType.AUTHORIZATION_CODE,
106+
AuthorizedGrantType.PASSWORD,
107+
AuthorizedGrantType.IMPLICIT,
108+
AuthorizedGrantType.REFRESH_TOKEN
109+
)
206110
}
207-
208-
app.asServer(Jetty(9000)).start()
111+
.client {
112+
clientId = "app2-client"
113+
clientSecret = "testpass"
114+
scopes = setOf("user")
115+
redirectUris = setOf("https://localhost:8080/callback")
116+
authorizedGrantTypes = setOf(
117+
AuthorizedGrantType.AUTHORIZATION_CODE
118+
)
119+
}
209120
```
210121

211-
**Note:** `/ping` is only added for demonstration for own defined routes.
212-
# Custom implementation
213-
## Identity service
214-
Users can be authenticate through the identity service. In OAuth2 terms this would be the resource owner.
215-
122+
#### Token store
123+
The `InMemoryTokenStore` stores all kinds of tokens.
216124
```kotlin
217-
fun identityOf(forClient: Client, username: String): Identity?
218-
219-
fun validCredentials(forClient: Client, identity: Identity, password: String): Boolean
220-
221-
fun allowedScopes(forClient: Client, identity: Identity, scopes: Set<String>): Set<String>
125+
tokenStore = InMemoryTokenStore()
222126
```
223127

224-
Each of the methods that needs to be implemented contains `Client`. This could give you extra flexibility.
225-
For example you could have user base per client, instead of have users over all clients.
226-
227-
## Client service
228-
Client service is similar to the identity service.
128+
### Converters
229129

130+
#### Access token converter
131+
By default `UUIDAccessTokenConverter` is used. With a default time-out of 1 hour. To override the time-out for example to half an hour:
230132
```kotlin
231-
fun clientOf(clientId: String): Client?
232-
233-
fun validClient(client: Client, clientSecret: String): Boolean
133+
accessTokenConverter = UUIDAccessTokenConverter(1800)
234134
```
235-
236-
## Token store
237-
The following methods have to be implemented for a token store.
238-
135+
#### Refresh token converter
136+
By default `UUIDRefreshTokenConverter` is used. With a default time-out of 1 hour. To override the time-out for example to half an hour:
239137
```kotlin
240-
fun storeAccessToken(accessToken: AccessToken)
241-
242-
fun accessToken(token: String): AccessToken?
243-
244-
fun revokeAccessToken(token: String)
245-
246-
fun storeCodeToken(codeToken: CodeToken)
247-
248-
fun codeToken(token: String): CodeToken?
249-
250-
fun consumeCodeToken(token: String): CodeToken?
251-
252-
fun storeRefreshToken(refreshToken: RefreshToken)
253-
254-
fun refreshToken(token: String): RefreshToken?
255-
256-
fun revokeRefreshToken(token: String)
257-
138+
refreshTokenConverter = UUIDRefreshTokenConverter(1800)
258139
```
259-
260-
When `AccessToken` is passed to `storeAccessToken` and it contains a `RefreshToken`, then `storeAccessToken` is also responsible for saving the refresh token.
140+
#### Code token converter
141+
By default `UUIDCodeTokenConverter` is used. With a default time-out of 5 minutes. To override the time-out for example 2 minutes:
142+
```kotlin
143+
codeTokenConverter = UUIDCodeTokenConverter(120)
144+
```

docs/http4k.md

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# http4k
2+
3+
## Dependencies
4+
```xml
5+
<dependency>
6+
<groupId>nl.myndocs</groupId>
7+
<artifactId>oauth2-server-http4k</artifactId>
8+
<version>${myndocs.oauth.version}</version>
9+
</dependency>
10+
```
11+
12+
## Implementation
13+
```kotlin
14+
val app: HttpHandler = routes(
15+
"/ping" bind GET to { _: Request -> Response(Status.OK).body("pong!") }
16+
) `enable oauth2` {
17+
identityService = InMemoryIdentity()
18+
.identity {
19+
username = "foo"
20+
password = "bar"
21+
}
22+
clientService = InMemoryClient()
23+
.client {
24+
clientId = "testapp"
25+
clientSecret = "testpass"
26+
scopes = setOf("trusted")
27+
redirectUris = setOf("http://localhost:8080/callback")
28+
authorizedGrantTypes = setOf(
29+
AuthorizedGrantType.AUTHORIZATION_CODE,
30+
AuthorizedGrantType.PASSWORD,
31+
AuthorizedGrantType.IMPLICIT,
32+
AuthorizedGrantType.REFRESH_TOKEN
33+
)
34+
}
35+
tokenStore = InMemoryTokenStore()
36+
}
37+
38+
app.asServer(Jetty(9000)).start()
39+
```

docs/javalin.md

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Javalin
2+
3+
## Dependencies
4+
```xml
5+
<dependency>
6+
<groupId>nl.myndocs</groupId>
7+
<artifactId>oauth2-server-javalin</artifactId>
8+
<version>${myndocs.oauth.version}</version>
9+
</dependency>
10+
```
11+
12+
## Implementation
13+
```kotlin
14+
Javalin.create().apply {
15+
enableOauthServer {
16+
identityService = InMemoryIdentity()
17+
.identity {
18+
username = "foo"
19+
password = "bar"
20+
}
21+
clientService = InMemoryClient()
22+
.client {
23+
clientId = "testapp"
24+
clientSecret = "testpass"
25+
scopes = setOf("trusted")
26+
redirectUris = setOf("https://localhost:7000/callback")
27+
authorizedGrantTypes = setOf(
28+
AuthorizedGrantType.AUTHORIZATION_CODE,
29+
AuthorizedGrantType.PASSWORD,
30+
AuthorizedGrantType.IMPLICIT,
31+
AuthorizedGrantType.REFRESH_TOKEN
32+
)
33+
}
34+
tokenStore = InMemoryTokenStore()
35+
}
36+
}.start(7000)
37+
```

docs/ktor.md

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Ktor
2+
3+
## Dependencies
4+
5+
```xml
6+
<dependency>
7+
<groupId>nl.myndocs</groupId>
8+
<artifactId>oauth2-server-ktor</artifactId>
9+
<version>${myndocs.oauth.version}</version>
10+
</dependency>
11+
```
12+
13+
## Implementation
14+
```kotlin
15+
embeddedServer(Netty, 8080) {
16+
install(Oauth2ServerFeature) {
17+
identityService = InMemoryIdentity()
18+
.identity {
19+
username = "foo"
20+
password = "bar"
21+
}
22+
clientService = InMemoryClient()
23+
.client {
24+
clientId = "testapp"
25+
clientSecret = "testpass"
26+
scopes = setOf("trusted")
27+
redirectUris = setOf("https://localhost:8080/callback")
28+
authorizedGrantTypes = setOf(
29+
AuthorizedGrantType.AUTHORIZATION_CODE,
30+
AuthorizedGrantType.PASSWORD,
31+
AuthorizedGrantType.IMPLICIT,
32+
AuthorizedGrantType.REFRESH_TOKEN
33+
)
34+
}
35+
tokenStore = InMemoryTokenStore()
36+
}
37+
}.start(wait = true)
38+
```

0 commit comments

Comments
 (0)