Script required scopes
This example builds on the example in Validate access tokens with introspection to use a script to define the scopes that a request requires in an access token.
-
If the request path is
/rs-tokeninfo
, the request requires only the scopemail
. -
If the request path is
/rs-tokeninfo/employee
, the request requires the scopesmail
andemployeenumber
.
Before you start, set up and test the example in Validate access tokens with introspection.
-
Add the following route to PingGateway:
-
Linux
-
Windows
$HOME/.openig/config/routes/rs-dynamicscope.json
%appdata%\OpenIG\rs-dynamicscope.json
{ "name": "rs-dynamicscope", "baseURI": "http://app.example.com:8081", "condition": "${find(request.uri.path, '^/rs-dynamicscope')}", "heap": [ { "name": "SystemAndEnvSecretStore-1", "type": "SystemAndEnvSecretStore" }, { "name": "AmService-1", "type": "AmService", "config": { "agent": { "username": "ig_agent", "passwordSecretId": "agent.secret.id" }, "secretsProvider": "SystemAndEnvSecretStore-1", "url": "http://am.example.com:8088/openam/" } } ], "handler": { "type": "Chain", "config": { "filters": [ { "name": "OAuth2ResourceServerFilter-1", "type": "OAuth2ResourceServerFilter", "config": { "scopes": { "name": "myscript", "type": "ScriptableResourceAccess", "config": { "type": "application/x-groovy", "source": [ "// Minimal set of required scopes", "def scopes = [ 'mail' ] as Set", "if (request.uri.path =~ /employee$/) {", " // Require another scope to access this resource", " scopes += 'employeenumber'", "}", "return scopes" ] } }, "requireHttps": false, "realm": "OpenIG", "accessTokenResolver": { "name": "token-resolver-1", "type": "TokenIntrospectionAccessTokenResolver", "config": { "amService": "AmService-1", "providerHandler": { "type": "Chain", "config": { "filters": [ { "type": "HttpBasicAuthenticationClientFilter", "config": { "username": "ig_agent", "passwordSecretId": "agent.secret.id", "secretsProvider": "SystemAndEnvSecretStore-1" } } ], "handler": "ForgeRockClientHandler" } } } } } } ], "handler": { "type": "StaticResponseHandler", "config": { "status": 200, "headers": { "Content-Type": [ "text/html; charset=UTF-8" ] }, "entity": "<html><body><h2>Decoded access_token: ${contexts.oauth2.accessToken.info}</h2></body></html>" } } } } }
-
-
Test the setup with the
mail
scope only:-
In a terminal, use a
curl
command to retrieve an access token with the scopemail
:$ mytoken=$(curl -s \ --user "client-application:password" \ --data "grant_type=password&username=demo&password=Ch4ng31t&scope=mail" \ http://am.example.com:8088/openam/oauth2/access_token | jq -r ".access_token")
-
Confirm that the access token is returned for the
/rs-dynamicscope
path:$ curl -v \ --cacert /path/to/secrets/ig.example.com-certificate.pem \ --header "Authorization: Bearer ${mytoken}" \ https://ig.example.com:8443/rs-dynamicscope { active = true, scope = mail, client_id = client-application, user_id = demo, token_type = Bearer, exp = 158...907, sub = demo, iss = http://am.example.com:8088/openam/oauth2, ... ... }
-
Confirm that the access token is not returned for the
/rs-dynamicscope/employee
path:$ curl -v \ --cacert /path/to/secrets/ig.example.com-certificate.pem \ --header "Authorization: Bearer ${mytoken}" \ https://ig.example.com:8443/rs-dynamicscope/employee
-
-
Test the setup with the scopes
mail
andemployeenumber
:-
In a terminal window, use a
curl
command similar to the following to retrieve an access token with the scopesmail
andemployeenumber
:$ mytoken=$(curl -s \ --user "client-application:password" \ --data "grant_type=password&username=demo&password=Ch4ng31t&scope=mail%20employeenumber" \ http://am.example.com:8088/openam/oauth2/access_token | jq -r ".access_token")
-
Confirm that the access token is returned for the
/rs-dynamicscope/employee
path:$ curl -v --cacert /path/to/secrets/ig.example.com-certificate.pem \ --header "Authorization: Bearer ${mytoken}" https://ig.example.com:8443/rs-dynamicscope/employee
-