Spring + OAuth 2.0 + OpenID Connect

1. Quick Start

1.1. Start an authorization server (OpenID provider) at port 8080

$ git clone https://github.com/authlete/spring-oauth-server
$ cd spring-oauth-server
$ vi authlete.properties
$ mvn spring-boot:run

1.2. Start a resource server at port 8081

$ git clone https://github.com/authlete/spring-resource-server
$ cd spring-resource-server
$ vi authlete.properties
$ mvn spring-boot:run

1.3. Issue an access token and an ID token

# Access the authorization endpoint with your web browser
http://localhost:8080/api/authorization
?client_id={client-id}
&response_type=token+id_token
&scope=openid
&redirect_uri={redirect-uri}
&state={state}
&nonce={nonce}
# An authorization page will be displayed. In the page,
# Input "john" and "john" as Login ID and Password, then
# press "Authorize" button.

1.4. Access a sample protected resource endpoint

$ curl http://localhost:8081/api/country/JP \
-d access_token={access-token}

1.5. Access UserInfo Endpoint (OpenID Connect Core 1.0)

$ curl http://localhost:8081/api/userinfo \
-d access_token={access-token}

1.6. Access Discovery Endpoint (OpenID Connect Discovery 1.0)

$ curl http://localhost:8080/.well-known/openid-configuration

1.7. Access JWK Set Endpoint (RFC 7517)

$ curl http://localhost:8080/api/jwks

1.8. Access Introspection Endpoint (RFC 7662)

$ curl http://localhost:8080/api/introspection \
-d token={access-token}

1.9. Delete the access token (Revocation Endpoint; RFC 7009)

$ curl http://localhost:8080/api/revocation \
-d token={access-token}

2. Architecture

spring-oauth-server is an implementation of authorization server and OpenID provider which supports OAuth 2.0 and OpenID Connect.

spring-resource-server is an implementation of resource server which includes an implementation of UserInfo Endpoint defined in OpenID Connect.

Both implementations use Spring Boot but do not use Spring Security OAuth. Instead, both use Authlete as the core implementation of OAuth 2.0 and OpenID Connect.

Authlete itself is not an authorization server / OpenID provider. It is a set of Web APIs by which developers can implement their authorization servers / OpenID providers.

The primary advantage of this architecture is in that the backend server (Authlete) can focus on implementing OAuth 2.0 and OpenID Connect without the need to care about other components such as identity management, user authentication, login session management, API management and fraud detection. To put it the other way around, developers can choose any solution of identity management, user authentication, etc. without the need to care about OAuth 2.0 and OpenID Connect implementation. Furthermore, developers can choose any programming language they like to implement an authorization server / OpenID provider. Please read New Architecture of OAuth 2.0 and OpenID Connect Implementation for details about the architecture.

Thanks to the architecture, frontend servers (spring-oauth-server and spring-resource-server) don’t have to have a database server that manages data related to OAuth 2.0 and OpenID Connect such as access tokens, refresh tokens, authorization codes, metadata of client applications and authorization servers / OpenID providers, and so on. Such data are managed by the backend server (Authlete).

2.1. Note for Spring Security OAuth

It might be better to mention here that Spring Security OAuth does not provide even schema of database tables. The following is a note excerpted from OAuth 2 Developers Guide of Spring Security OAuth.

NOTE: the schema for the JDBC service is not packaged with the library (because there are too many variations you might like to use in practice), but there is an example you can start from in the test code in github.

This means that you have to investigate APIs of Spring Security OAuth library (such as ClientDetails interface) and design database table schema to store corresponding data.

To support OpenID Connect, an authorization server / OpenID provider should have metadata listed in 3. OpenID Provider Metadata (OpenID Connect Discovery 1.0), and client applications should have metadata listed in 2. Client Metadata (OpenID Connect Dynamic Client Registration 1.0). However, because Spring Security OAuth does not support OpenID Connect, your database tables don’t have to have columns corresponding to the metadata unless you try to implement OpenID Connect on top of Spring Security OAuth.

3. Technical Details

3.1. API key and API secret to use Authlete APIs

You need to get a pair of API key and API secret to use Authlete APIs, and set the pair in the authlete.properties file of spring-oauth-server and spring-resource-server.

It’s easy. Just create your Authlete account at the sign-up page. On account registration, one service (which corresponds to one authorization server / OpenID provider) and one client application (which belongs to the service) are automatically created. You can find the pair of API key and API secret of the service in the management console (Service Owner Console).

3.2. Client ID

To make an authorization request, you need to know the client ID of the client application. Authlete provides another web console (Developer Console) to manage client applications. The URL of the web console is https://cd.authlete.com/{service-api-key} where {service-api-key} is the API key of the service which the client application belongs to. You can login using the pair of API key and API secret of the service, and will find the client ID in the web console.

3.3. Authorization server and OpenID provider

First, download spring-oauth-server.

$ git clone https://github.com/authlete/spring-oauth-server

Second, open the configuration file (authlete.properties) with a text editor and change the values of service.api_key and service.api_secret.

$ cd spring-oauth-server
$ vi authlete.properties

Finally, start spring-oauth-server.

$ mvn spring-boot:run

3.4. Authorization request

spring-oauth-server exposes its authorization endpoint at /api/authorization. If the value of the response_type request parameter of an authorization request is token id_token, an access token and an ID token will be issued directly from the authorization endpoint. If you are not familiar with OpenID Connect flows, reading Diagrams of All The OpenID Connect Flows will help you.

The following is an example of authorization request to get both an access token and an ID token. Input the URL in the address bar of your web browser.

http://localhost:8080/api/authorization
?client_id={client-id}
&response_type=token+id_token
&scope=openid
&redirect_uri={redirect-uri}
&state={state}
&nonce={nonce}

Of course, replace {client-id}, {redirect-uri}, {state} and {nonce} properly. You can find the value of redirect URI of the client application in Developer Console. If you have not changed the default value, the redirect URI is https://api.authlete.com/api/mock/redirection/{service-api-key}.

The authorization endpoint will return an authorization page. It has a login form. Input john and john (or jane and jane) in the Login ID field and the Password field, then press “Authorize” button. Your browser will be redirected to the redirect URI of the client application.

If you have not changed the value of the redirect URI, your browser will be redirected to the mock redirection endpoint provided by Authlete server. The mock implementation displays parameters it received, so you can confirm the values of the access token and the ID token there.

3.5. Resource server

Now you have an access token, you can make API calls to protected resources. But, before making API calls, you need to run a resource server.

First, download spring-resource-server.

$ git clone https://github.com/authlete/spring-resource-server

Second, open the configuration file (authlete.properties) with a text editor and change the values of service.api_key and service.api_secret.

$ cd spring-resource-server
$ vi authlete.properties

Finally, start spring-resource-server.

$ mvn spring-boot:run

3.6. API call

Now, you are ready to make an API call to a sample protected resource endpoint provided by spring-resource-server. Of course, replace {access-token} with the actual value of an access token.

$ curl http://localhost:8081/api/country/JP \
-d access_token={access-token}

Congratulations. You have finished all the steps.

Next step

  1. Read README.md and CUSTOMIZATION.md of spring-oauth-server and spring-resource-server for more details.
  2. java-oauth-server and java-resource-server are implementations which use JAX-RS API only. You might be more interested in these than in spring-oauth-server and spring-resource-server.

Finally

If you are looking for an implementation of authorization server / OpenID provider, please consider Authlete. Read New Architecture of OAuth 2.0 and OpenID Connect implementation, and you will love the architecture of Authlete 😉