The OAuth protocol uses different flows to to setup tokens, as well as different ways how tokens can be used. This chapter is a summary of the different flows that establish Access Tokens, in relation to the Curity Identity Server. The actors that are used, are the Resource Owner (RO), the Client (C), the Resource Server (RS) and the Authorization Server (AS).
The full specification of OAuth is in RFC 6749.
The Code flow is about a Resource Owner that authorizes an access request from the Client with the Authorization Server, resulting in a code that represents that delegated authorization. The user hands over the code to the Client, that uses it on a backchannel with the Authorization Server to exchange it for an OAuth Access Token.
This flow uses two endpoints on the Authorization Server, the oauth-authorize and the oauth-token endpoint.
It is split in two separate requests. The first is done in the front-channel in the browser as a regular GET request to the oauth-authorize endpoint.
GET request parameters:
The second request is done as a server-side POST request with the content type application/x-www-form-urlencoded to the oauth-token endpoint. In this call the client needs to authenticate itself using its client credentials.
POST request parameters
OAuth public clients are susceptible to the authorization code interception attack (RFC 7636).
In this attack, the attacker intercepts the authorization code returned from the authorization endpoint within a communication path not protected by Transport Layer Security (TLS), such as inter-application communication within the client’s operating system; e.g. custom protocol handlers. Once the attacker has gained access to the authorization code, it can use it to obtain the access token.
To mitigate this attack, a unique “code verifier” is created client-side for every authorization request; which is transformed into a “code challenge” that is sent to the authorization server. The authorization code obtained is then sent to the token endpoint together with the “code verifier”, where it is compared with the previously received “code challenge”; performing proof of possession of the “code verifier” by the client.
The Implicit flow is also about the Resource Owner authorizing the access request from the Client with the Authorization Server, like the Code flow, but it does not respond with a code, but instead it provides the OAuth Access Token directly.
The implicit flow is available on the oauth-authorize endpoint and is accessed with a GET request in the browser. The following request parameters are supported in the query string:
The response is given as a fragment parameter in a redirect back to the client on a predefined or whitelisted redirect uri.
In case a Client needs an OAuth Access Token, the Client Credentials flow allows an OAuth Client to make an authenticated request on the token endpoint to request an Access Token. Authentication is based on the Client Secret. There is no user authenticated in this flow, which makes it suitable for server to server communication only.
The client credentials flow is available on the oauth-token endpoint and is accessed with a POST and the content type application/x-www-form-urlencoded. The following request parameters are supported:
Mainly for supporting legacy applications, the Resource Owner Password Credentials flow allows an OAuth Client to provide the Resource Owner’s password credentials to the Authorization Server. The AS authenticates both the RO as well as the Client, and issues an OAuth Access Token on success.
This flow has the undesired effect that the RO’s credentials are exposed to the OAuth Client.
The resource owner password credentials flow is available on the oauth-token endpoint and is accessed with a POST and the content type application/x-www-form-urlencoded. The following request parameters are supported:
OpenID Connect defines hybrid flows which consists of combinations of (some of) the regular OAuth2 / OpenID Connect
flows. To allow this, no extra configuration is needed other than having OpenID Connect enabled on the profile as well
as the openid scope granted (and requested) for the client.
As an example, a grant_type could with a hybrid flow allow both code, token and even id_token to be
asked for in the same request. This allows for some interesting, albeit not too common, flows for clients that need some
data delivered on the front end channel, while still having the capability to retrieve other information from the
backend (i.e. can keep a secret). See Hybrid Capabilities on the clients configuration page for more
Client Initiated Backchannel Authentication
(CIBA) is an OpenID Connect authentication flow in which Relying Parties (RP),
that can obtain a valid identifier for the user they want to authenticate, will be able to initiate an interaction flow
to authenticate their users without having end-user interaction from the consumption device.
In order to be able to use back-channel authentication, an endpoint of type oauth-backchannel-authentication
needs to be configured in the Token Service profile.
Back-channel Authenticators of supported types needs to be created in Authentication profile under the
Back-channel Authenticators section of the admin UI.
Depending on the authenticator type, the back-channel authenticator can have its own settings or optionally link to a
front-channel authenticator in the same plugin group to re-use its settings and managed objects.
If multiple back-channel authenticators are configured, then back-channel authentication will be attempted on all of them
for a request to start back-channel authentication. If required, it can be limited by specifying acr_values in the
Back-channel authentication can be enabled or disabled using admin UI under Capabilities section of Client Settings
in Token Service profile. In addition, the following settings can also be configured.
Request Object JWT
Signature Verification Key
Authentication can be initiated by the client by making a HTTP POST request to the configured back-channel endpoint
with the below parameters. Upon successful initiation, the response would contain auth_req_id that corresponds to
the CIBA Authentication request.
Any additional parameters provided will be ignored by the server for the authentication request, however they are
available for inspection in back-channel token procedure and can be included in the tokens, if required.
Currently, the Curity Identity Server supports only poll mode to get authentication result as specified in
section 5 of the CIBA spec.
The token can be obtained by making a poll request to the token endpoint using HTTP POST with below
The poll request may be repeated until success or error for a period mentioned as expires_in in the initiation
response at an interval specified by interval value.
A signed authentication request can be made by encoding all of the authentication request parameters as claims of a
signed JWT with each parameter name as the claim name and its value as a JSON string.
The JWT must contain all of the authentication request parameters and be signed with asymmetric signing algorithm. The
signed authentication request JWT should be passed as an application/x-www-form-urlencoded HTTP request parameter
with the name request.
The signing key for signed requests, is either statically configured as request-object configuration for a client,
or taken from the jwks_uri in case of a dynamically registered client.
The token exchange flow is a non-standard flow, that a Client can use to exchange an existing Access Token for a new Access Token. This new Access Token’s properties are limited to the original Access Token’s properties.
The purpose is to create a token that is a subset of the original token. Thus the new token cannot contain more authorization than the original token. This operation is typically referred to as downscoping. Two things can be downscoped:
Thus, the token returned from the endpoint contains fewer audiences and fewer scopes than the original token.
The client needs to have the token-exchange capability enabled to be allowed to use this flow, and the client needs to authenticate (i.e. using Client Authentication).
Token exchange is initiated by the Client making a call to the oauth-token endpoint of the OAuth profile, using the grant_type https://curity.se/grant/accesstoken.
The request is a POST to the oauth-token endpoint with the content type application/x-www-form-urlencoded. The following request parameters are supported:
The token exchange flow is available on the oauth-token endpoint.
The grant-type to use for the token exchange flow is https://curity.se/grant/accesstoken
The assisted token flow is a non-standard flow that a client can use to setup a new Access Token. This flow is particularly well suited to integrate in client side web applications, and is aimed to make integrating token setup as easy as possible.
The client needs to have the assisted-token capability enabled to be allowed to use this flow.
The assisted token flow is available on the oauth-assisted-token endpoint. For more information about the assisted flow see the assisted token api.
The refresh flow is used to exchange a refresh token for a new access token and refresh token pair. If reuse-refresh-token is set in the authorization server configuration, only an access token will be returned.
The refresh token flow is available on the oauth-token endpoint and is accessed with a POST and the content type application/x-www-form-urlencoded. The following request parameters are supported:
The time validity of refresh tokens is defined by two configuration settings:
Using the refresh token flow, a client can obtain fresh access tokens and refresh tokens, until refresh-token-max-rolling-lifetime has elapsed since the first token request, as long as each refresh token is used before refresh-token-ttl seconds since its issuance.
Both these settings are configurable:
The default values configured for the non-templatized dynamic clients can be overriden during dynamic client registration or dynamic client management via two custom registration parameters:
If a token with fewer scopes than the original access token is desired, the scope parameter can be used to tell the authorization server which scopes to include. Only scopes available in the original token are allowed to request.
The revoke flow is used to revoke an access token or a refresh token.
The revoke flow is available on the oauth-revoke endpoint and is accessed with a POST and the content type application/x-www-form-urlencoded. The following request parameters are supported:
The introspect flow is used to inspect a token, to see if it’s valid and to retrieve the associated data with that token.
The introspection flow is available on the oauth-introspect endpoint and is accessed with a POST and the content type application/x-www-form-urlencoded. The following request parameters are supported:
The JSON Web Key Set endpoint publication of the currently active public keys. These can then be retrieved by the client to use when validating JWTs issued by this token server.
The JWKS is available on the oauth-anonymous endpoint and is unauthenticated. It expects the accept header application/json.
The oauth-anonymous endpoint can publish many services, and the JWKS service is located under <configured_path_of_anonymous>/jwks
If the oauth-anonymous endpoint is configured with path /oauth/v2/info then the JWKS service is published at /oauth/v2/info/jwks.
The device flow is specified for internet connected devices that have a limited user interface, but need an
Access Token or ID token. The device flow allows a device to offload the user interaction that is needed for user
authentication and consent to a device of the user’s choice. The result of going through the Device Flow is still an
Access Token and/or an ID token, making it possible for the device to operate as a fully enabled OAuth client.
The device flow is initiated by the device, that makes an authenticated back-channel request to the device
authorization endpoint. In response to this request, Curity returns a device_code and a user_code to the device,
together with a verification_uri that can be used by the user to verify the user_code. It is up to the device
to instruct the user to visit the verification_uri.
The process of verifying the user_code is done in three steps:
The user enters the user_code, giving Curity the opportunity to find the context that needs to be verified
The user authenticates, using the device client’s settings
The user is asked to confirm the access that device is requesting
While the user is verifying the user_code, the device can poll the token-endpoint to find out whether
verification has completed. Once the user has confirmed access (step 3 above), the response of the device making a
request to the oauth-token endpoint will be successful and include the requested token or tokens.
A more detailed description of how the device flow works in Curity can be found in Using the device flow.
The flow where the token endpoint can accept an assertion as authorization grant is referred to as the Assertion Flow.
Using JWTs as assertions is specified in the JSON Web Token (JWT) Profile for OAuth, published as
To present a JWT as authorization grant, make a POST-request to the token endpoint that uses the value
urn:ietf:params:oauth:grant-type:jwt-bearer for the grant_type-parameter, and provide the JWT through the
A JWT used as assertion is commonly issued by the client that presents it. This is indicated by using the client id
as value for the iss-claim of the JWT. In case a particular client must be able to present a JWT that was issued
by another entity, the value to expect for the iss claim can be configured through that particular client’s
If a JWT is presented as authorization grant, it needs to include a minimal set of claims, as specified in RFC7523:
When included in the JWT, Curity considers the nbf (not-before) and iat (issued-at) claims to control the time
window in which the token is valid.
By default, Curity ensures that a token used as assertion grant can only be used once. This restriction can be overridden
for individual clients by configuring the Assertion Grant settings of that particular client.
When a client wants to indicate to the Token Service that a user is logged out, it can call the logout path
on the Session endpoint (i.e. the end_session_endpoint in the Metadata). Doing so will log the user out
of the associated Authentication Service, as well as notify all clients that the user has logged in to through their
respective registered frontchannel- or backchannel logout uri’s, so called Single Logout.
Logout follows the OpenId Connect Session Management,
OpenId Connect Backchannel Logout and
OpenId Connect Frontchannel logout specifications.
More details are in Session Management and Logout.