Customizing OAuth 2.0 Scope Handling

RFC 6749, The OAuth 2.0 Authorization Framework, describes access token scopes as a set of case-sensitive strings defined by the authorization server. Clients can request scopes, and resource owners can authorize them.

The default scopes implementation in AM treats scopes as per RFC 7662, while the legacy /oauth2/tokeninfo endpoint populates the scopes with profile attribute values. For example, if one of the scopes is mail, AM sets mail to the resource owner's email address in the token information returned.

You can change the scope implementation behavior by writing your own scope validator plugin. This section shows how to write a custom OAuth 2.0 scope validator plugin for use in an OAuth 2.0 provider (authorization server) configuration.

Tip

The default scope validator calls the script that lets AM modify the key pairs contained inside an access token before issuing it. If you intend to use this functionality, you must incorporate this call into your custom scope validator implementation.

About the Scope Validator Plugin Sample

A scope validator plugin implements the org.forgerock.oauth2.core.ScopeValidator interface. As described in the API specification, the ScopeValidator interface has several methods that your plugin overrides.

The following plugin, taken from the openam-scope-sample example, sets whether read and write permissions were granted.

[/home/jenkins/workspace/ipelines_product-docs-qa-release/src/main/docbkx/resources/CustomScopeValidator.java]

For information on downloading and building AM sample source code, see How do I access and build the sample code provided for AM/OpenAM (All versions)? in the Knowledge Base.

Get a local clone so that you can try the sample on your system.

pom.xml

Apache Maven project file for the module

This file specifies how to build the sample scope validator plugin, and also specifies its dependencies on AM components.

src/main/java/org/forgerock/openam/examples/CustomScopeValidator.java

Core class for the sample OAuth 2.0 scope validator plugin

See "About the Scope Validator Plugin Sample" for a listing.

After you successfully build the project, you find the openam-scope-sample-7.1.jar in the /path/to/openam-samples-external/openam-scope-sample/target directory of the project.

Configuring an Instance to Use the Plugin

After building your plugin .jar file, copy the .jar file under WEB-INF/lib/ where you deployed AM.

Restart AM or the container in which it runs.

In the AM console, you can either configure a specific OAuth 2.0 provider to use your plugin, or configure your plugin as the default for new OAuth 2.0 providers. In either case, you need the class name of your plugin. The class name for the sample plugin is org.forgerock.openam.examples.CustomScopeValidator.

  • To configure a specific OAuth 2.0 provider to use your plugin, navigate to Realms > Realm Name > Services, click OAuth2 Provider, and enter the class name of your scopes plugin to the Scope Implementation Class field.

  • To configure your plugin as the default for new OAuth 2.0 providers, add the class name of your scopes plugin. Navigate to Configure > Global Services, click OAuth2 Provider, and set Scope Implementation Class.

Trying the Sample Plugin

In order to try the sample plugin, make sure you have configured an OAuth 2.0 provider to use the sample plugin. Also, set up an OAuth 2.0 client of the provider that takes scopes read and write.

Next try the provider as shown in the following example:

$ curl \
--request POST \
--data "grant_type=client_credentials \
&client_id=myClientID&client_secret=password&scope=read" \
"https://openam.example.com:8443/openam/oauth2/realms/root/access_token"
{
    "scope": "read",
    "expires_in": 59,
    "token_type": "Bearer",
    "access_token": "c8860442-daba-4af0-a1d9-b607c03e5a0b"
}

$ curl https://openam.example.com:8443/openam/oauth2/realms/root/tokeninfo\
?access_token=0d492486-11a7-4175-b116-2fc1cbff6d78
{
    "scope": [
        "read"
    ],
    "grant_type": "client_credentials",
    "realm": "/",
    "write": false,
    "read": true,
    "token_type": "Bearer",
    "expires_in": 24,
    "access_token": "c8860442-daba-4af0-a1d9-b607c03e5a0b"
}

As seen in this example, the requested scope read is authorized, but the write scope has not been authorized.

Read a different version of :