Access Management 7.2.2

Implicit grant

The OpenID Connect implicit grant is designed for public clients that run inside the end user’s user-agent. For example, JavaScript applications.

This flow lets the relying party interact directly with the OpenID provider, AM, and receive tokens directly from the authorization endpoint instead of from the token endpoint.

Since applications running in the user-agent are considered less trusted than applications running in servers, the authorization server will never issue refresh tokens in this 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 of this flow, it is recommended to use the Authorization Code grant with PKCE flow whenever possible.

OpenID Connect Implicit Flow
Figure 1. OpenID Connect Implicit Flow
Implicit flow explained
  1. The relying party, usually a single-page application (SPA), receives a request to access user information stored in an OpenID provider. To access this information, the client requires authorization from the end user.

  2. The relying party redirects the end user’s user-agent or opens a new frame to the AM OpenID provider.

    As part of the OpenID Connect flow, the request contains the openid scope and the nonce parameter.

  3. The OpenID provider authenticates the end user, confirms resource access, and gathers consent if not previously saved.

  4. If the end user’s credentials are valid, the authorization server returns an ID token (and optionally, an access token) to the user-agent as part of the redirection URI.

  5. The user-agent must extract the token(s) from the URI. In this example, the user-agent follows the redirection to the relying party without the token(s)…​

  6. ... And the relying party returns a web page with an embedded script to extract the token(s) from the URI.

    In another possible scenario, the redirection URI is a dummy URI in the application running in the user-agent which already has the logic in itself to extract the tokens.

  7. The user-agent executes the script and retrieves the tokens.

  8. The user-agent returns the tokens to the relying party.

  9. The relying party validates the ID token and its claims.

    Now, the relying party can use the ID token subject ID claim as the end user’s identity.

  10. The relying party may require more claims than those included in the ID token. In this case, it makes a request to the OpenID provider’s oauth2/userinfo endpoint with the access token.

  11. If the access token is valid, the oauth2/userinfo endpoint returns additional claims, if any.

    Now, the relying party can use the subject ID and the additional retrieved claims as the end user’s identity.

Get an ID/access token using a browser

This example shows how to obtain an ID token and an access token. It adds notes on how to obtain the ID token only, as well.

The procedure assumes the following configuration:

  • AM is configured as an OAuth 2.0/OpenID provider. Ensure that:

    • The token and id_token plugins are configured in the Response Type Plugins field.

    • The Implicit Grant grant type is configured in the Grant Types field.

    For more information, see OpenID provider configuration.

  • A public client called myClient is registered in AM with the following configuration:

    • Scopes: openid profile

    • Response Types: token id_token

      Configure id_token to receive an ID token only.

    • Grant Types: Implicit

    • Authentication Method: none

    • Token Endpoint Authentication Method: none

      If you were using a confidential OpenID Connect client, you must specify a method to authenticate. For more information, see OpenID Connect client authentication.

For more information, see Dynamic client registration.

Perform the steps in this procedure to obtain an ID token and an access token using the Implicit grant:

  1. The client makes a GET call to AM’s authorization endpoint specifying, at least, the following parameters:

    • client_id=your-client-id

    • response_type=token id_token

      To obtain only an ID token, use response_type=id_token instead.

    • redirect_uri=your-redirect-uri

    • nonce=your-nonce

    • 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 /alpha realm, then use /oauth2/realms/root/realms/alpha/authorize.

    For example:

    https://openam.example.com:8443/openam/oauth2/realms/root/realms/alpha/authorize \
    ?client_id=myClient \
    &response_type=token%20id_token \
    &scope=openid%20profile \
    &redirect_uri=https://www.example.com:443/callback \
    &state=abc123 \
    &nonce=123abc

    Note that the URL is split for readability purposes and that the state parameter has been included to protect against CSRF attacks.

  2. The end user logs in 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 the AM user interface consent screen:

    The OAuth 2.0 AM user interface consent screen requesting access to profile information.
    Figure 2. Consent Screen

    Note that requesting the profile scope translates into requesting access to several claims. For more information about the special profile scope, see Claims.

  3. The end user selects the Allow button to grant consent for the profile scope.

    AM redirects the resource owner to the URL specified in the redirect_uri parameter.

  4. Inspect the URL in the browser.

    It contains an access_token and an id_token parameter with the tokens AM has issued. For example:

    https://www.example.com:443/callback/#access_token=pRbNamsGPv1T7NfAf5Dbx4AHM2c&id_token=eyJ0eXAiOiJKV1QiLCJra...7r8soMCk8A7QdQpg&state=123&token_type=Bearer&expires_in=3599

    If you only request an ID token, the response would not include the access_token parameter.

  5. The relying party can request additional claims about the end user from AM.

    For more information, see /oauth2/userinfo.

