Hybrid Grant
- Endpoints
The OpenID Connect Hybrid grant is designed for clients that require flexibility when requesting ID, access, and refresh tokens.
Similar to the Authorization Code grant flow, the Hybrid grant flow is a two-step process:
The relying party makes a first request for tokens or codes. For example, a request for an ID token and an access code. AM returns them in the redirection fragment, as it does during the Implicit grant flow.
The client relying party usually starts using these tokens immediately.
Some time after the first request has happened, the relying party makes a second request for additional tokens. For example, a request for an access token using the access code, or a request for a refresh token.
Important
Consider the following security tips when implementing this flow:
Requesting an access token during the first step exposes the token in the redirection fragment, just like during the Implicit grant flow.
Also, you must consider the security impact of cross-site scripting (XSS) attacks that could leak the ID and access tokens to other systems, and implement Cross-Origin Resource Sharing (CORS) to make OAuth 2.0/OpenID Connect requests to different domains.
Due to the security implications, ForgeRock recommends not to request access tokens during the first step of this flow.
If the relying party is a public client, you can use the PKCE specification to mitigate against interception attacks performed by malicious users.
A common use case is the relying party requesting an ID token which can be used to, for example, pre-register the end user so they can start shopping. Only later and, if required, the relying party requests an access token to inquire the OpenID provider about additional claims. For example, during the check out, the relying party requests from AM the end user's address details.
The steps in the diagram are described below:
The end user wants to use the services provided by the relying party. The relying party, usually a web-based service, requires an account to provide those services.
The end user issues a request to the relying party to access their information, which is stored in an OpenID provider.
To access the end user's information in the provider, the relying party requires authorization from the end user. Therefore, the relying party redirects the end user's user agent...
... to the OpenID provider.
The OpenID provider authenticates the end user, confirms resource access, and gathers consent if not previously saved.
If the end user's credentials are valid, the OpenID provider redirects the end user to the relying party.
During the redirection process, the OpenID provider appends an authorization code and an ID token to the URL.
Note that AM can return any combination of access token, ID token, and authorization code depending on the request. In this example, the access token is not requested at this time due to security concerns.
The relying party stores the authorization code for future use. It also validates the ID token and gets the subject ID.
With the ID token, the relying party starts providing services to the end user.
Later, but always before the authorization code has expired, the relying party requests an access token from the OpenID provider so it can access more information about the end user.
A use case would be the end user requiring services from the relying party that requires additional (usually more sensitive) information. For example, the end user requests the relying party to compare their electricity usage and supplier information against offers in the market.
If required, the relying party could also request a refresh token.
If the relying party credentials and the authorization code are valid, AM returns an access token.
The relying party makes a request to AM's
/oauth2/userinfo
endpoint with the access token to access the end user's additional claims.If the access token is valid, the
/oauth2/userinfo
endpoint returns additional claims, if any.The relying party can now use the subject ID in the ID token and the additional claims as the end user's identity to provide them with more services.
Perform the steps in the following procedure to obtain an authorization code and an ID token, and later an access token:
This procedure assumes the following configuration:
AM is configured as an OAuth 2.0/OpenID provider. Ensure that:
The
token
,code
, andid_token
plugins are configured in the Response Type Plugins field.The
Authorization Code
grant type is configured in the Grant Types field.
For more information, see OpenID Provider Configuration.
A confidential client called
myClient
is registered in AM with the following configuration:Client secret:
forgerock
Scopes:
openid profile
Response Types:
code id_token token
Grant Types:
Authorization Code
Token Endpoint Authentication Method:
client_secret_post
Confidential OpenID Connect clients can use several methods to authenticate. For more information, see OpenID Connect Client Authentication.
For more information, see Dynamic Client Registration.
Perform the steps in the following procedure to obtain an ID token and an authorization code that will later be exchanged for an access token:
The client redirects the end user's user-agent to the authorization server's authorization endpoint specifying, at least, the following form parameters:
client_id=your_client_id
response_type=code id_token
As per the specification, you can request the following response types:
code id_token
code token
code id_token token
Since AM returns the tokens in the redirection URL, requesting access tokens in this way poses a security risk.
redirect_uri=your_redirect_uri
scope=openid profile
For information about the parameters supported by the
/oauth2/authorize
endpoint, see "/oauth2/authorize".If the OAuth 2.0/OpenID provider is configured for a subrealm rather than the Top Level Realm, you must specify it in the endpoint. For example, if the OAuth 2.0/OpenID provider is configured for the
/customers
realm, then use/oauth2/realms/root/realms/customers/authorize
.For example:
https://openam.example.com:8443/openam/oauth2/realms/root/authorize \ ?client_id=myClient \ &response_type=code%20id_token \ &scope=openid%20profile \ &state=abc123 \ &nonce=123abc \ &redirect_uri=https://www.example.com:443/callback
Note that the URL is split and spaces have been added for readability purposes. The
state
andnonce
parameters have been included to protect against CSRF and replay attacks.Tip
Implement the PKCE specification to mitigate against interception attacks performed by malicious users.
For more information about the required additional parameters and an example, see "Authorization Code Grant with PKCE".
The end user authenticates to AM, for example, using the credentials of the
demo
user. In this case, they log in using the default chain or tree configured for the realm.After logging in, AM presents its consent screen:
Note that requesting the
profile
scope translates into requesting access to several claims. For more information about the specialprofile
scope, see Claims.The end user selects the
Allow
button to grant consent for theprofile
scope.AM redirects the end user to the URL specified in the
redirect_uri
parameter.Inspect the URL in the browser. It contains a
code
parameter with the authorization code and anid_token
parameter with the ID token AM has issued. For example:https://www.example.com:443/callback#code=bOrAijEerd_YdNCUC1piL5VfNO4&id_token=eyJ0eXAiOiJKV1QiLCJra...7r8soMCk8A7QdQpg
The client relying party can now use the ID token as the end user's identity and store the access code for later use.
(Optional) The client exchanges the authorization code for an access token (and maybe, an refresh token). Perform the steps in one of the following procedures:
This procedure assumes the following configuration:
AM is configured as an OAuth 2.0/OpenID provider in the Top Level Realm.
For more information, see OpenID Provider Configuration.
A confidential client called
myClient
is registered in AM with the following configuration:Client secret:
forgerock
Scopes:
openid profile
Response Types:
code id_token token
Grant Types:
Authorization Code
Token Endpoint Authentication Method:
client_secret_post
Confidential OpenID Connect clients can use several methods to authenticate. For more information, see OpenID Connect Client Authentication.
For more information, see Dynamic Client Registration.
Perform the steps in the following procedure to obtain an ID token and an authorization code that will later be exchanged for an access token:
The end user logs in to AM, for example, using the credentials of the
demo
user. For example:$
curl \ --request POST \ --header "Content-Type: application/json" \ --header "X-OpenAM-Username: demo" \ --header "X-OpenAM-Password: Ch4ng31t" \ --header "Accept-API-Version: resource=2.0, protocol=1.0" \ 'https://openam.example.com:8443/openam/json/realms/root/authenticate'
{ "tokenId":"AQIC5wM...TU3OQ*", "successUrl":"/openam/console", "realm":"/" }
The client makes a POST call to AM's authorization endpoint, specifying the SSO token of the
demo
in a cookie and, at least, the following parameters:client_id=your_client_id
response_type=code id_token
As per the specification, you can request the following response types:
code id_token
code token
code id_token token
Since AM returns the tokens in the redirection URL, requesting access tokens in this way poses a security risk.
redirect_uri=your_redirect_uri
scope=openid profile
decision=allow
csrf=demo_user_SSO_token
For information about the parameters supported by the
/oauth2/authorize
endpoint, see "/oauth2/authorize".If the OAuth 2.0/OpenID provider is configured for a subrealm rather than the Top Level Realm, you must specify it in the endpoint. For example, if the OAuth 2.0/OpenID provider is configured for the
/customers
realm, then use/oauth2/realms/root/realms/customers/authorize
.For example:
$
curl --dump-header - \ --request POST \ --Cookie "iPlanetDirectoryPro=AQIC5wM...TU3OQ*" \ --data "scope=openid profile" \ --data "response_type=code id_token" \ --data "client_id=myClient" \ --data "csrf=AQIC5wM...TU3OQ*" \ --data "redirect_uri=https://www.example.com:443/callback" \ --data "state=abc123" \ --data "nonce=123abc" \ --data "decision=allow" \ "https://openam.example.com:8443/openam/oauth2/realms/root/authorize"
Note that the
state
andnonce
parameters have been included to protect against CSRF and replay attacks.Tip
Implement the PKCE specification to mitigate against interception attacks performed by malicious users.
For more information about the required additional parameters and an example, see "Authorization Code Grant with PKCE".
If AM is able to authenticate the user and the client, it returns an HTTP 302 response with the authorization code appended to the redirection URL:
HTTP/1.1 302 Found Server: Apache-Coyote/1.1 X-Frame-Options: SAMEORIGIN Pragma: no-cache Cache-Control: no-store Date: Mon, 30 Jul 2018 11:42:37 GMT Accept-Ranges: bytes Location: https://www.example.com:443/callback#code=bOrAijEerd_YdNCUC1piL5VfNO4&id_token=eyJ0eXAiOiJKV1QiLCJra...7r8soMCk8A7QdQpg Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept Content-Length: 0
The client relying party can now use the ID token as the end user's identity and store the access code for later use.
(Optional) The client exchanges the authorization code for an access token (and maybe, a refresh token). Perform the steps in one of the following procedures: