Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
225 changes: 21 additions & 204 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,210 +51,27 @@ For the frameworks examples we need at least the following dependencies:
</dependency>
```

## Ktor
The following dependency is required along with the dependencies described in Setup

```xml
<dependency>
<groupId>nl.myndocs</groupId>
<artifactId>oauth2-server-ktor</artifactId>
<version>${myndocs.oauth.version}</version>
</dependency>
```

In memory example for Ktor:
```kotlin
embeddedServer(Netty, 8080) {
install(Oauth2ServerFeature) {
tokenService = Oauth2TokenServiceBuilder.build {
identityService = InMemoryIdentity()
.identity {
username = "foo"
password = "bar"
}
clientService = InMemoryClient()
.client {
clientId = "testapp"
clientSecret = "testpass"
scopes = setOf("trusted")
redirectUris = setOf("https://localhost:8080/callback")
authorizedGrantTypes = setOf(
AuthorizedGrantType.AUTHORIZATION_CODE,
AuthorizedGrantType.PASSWORD,
AuthorizedGrantType.IMPLICIT,
AuthorizedGrantType.REFRESH_TOKEN
)
}
tokenStore = InMemoryTokenStore()
}
}
}.start(wait = true)
```

## Javalin
The following dependency is required along with the dependencies described in Setup
```xml
<dependency>
<groupId>nl.myndocs</groupId>
<artifactId>oauth2-server-javalin</artifactId>
<version>${myndocs.oauth.version}</version>
</dependency>
```

In memory example for Javalin:
```kotlin
Javalin.create().apply {
enableOauthServer {
tokenService = Oauth2TokenServiceBuilder.build {
identityService = InMemoryIdentity()
.identity {
username = "foo"
password = "bar"
}
clientService = InMemoryClient()
.client {
clientId = "testapp"
clientSecret = "testpass"
scopes = setOf("trusted")
redirectUris = setOf("https://localhost:7000/callback")
authorizedGrantTypes = setOf(
AuthorizedGrantType.AUTHORIZATION_CODE,
AuthorizedGrantType.PASSWORD,
AuthorizedGrantType.IMPLICIT,
AuthorizedGrantType.REFRESH_TOKEN
)
}
tokenStore = InMemoryTokenStore()
}

}
}.start(7000)
```

## Spark java
The following dependency is required along with the dependencies described in Setup
```xml
<dependency>
<groupId>nl.myndocs</groupId>
<artifactId>oauth2-server-sparkjava</artifactId>
<version>${myndocs.oauth.version}</version>
</dependency>
```

In memory example for Spark java:
```kotlin
Oauth2Server.configureOauth2Server {
tokenService = Oauth2TokenServiceBuilder.build {
identityService = InMemoryIdentity()
.identity {
username = "foo"
password = "bar"
}
clientService = InMemoryClient()
.client {
clientId = "testapp"
clientSecret = "testpass"
scopes = setOf("trusted")
redirectUris = setOf("https://localhost:4567/callback")
authorizedGrantTypes = setOf(
AuthorizedGrantType.AUTHORIZATION_CODE,
AuthorizedGrantType.PASSWORD,
AuthorizedGrantType.IMPLICIT,
AuthorizedGrantType.REFRESH_TOKEN
)
}
tokenStore = InMemoryTokenStore()
}
}
```
## http4k
The following dependency is required along with the dependencies described in Setup
```xml
<dependency>
<groupId>nl.myndocs</groupId>
<artifactId>oauth2-server-http4k</artifactId>
<version>${myndocs.oauth.version}</version>
</dependency>
```

In memory example for http4k:
```kotlin
val app: HttpHandler = routes(
"/ping" bind GET to { _: Request -> Response(Status.OK).body("pong!") }
) `enable oauth2` {
tokenService = Oauth2TokenServiceBuilder.build {
identityService = InMemoryIdentity()
.identity {
username = "foo"
password = "bar"
}
clientService = InMemoryClient()
.client {
clientId = "testapp"
clientSecret = "testpass"
scopes = setOf("trusted")
redirectUris = setOf("http://localhost:8080/callback")
authorizedGrantTypes = setOf(
AuthorizedGrantType.AUTHORIZATION_CODE,
AuthorizedGrantType.PASSWORD,
AuthorizedGrantType.IMPLICIT,
AuthorizedGrantType.REFRESH_TOKEN
)
}
tokenStore = InMemoryTokenStore()
}
}

app.asServer(Jetty(9000)).start()
```

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

```kotlin
fun identityOf(forClient: Client, username: String): Identity?

fun validCredentials(forClient: Client, identity: Identity, password: String): Boolean

fun allowedScopes(forClient: Client, identity: Identity, scopes: Set<String>): Set<String>
```

Each of the methods that needs to be implemented contains `Client`. This could give you extra flexibility.
For example you could have user base per client, instead of have users over all clients.

## Client service
Client service is similar to the identity service.

```kotlin
fun clientOf(clientId: String): Client?

