OAuth 2.0 & OpenID Connect

1. Overview

FusionAuth supports the following two grant types as defined by the OAuth 2.0 framework in RFC 6749.

2. Configure Application OAuth Settings

Navigate to the Application configuration from the settings menu, Settings Applications.

If you have already created a FusionAuth application for the purpose your application, you do not need to create another, however you will still need to complete the OAuth configuration. If an application has not yet been created, click Add and name your application accordingly and fill out the OAuth configuration.

In this example you will see we have created a new Application named Pied Piper and have filled out the fields in the OAuth Configuration tab. A FusionAuth application represents an authenticated resource that you will be using with FusionAuth.

Application OAuth Configuration
Table 1. OAuth Form Fields

Client Id Read-Only

The unique client identifier as defined by RFC 6749 Section 2.2. This value is read only, it is equal to unique Id of the Application.

Client secret Read-Only

The client secret as defined by RFC 6749 Section 2.3-1.

Available Since 1.3.0 This value may be optionally re-generated by clicking the regenerate button. If this application is configured to require client authentication, changing the client secret will cause all clients to fail client authentication and they will not be able to complete the OAuth login process. If this application is not configured to require client authentication, regenerating this secret will not have any external effect.

Require authentication Available Since 1.3.0

When enabled, client authentication will be enforced for this Application. This means that the Token endpoint will require Basic Authentication to access the endpoint.

See the Authorization request header for the Token endpoint.

Generate refresh tokens Available Since 1.3.0

When enabled, a refresh token will be generated when the offline_access scope has been requested and other required values have been provided.

Authorized redirect URLs Optional

One or more authorized URLs that the OAuth grant workflow may redirect to upon completion.

Authorized request origin URLs Optional

One or more authorized origins that can initiate the OAuth grant to the /oauth2/authorize or /oauth2/token endpoints. Leaving this value empty will allow all origins.

Logout URL Optional

The URL used to perform the 302 redirect as the response from the /oauth2/logout API.

3. Example Authorization Code Grant

3.1. Point your application to the authorize endpoint

Now that your FusionAuth application has been configured to use the OAuth provider, you may now point the login for your application to the FusionAuth authorize endpoint which will now handle user authentication.

For the purposes of this example, I will make the assumption that FusionAuth App is running locally at http://localhost:9011, the client_id will be found on the OAuth tab in the application configuration, the redirect_uri will be where you wish FusionAuth to redirect the browser when the authorization step has completed. This value will need to be pre-defined in the authorized redirect URLs in the OAuth configuration. The response_type will always be code for this grant type.

Review the Authorization endpoint documentation for more detail.

http://localhost:9011/oauth2/authorize?client_id=06494b74-a796-4723-af44-1bdb96b48875&redirect_uri=https://www.piedpiper.com/login&response_type=code

3.2. Consume the authorization code returned from the authorize request

When the authorize request completes successfully it will respond with a status code of 302 to the location provided by the redirect_uri parameter. The request will contain a code parameter which can be exchanged for an access token. The access token contains the user Id of the authenticated user which can then be used to retrieve the entire user object.

Review the Token endpoint documentation for more detail. The following is an example redirect URI containing the authorization code.

https://www.piedpiper.com/login?code=+WYT3XemV4f81ghHi4V+RyNwvATDaD4FIj0BpfFC4Wzg=&userState=Authenticated

3.3. Exchange the authorization code for an access token

The last step to complete the authentication process and retrieve the users Id is to exchange the returned authorization code for an access token. The JSON response will contain the user Id of the authenticated user.