Get an ID/access token without using a browser

This example shows how to obtain an ID token and an access token. It adds notes on how to obtain the ID token only, as well.

The procedure assumes the following configuration:

  • AM is configured as an OAuth 2.0/OpenID provider. Ensure that:

    • The token plugin is configured in the Response Type Plugins field.

    • The Implicit Grant grant type is configured in the Grant Types field.

    For more information, see OpenID provider configuration.

  • A public client called myClient is registered in AM with the following configuration:

    • Scopes: openid profile

    • Response Types: token id_token

    • Grant Types: Implicit

    • Authentication Method: none

      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 this procedure to obtain an ID token and an access token using the Implicit grant:

  1. The end user authenticates 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/realms/alpha/authenticate'
    {
        "tokenId":"AQIC5wM…​TU3OQ*",
        "successUrl":"/openam/console",
        "realm":"/alpha"
    }
  2. The client makes a POST call to the 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=token id_token

      To obtain only an ID token, use response_type=id_token instead.

    • redirect_uri=your-redirect-uri

    • nonce=your-nonce

    • 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 /alpha realm, then use /oauth2/realms/root/realms/alpha/authorize.

    For example:

    $ curl --dump-header - \
    --Cookie "iPlanetDirectoryPro=AQIC5wM…​TU3OQ*" \
    --request POST \
    --data "client_id=myClient" \
    --data "response_type=token id_token" \
    --data "scope=openid profile" \
    --data "state=123abc" \
    --data "nonce=abc123" \
    --data "decision=allow" \
    --data "csrf=AQIC5wM…​TU3OQ*" \
    --data "redirect_uri=https://www.example.com:443/callback" \
    "https://openam.example.com:8443/openam/oauth2/realms/root/realms/alpha/authorize"

    Note that the state parameter has been included to protect against CSRF attacks.

    If the authorization server is able to authenticate the user, it returns an HTTP 302 response with the access and ID tokens appended to the redirection URI:

    HTTP/1.1 302 Found
    Server: Apache-Coyote/1.1
    X-Frame-Options: SAMEORIGIN
    Pragma: no-cache
    Cache-Control: no-store
    Date: Mon, 04 Mar 2019 16:56:46 GMT
    Accept-Ranges: bytes
    Location: https://www.example.com:443/callback#access_token=az91IvnIQ-uP3Eqw5QqaXXY_DCo&id_token=eyJ0eXAiOiJKV1QiLCJra…​7r8soMCk8A7QdQpg&state=123abc&token_type=Bearer&expires_in=3599
    Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
    Content-Length: 0

    If you only request an ID token, the response would not include the access_token parameter.

  3. The relying party can request additional claims about the end user from AM.

    For more information, see /oauth2/userinfo.

For access to a sample JavaScript-based relying party to test the Implicit grant flow, see How do I access and build the sample code provided for PingAM? in the Knowledge Base.

Clone the example project to deploy it in the same web container as AM. Edit the configuration at the outset of the .js files in the project, register a corresponding profile for the example relying party as described in Dynamic client registration, and browse the deployment URL to see the initial page.

The example relying party validates the ID token signature using the default (HS256) algorithm, decodes de ID token to validate its contents and shows it in the output. Finally, the relying party uses the access token to request information about the end user who authenticated, and displays the result.