Automatically revoke access_token once session is destroyed

Hi guys!. I have to expose a scenario that we are facing right now working on AM:

Some context:

  • Max sessions per user: 1 (Session quota has been set up with DESTROY_NEXT_EXPIRING option)
  • We have a custom auth tree to authenticate our users. Once the user is authenticated, we are able to get a server session Id.
  • We are using a PKCE flow to get an access_token.

Now, this is our scenario:

  • User logs in on Device A - User is authenticated successfully and access_token is stored.
  • User logs in on Device B - User is authenticated successfully and access_token is stored, however session previously created on Device A has been destroyed.
  • User is able to call REST APIs on Device A, since the access_token is still invalid.

Is there any way to revoke automatically an access_token associated with a particular session?

Additional information:

  • ForgeRock Access Management 7.2.1
1 Like

Hello @caholguin,

Thanks for reaching out to the Community! I see you have also raised this issue through a support ticket. Once the AM Engineer assigned to your case confirms the resolution within the ticket, we will promptly share the recommended solution here as well to help others in the Community facing a similar challenge.

Warm Regards,
Ed

1 Like

Hi @edward.johnson ,

Do we have any updates on this ? I also had similar question.
We already have access_token with minimum lifetime but we need to understand if the user’s session is terminated (due to fraud, etc…) is there any ability to implicitly revoke/delete the issued access_token.

Regards,
~Ajay.

Hi All,

Do we have any solution here for this case?

How to revoke all access_tokens associated with a particular session?

Hi folks,

I’m glad to provide a recent update on the resolution for this inquiry regarding automatically revoking access tokens once a session is destroyed.

As I understand, the OAuth access token is not linked with the AM session. The following is taken from the FAQ: OAuth 2.0 in Identity Cloud and AM:

Q. Why is the OAuth access token still valid after the Identity Cloud or AM session has ended?