Example HTTP Request
POST /oauth2/token HTTP/1.1
Host: piedpiper.fusionauth.io
Content-Type: application/x-www-form-urlencoded
Accept: */*
Content-Length: 436
client_id=3c219e58-ed0e-4b18-ad48-f4f92793ae32&code=+WYT3XemV4f81ghHi4V+RyNwvATDaD4FIj0BpfFC4Wzg&grant_type=authorization_code&redirect_uri=https%3A%2F%2Fwww.piedpiper.com%2Flogin
Example HTTP Response
{
  "access_token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0ODUxNDA5ODQsImlhdCI6MTQ4NTEzNzM4NCwiaXNzIjoiYWNtZS5jb20iLCJzdWIiOiIyOWFjMGMxOC0wYjRhLTQyY2YtODJmYy0wM2Q1NzAzMThhMWQiLCJhcHBsaWNhdGlvbklkIjoiNzkxMDM3MzQtOTdhYi00ZDFhLWFmMzctZTAwNmQwNWQyOTUyIiwicm9sZXMiOltdfQ.Mp0Pcwsz5VECK11Kf2ZZNF_SMKu5CgBeLN9ZOP04kZo",
  "expires_in" : 3600,
  "token_type" : "Bearer",
  "userId" : "3b6d2f70-4821-4694-ac89-60333c9c4165"
}

3.4. Verify Authorization

If you only need to validate registration and User roles, this can be done by inspecting the JWT payload as returned in the access_token property of the response body.

If you require the entire User object to validate authorization, you may need to retrieve the entire User. The User may be retrieved in one of several ways. If you have an API key ou can retrieve the User by Id or email, these two values are returned in the JWT payload. The email address is returned in the email identity claim, and the User’s Id is returned in the sub identity claim. You may also retrieve the User without an API key by utilizing the JWT as returned in the access_token property in the response body.

See the Retrieve a User API for examples.

You may also choose to use the Introspect or Userinfo endpoints to validate the access token returned from the Token endpoint and to provided you decode claims as a JSON object.

Now that you have the user, or retrieved the roles from the JWT, you may review their roles and registration to ensure they have adequate authority for the intended action, and if the user is not yet registered for the requested application, you can either fail their login, or complete a registration workflow. Once you have determined a user can be logged into your application, you’ll need to log them into your application. For a web based application, this generally will include creating an HTTP session and storing the user in the newly created session.

3.5. Log Out

To log the user out, a typical workflow would include first logging out of your application, if that is successful, you would then log the user out of FusionAuth. This is accomplished by making a [GET] request to the /oauth2/logout endpoint. The logout request will complete with a 302 redirect to the configured logout URL.

[GET] http://localhost:9011/oauth2/logout?client_id=06494b74-a796-4723-af44-1bdb96b48875

Response: HTTP/1.1 302 Found
Location: https://www.piedpiper.com

4. Example Resource Owner Password Credentials Grant

4.1. Exchange the user credentials for an access token

Once you have collected the user’s email and password you will make a POST request to the Token endpoint. Below is an example HTTP request where the user’s email is richard@piedpiper.com and password is disrupt. The grant_type will always be password.

Example HTTP Request
POST /oauth2/token HTTP/1.1
Host: piedpiper.fusionauth.io
Content-Type: application/x-www-form-urlencoded
Accept: */*
Content-Length: 436
client_id=3c219e58-ed0e-4b18-ad48-f4f92793ae32&grant_type=password&username=richard%40piedpiper.com&password=disrupt
Example HTTP Response
{
  "access_token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0ODUxNDA5ODQsImlhdCI6MTQ4NTEzNzM4NCwiaXNzIjoiYWNtZS5jb20iLCJzdWIiOiIyOWFjMGMxOC0wYjRhLTQyY2YtODJmYy0wM2Q1NzAzMThhMWQiLCJhcHBsaWNhdGlvbklkIjoiNzkxMDM3MzQtOTdhYi00ZDFhLWFmMzctZTAwNmQwNWQyOTUyIiwicm9sZXMiOltdfQ.Mp0Pcwsz5VECK11Kf2ZZNF_SMKu5CgBeLN9ZOP04kZo",
  "expires_in" : 3600,
  "token_type" : "Bearer",
  "userId" : "3b6d2f70-4821-4694-ac89-60333c9c4165"
}