Hybrid grant
- Endpoints
OpenID Connect (OIDC) authentication using the hybrid flow lets a relying party (RP) choose when to request access and ID tokens.
The hybrid grant flow is a two-step process:
-
The RP first requests a code and tokens by setting the response type:
Response type OpenID provider (OP) returns code id_token
An authorization code and an ID token
code token
An authorization code and an access token
code token id_token
An authorization code, and access token, and an ID token
PingOne Advanced Identity Cloud returns the code and the requested tokens in the fragment of the redirection URL.
-
After the first request but before the authorization code expires (default: 120 seconds), the RP makes a second request to exchange the authorization code for additional tokens.
Follow these security recommendations when implementing the hybrid flow:
|
-
The end user wants to access services the RP provides. The RP requires an account to provide access to the services.
The end user makes a request to the RP to access their information stored at the OP.
-
To access the end user’s information at the OP, the RP needs authorization from the end user. The RP redirects the end user’s browser...
-
...to the OP.
-
The OP authenticates the end user, confirms resource access, and gathers consent if necessary.
-
On success, the OP redirects the end user to the RP.
-
The OP appends an authorization code and tokens to the URL fragment.
-
The RP stores the authorization code for future use and validates the ID token to get the subject ID.
-
With the ID token, the RP provides services to the end user.
-
Before the authorization code expires, the RP exchanges it for an access token, which the RP can use to get more information about the end user.
-
PingOne Advanced Identity Cloud returns an access token.
-
The RP sends a request to the /oauth2/userinfo endpoint with the access token for authorization.
-
If the access token is valid, the
/oauth2/userinfo
endpoint returns any additional claims.The RP can use the subject ID and the additional claims to identify the end user.
Demonstrate the flow
Prepare the demonstration
Complete these steps to prepare the hybrid flow demonstration:
-
Create an application owner profile and record the username and password.
-
Register a client application.
-
In the Advanced Identity Cloud admin UI, go to Applications and select + Custom Application.
-
Select the sign-in method as OIDC - OpenId Connect and application type as Web.
-
Create the application, providing the following details:
- Name
-
myClient
- Owners
-
<application-owner>
- Client ID
-
myClient
- Client Secret
-
forgerock
-
Switch to the Sign On tab and under General Settings, set these fields to have the following values:
- Sign-in URLs
-
https://www.example.com:443/callback
- Scopes
-
openid
profile
- Grant Types
-
Authorization Code
Implicit
-
Click Show advanced settings and under Access, add these settings:
- Response Types
-
code id_token
code token
code token id_token
-
Under Token Lifetimes, update this setting as appropriate for your use case:
- Authorization code lifetime (seconds)
-
Default: 120
-
Save your changes.
-
-
Create an end user profile and record the username and password.
Get a code and an ID token using a browser
-
As RP, browse to the /oauth2/authorize endpoint with at least the following parameters:
-
client_id:
myClient
-
response_type:
code id_token
-
scope:
openid profile
-
redirect_uri:
https://www.example.com:443/callback
For example:
https://<tenant-env-fqdn>/am/oauth2/realms/root/realms/alpha/authorize \ ?client_id=myClient \ &response_type=code%20id_token \ &scope=openid%20profile \ &state=abc123 \ &nonce=123abc \ &redirect_uri=https://www.example.com:443/callback
The URL is split and spaces added for readability purposes.
The
scope
parameter is optional if default values are configured in the authorization server or the client.The
state
andnonce
parameters are optional and included to protect against CSRF attacks. -
-
Sign in as the end user and grant consent if necessary.
PingOne Advanced Identity Cloud redirects to the
redirect_uri
. -
Inspect the URL in the browser:
https://www.example.com:443/callback#code=<authorization-code>&id_token=<id-token>...
Get a code and an ID token using REST
-
Authenticate as the end user:
$ curl \ -i \ --request POST \ --header "Content-Type: application/json" \ --header "X-OpenAM-Username: <end-user-id>" \ --header "X-OpenAM-Password: <end-user-password>" \ --header "Accept-API-Version: resource=2.0, protocol=1.0" \ 'https://<tenant-env-fqdn>/am/json/realms/root/realms/alpha/authenticate' {"tokenId":"<tokenId>","successUrl":"/enduser/?realm=/alpha","realm":"/alpha"}
-
As RP, make an HTTP POST request to the /oauth2/authorize endpoint with the following parameters:
-
scope:
openid profile
-
response_type:
code id_token
-
client_id:
myClient
-
csrf:
<tokenId>
-
redirect_uri:
https://www.example.com:443/callback
-
decision:
allow
For example:
$ curl \ --dump-header - \ --request POST \ --cookie "<session-cookie-name>=<tokenId>" \ --data "scope=openid profile" \ --data "response_type=code id_token" \ --data "client_id=myClient" \ --data "csrf=<tokenId>" \ --data "redirect_uri=https://www.example.com:443/callback" \ --data "state=abc123" \ --data "nonce=123abc" \ --data "decision=allow" \ "https://<tenant-env-fqdn>/am/oauth2/realms/root/realms/alpha/authorize"
The URL is split and spaces added for readability purposes.
The
scope
parameter is optional if default values are configured in the authorization server or the client.The
state
andnonce
parameters are optional and included to protect against CSRF attacks.PingOne Advanced Identity Cloud returns an HTTP 302 response with the code and ID token in the redirection URL fragment:
HTTP/1.1 302 Found ... Location: https://www.example.com:443/callback#code=<authorization-code>&id_token=<id-token>... ...
-
Exchange the code for an access token
Choose one of the following options:
-
Use the authorization code grant to exchange an authorization code for an access token.
-
Use the authorization code grant with PKCE to exchange an authorization code for an access token.
Additional OIDC claims
An RP can request additional claims about the end user with the access token at the /oauth2/userinfo endpoint:
$ curl \
--request GET \
--header "Authorization Bearer <access-token>" \
"https://<tenant-env-fqdn>/am/oauth2/realms/root/realms/alpha/userinfo"
{
"name": "<end-user-display-name>",
"family_name": "<end-user-family-name>",
"given_name": "<end-user-given-name>",
"sub": "<end-user-id>",
"subname": "<end-user-id>"
}