A. OAuth 2.0 does not check whether the assertion has been consumed or not; it only checks if it is valid. This means that even when an underlying Identity Cloud or AM session has ended (for example, there has been an IdP initiated single logout, the access token is still valid. The access token can be reused until the validity of the assertion has expired.

Note

AM provides an OAuth 2.0 Post-Authentication Plugin as part of the standard product delivery. You can configure this plugin so that the OAuth 2.0 authentication module logs the resource owner out with the OAuth 2.0 provider when logging out of AM. See Post-authentication plugins for further details and caveats.


I also wanted to share some questions that were raised, along with their corresponding answers, as they might be helpful for others facing similar inquiries:

  • When using Auth Trees instead of Auth Chains, Can the Post-authentication plugins, which look only applicable for Auth Chains, be used?

    • This is correct. Unfortunately, Post-authentication Plugins are only applicable to the authentication chain and not to the authentication tree.
  • Isn’t there a way to know the sessionId that was used to issue an access token? Let’s say that we want to implement some custom logic, where we want to revoke the access token using the tokenId as input.

    • As mentioned, OAuth 2.0 does not check whether the assertion has been consumed or not.

While it is not possible to revoke access_token associated with a particular session automatically, there is a Legacy OAuth 2.0 endpoint that you can use to obtain all the access tokens from the same user.

However, this endpoint would not work with client-based OAuth 2.0 tokens (stateless token). In addition (taken from : How do I know which endpoint to use for REST calls in newer versions of AM/OpenAM?), we would like to highlight to you that this endpoint is deprecated as of AM 5 and will be removed in future releases of AM. This would also mean that these deprecated endpoints are not supported.

If you planning to use the legacy endpoint, the steps are mentioned below:

For example, if you would like to list a specific user’s token, please execute the following REST command:

curl -X GET \
  'http://am.example.com:8080/openam/frrest/oauth2/token/?_queryId=userName=demo' \
  -H 'iplanetdirectorypro: pftzuI_xNaYJ3Tey1tTz14MOzls.*AAJTSQACMDEAAlNLABxCYzY1T1BuZzM4ejlwYzA2VXV1ZFgyNWFMQ1U9AAR0eXBlAANDVFMAAlMxAAA.*' <-- amadmin SSO Token ID

{
    "result": [
        {
            "_id": "rJ4owpaamhJdsjwGLR13hIx46Pg",
            "_rev": "-980589880",
            "clientID": [
                "myClientID"
            ],
            "auth_level": 0,
            "auditTrackingId": [
                "e38d2081-2ce3-4f2c-acf8-77b283409433-26542"
            ],
            "tokenName": [
                "access_token"
            ],
            "userName": [
                "demo"
            ],
            "authGrantId": [
                "1UfvWiiBP1h3kmykc5xpgbv-wAc"
            ],
            "nonce": [],
            "expireTime": "Aug 13, 2019 2:24 PM",
            "grant_type": [
                "token"
            ],
            "scope": [
                "profile"
            ],
            "auth_time": [
                "1565672640"
            ],
            "realm": [
                "/"
            ],
            "id": [
                "rJ4owpaamhJdsjwGLR13hIx46Pg" <-- access token id
            ],
            "tokenType": [
                "Bearer"
            ],
            "display_name": null,
            "scopes": "profile"
        },
        {
            "_id": "ecXLYkZd3APIHfETm4HIR8prpU8",
            "_rev": "-1454064015",
            "clientID": [
                "myClientID1"
            ],
            "auth_level": 0,
            "auditTrackingId": [
                "e38d2081-2ce3-4f2c-acf8-77b283409433-26665"
            ],
            "tokenName": [
                "access_token"
            ],
            "userName": [
                "demo"
            ],
            "authGrantId": [
                "WdHHYOxh34-LLIRT9iA2T_chh4E"
            ],
            "nonce": [],
            "expireTime": "Aug 13, 2019 2:25 PM",
            "grant_type": [
                "token"
            ],
            "scope": [
                "profile"
            ],
            "auth_time": [
                "1565672640"
            ],
            "realm": [
                "/"
            ],
            "id": [
                "ecXLYkZd3APIHfETm4HIR8prpU8" <--access token id
            ],
            "tokenType": [
                "Bearer"
            ],
            "display_name": null,
            "scopes": "profile"
        }
    ],
    "resultCount": 2,
    "pagedResultsCookie": null,
    "totalPagedResultsPolicy": "NONE",
    "totalPagedResults": -1,
    "remainingPagedResults": -1
}

The iplanetdirectorypro header take in SSO token of administrative user such as amadmin. To obtain SSO token of amadmin user (highlighted in bold):

curl -X POST \
  http://am.example.com:8080/openam/json/authenticate \
  -H 'Accept-API-Version: resource=2.0,protocol=1.0' \
  -H 'Content-Type: application/json' \
  -H 'X-OpenAM-Password: password' \
  -H 'X-OpenAM-Username: amadmin' \
  -H 'cache-control: no-cache' \
  -d '{}'
{
    "tokenId": "pftzuI_xNaYJ3Tey1tTz14MOzls.*AAJTSQACMDEAAlNLABxCYzY1T1BuZzM4ejlwYzA2VXV1ZFgyNWFMQ1U9AAR0eXBlAANDVFMAAlMxAAA.*", <-- amadmin SSO Token ID
    "successUrl": "/openam/console",
    "realm": "/"
}

After which, to delete the OAuth token, you could use the legacy endpoint (/frrest/oauth2/token/ ) or /oauth2/token/revoke endpoint.

For this example, we are deleting the access token (ecXLYkZd3APIHfETm4HIR8prpU8) authorize from myClientID OAuth2.0 agent.

 

To use legacy endpoint to delete token :

curl -X DELETE \
  http://am.example.com:8080/openam/frrest/oauth2/token/ecXLYkZd3APIHfETm4HIR8prpU8 \
  -H 'iplanetdirectorypro: pftzuI_xNaYJ3Tey1tTz14MOzls.*AAJTSQACMDEAAlNLABxCYzY1T1BuZzM4ejlwYzA2VXV1ZFgyNWFMQ1U9AAR0eXBlAANDVFMAAlMxAAA.*'

To use /oauth2/token/revoke endpoint to delete token:


curl -X POST \
  http://am.example.com:8080/openam/oauth2/realms/root/token/revoke \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'token=ecXLYkZd3APIHfETm4HIR8prpU8&client_id=myClientID&client_secret=password'
{}

I hope the above helps answer your inquiry and meet your requirements.

Warm regards,
Sheila