fun validClient(client: Client, clientSecret: String): Boolean
```

## Token store
The following methods have to be implemented for a token store.

### Framework implementation
The following frameworks are supported:
- [Ktor](docs/ktor.md)
- [Javalin](docs/javalin.md)
- [http4k](docs/http4k.md)
- [Sparkjava](docs/sparkjava.md)

## Configuration
### Routing
Default endpoints are configured:

| Type | Relative url |
| ----- | ------------- |
| token | /oauth/token |
| authorize | /oauth/authorize |
| token info | /oauth/tokeninfo |

These values can be overridden:
```kotlin
fun storeAccessToken(accessToken: AccessToken)

fun accessToken(token: String): AccessToken?

fun revokeAccessToken(token: String)

fun storeCodeToken(codeToken: CodeToken)

fun codeToken(token: String): CodeToken?

fun consumeCodeToken(token: String): CodeToken?

fun storeRefreshToken(refreshToken: RefreshToken)

fun refreshToken(token: String): RefreshToken?

fun revokeRefreshToken(token: String)

tokenEndpoint = "/custom/token"
authorizationEndpoint = "/custom/authorize"
tokenInfoEndpoint = "/custom/tokeninfo"
```

When `AccessToken` is passed to `storeAccessToken` and it contains a `RefreshToken`, then `storeAccessToken` is also responsible for saving the refresh token.
39 changes: 39 additions & 0 deletions docs/http4k.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# http4k

## Dependencies
```xml
<dependency>
<groupId>nl.myndocs</groupId>
<artifactId>oauth2-server-http4k</artifactId>
<version>${myndocs.oauth.version}</version>
</dependency>
```

## Implementation
```kotlin
val app: HttpHandler = routes(
"/ping" bind GET to { _: Request -> Response(Status.OK).body("pong!") }
) `enable oauth2` {
identityService = InMemoryIdentity()
.identity {
username = "foo"
password = "bar"
}
clientService = InMemoryClient()
.client {
clientId = "testapp"
clientSecret = "testpass"
scopes = setOf("trusted")
redirectUris = setOf("http://localhost:8080/callback")
authorizedGrantTypes = setOf(
AuthorizedGrantType.AUTHORIZATION_CODE,
AuthorizedGrantType.PASSWORD,
AuthorizedGrantType.IMPLICIT,
AuthorizedGrantType.REFRESH_TOKEN
)
}
tokenStore = InMemoryTokenStore()
}

app.asServer(Jetty(9000)).start()
```
37 changes: 37 additions & 0 deletions docs/javalin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Javalin

## Dependencies
```xml
<dependency>
<groupId>nl.myndocs</groupId>
<artifactId>oauth2-server-javalin</artifactId>
<version>${myndocs.oauth.version}</version>
</dependency>
```

## Implementation
```kotlin
Javalin.create().apply {
enableOauthServer {
identityService = InMemoryIdentity()
.identity {
username = "foo"
password = "bar"
}
clientService = InMemoryClient()
.client {
clientId = "testapp"
clientSecret = "testpass"
scopes = setOf("trusted")
redirectUris = setOf("https://localhost:7000/callback")
authorizedGrantTypes = setOf(
AuthorizedGrantType.AUTHORIZATION_CODE,
AuthorizedGrantType.PASSWORD,
AuthorizedGrantType.IMPLICIT,
AuthorizedGrantType.REFRESH_TOKEN
)
}
tokenStore = InMemoryTokenStore()
}
}.start(7000)
```
38 changes: 38 additions & 0 deletions docs/ktor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Ktor

## Dependencies

```xml
<dependency>
<groupId>nl.myndocs</groupId>
<artifactId>oauth2-server-ktor</artifactId>
<version>${myndocs.oauth.version}</version>
</dependency>
```

## Implementation
```kotlin
embeddedServer(Netty, 8080) {
install(Oauth2ServerFeature) {
identityService = InMemoryIdentity()
.identity {
username = "foo"
password = "bar"
}
clientService = InMemoryClient()
.client {
clientId = "testapp"
clientSecret = "testpass"
scopes = setOf("trusted")
redirectUris = setOf("https://localhost:8080/callback")
authorizedGrantTypes = setOf(
AuthorizedGrantType.AUTHORIZATION_CODE,
AuthorizedGrantType.PASSWORD,
AuthorizedGrantType.IMPLICIT,
AuthorizedGrantType.REFRESH_TOKEN
)
}
tokenStore = InMemoryTokenStore()
}
}.start(wait = true)
```
35 changes: 35 additions & 0 deletions docs/sparkjava.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Spark java

## Dependencies
```xml
<dependency>
<groupId>nl.myndocs</groupId>
<artifactId>oauth2-server-sparkjava</artifactId>
<version>${myndocs.oauth.version}</version>
</dependency>
```

## Implementation
```kotlin
Oauth2Server.configureOauth2Server {
identityService = InMemoryIdentity()
.identity {
username = "foo"
password = "bar"
}
clientService = InMemoryClient()
.client {
clientId = "testapp"
clientSecret = "testpass"
scopes = setOf("trusted")
redirectUris = setOf("https://localhost:4567/callback")
authorizedGrantTypes = setOf(
AuthorizedGrantType.AUTHORIZATION_CODE,
AuthorizedGrantType.PASSWORD,
AuthorizedGrantType.IMPLICIT,
AuthorizedGrantType.REFRESH_TOKEN
)
}
tokenStore = InMemoryTokenStore()
}
```
Loading