The UMA Guide Example
A resource owner, Alice, is a patient who plans to undergo a medical procedure at a surgery center. Dr. Bob is a specialist surgeon who needs read access (for example, view
scope) to Alice's electronic health records in order to operate, and write access (for example, comment
scope) in order to add new entries related to the surgery. These records are a resource whose contents have built up over time and to which Alice's regular physician, Dr. Carol, has access already.
Alice, or some party representing Alice, registers her medical health records and sets up permissions using authorization policies, allowing Dr. Bob and Dr. Carol access to her health data. On an online healthcare application, Alice can easily grant consent by clicking a "Share" button to her data, or decline access by clicking a "Deny" button.
UMA also solves managed consent for IoT deployments. For example, Alice will need to be monitored after her operation. Dr. Bob prescribes a smart medical device for Alice, such as a clinical-grade blood pressure monitor, which must be registered by the resource server to place it under the authorization server's protection. The blood pressure monitor sends data to a server that aggregates and transmits the data to external devices, allowing Dr. Bob and Dr. Carol access to Alice's data on their tablets or mobile apps.
AM supports a one-to-many policy that can be shared with many entities, not just targeting a single requesting party. Thus, Alice is able to share her data with Dr. Bob, Dr. Carol, as well as with the clinical and operational employees at the surgery center.
In this example, you will learn how to:
Create an example configuration in AM.
Register and protect a resource as the resource owner.
Request access to the resource as the requesting party, by partaking in the UMA grant flow.
Important
The example will not give you insight on the more technical aspects of UMA. It is only meant to demo the concepts and the flows.
Read the rest of the topics on this guide to learn how to configure UMA in production environments, and for more in-depth explanations regarding how to use the REST APIs.
You can configure UMA manually by following the steps in a series of procedures, and then run the flow examples using your preferred REST client, or you can use the ForgeRock UMA Postman collection:
Download a Postman collection to configure AM and to run the example scenarios. If this is your first time with UMA, you may want to read through the manual steps as you run the collection to better understand the calls being made. | Configure AM and run the example scenarios manually. |
The Postman Collection
ForgeRock provides an UMA Postman collection to help configure AM for the example, and to run each of the steps in the procedures contained within. It also contains REST calls to the supporting UMA endpoints that you can run as part of the example.
Download and install Postman.
Download the ForgeRock UMA Postman Collection.
Import the collection in Postman:
Go to File > Import ... > Upload Files.
Select the collection you downloaded, and click Open. Then, click Import.
Configure the collection's variables to suit your environment:
In Postman, on the Collections tab, select the ForgeRock UMA Collection. Click on the ... button, and then on Edit.
The Edit Collection page appears.
Click on the Variables tab, and change at least the value of the following variables:
URL_base
admin_password
Click Update to save your changes.
You are ready to start running the collection.
The collection is divided into the following folders:
Prerequisites
, containing REST calls equivalent to the configuration tasks in "Configuring AM for UMA".If your run the calls in this folder, do not perform the equivalent manual steps to avoid object conflicts.
UMA Registration Flow
, containing the REST calls in "Registering and Protecting an UMA Resource".UMA Grant Flow
, containing the REST calls in "Requesting Access to a Resource".Managing UMA Resources
, containing REST calls related to the "/uma/resource_set" endpoint.Managing UMA User Labels
, containing REST calls related to the "How to Manage UMA User and Favorite Labels" endpoint.Managing UMA Policies
, containing REST calls related to the "/json/users/{user}/uma/policies" endpoint.
Manual Steps
The high-level steps to run the example manually are as follows:
Configuring AM for UMA
To configure the example UMA deployment to test the procedures in this documentation, perform the following tasks:
Task | Description |
---|---|
Create an OAuth 2.0 provider service with a basic configuration. | |
Create a UMA provider service with a basic configuration. | |
Create an UMA client. | |
Create an UMA resource server client. | |
Create an OAuth2/OpenID Connect provider. | |
Create a resource owner. | |
Create a requesting party. |
This procedure shows you how to configure a basic OAuth 2.0 provider suitable for the example.
In the AM console, go to Realms > Top Level Realm > Services.
Create an OAuth 2.0 provider, or configure it if one is already created.
If an OAuth 2.0 provider is already created, click on it.
If there is no OAuth 2.0 provider, add one:
Click Add a Service.
On the drop-down menu, select the OAuth2 Provider service. Then, click the Create button without filling any other field.
The OAuth 2.0 provider page appears.
Go to the Advanced tab.
Ensure that the following fields are configured:
Grant Types: At least,
UMA
andResource Owner Password Credentials
must be configured.Response Type Plugins: At least,
id_token|org.forgerock.openidconnect.IdTokenResponseTypeHandler
andtoken|org.forgerock.oauth2.core.TokenResponseTypeHandler
must be configured.
In the AM console, go to Realms > Top Level Realm > Services, and add an UMA Provider service.
The default configuration suitable for the example. For production environments, see Configuring the UMA Actors.
Create a profile for the example UMA client in AM. Since this client will partake in the UMA grant, which requires an ID token, you need to configure OpenID Connect properties on it, too:
In the AM console, go to Realms > Top Level Realm > Applications > OAuth 2.0 > Clients.
Click Add Client, and enter the following values:
Client ID :
UmaClient
Client secret:
password
Redirection URIs:
redirection URI
. For this example, leave it blank.Scope(s):
view openid comment download
You will need to enter
view
, press Enter, and then enteropenid
, and so on.Default Scope(s): For this example, leave it blank.
Click Create. The page for the client appears.
In the Advanced tab, enter the following values:
Grant Types:
UMA
,Resource Owner Password Credentials
You will need to enter
UMA
, press Enter, and then enterResource Owner Password Credentials
.This example uses the Resource Owner Password Credentials grant, but you can use any grant type except the Client Credentials one. This is because this client acts on behalf of the requesting party, which needs to authenticate with their identities as part of the flow.
Token Endpoint Authentication Method:
client secret post
Confidential OpenID Connect clients can use several methods to authenticate, but this example uses
client secret post
for clarity. For more information, see OpenID Connect Client Authentication.
Save your changes.
Create a profile for the example resource server client in AM. This client only needs to obtain PATs and therefore, it does not require any OpenID Connect-related configuration.
In the AM console, go to Realms > Top Level Realm > Applications > OAuth 2.0 > Clients.
Click Add Client, and enter the following values:
Client ID:
Uma-Resource-Server
Client secret:
password
Redirection URIs:
redirection URI
. For this example, leave it blank.Scope(s):
uma_protection
Default Scope(s): For this example, leave it blank.
Click Create. The page for the client appears.
In the Advanced tab, enter the following values:
Grant Types:
Resource Owner Password Credentials
This example uses the Resource Owner Password Credentials grant, but you can use any grant type except the Client Credentials one. This is because the resource owner must authenticate to the resource server.
Save your changes.
In the AM console, go to Realms > Top Level Realm > Identities.
Click New, and create a new requesting party. This example uses the following values:
ID:
alice
First Name:
Alice
Last Name:
Resource-Owner
Full Name:
Alice Resource-Owner
Password:
Ch4ng31t
Click Create.
In the AM console, go to Realms > Top Level Realm > Identities.
Click New, and create a new requesting party. This example uses the following values:
ID:
bob
First Name:
Bob
Last Name:
Requesting-Party
Full Name:
Bob Requesting-Party
Password:
Ch4ng31t
Click Create.
Registering and Protecting an UMA Resource
Alice, the resource owner, has been provided with the latest results of their medical procedure. To share the results with their doctors, Alice registers them online in their surgery's resource server, and lets Dr. Bob view them and comment on them:
A resource owner wants to make a resource sharable and sends a request to the resource server (labeled 1 in the diagram).
The resource server requires the resource owner to acquire a PAT on the authorization server (2).
The authorization server returns a PAT, which lets the resource owner register resources and manage policies (3).
The resource server registers the resource on the authorization server at the resource registration endpoint (4).
The resource owner creates a policy after registering the resource (5).
Perform the steps in the following procedure to register an example resource and protect it as Alice:
Alice's client application requests a PAT on their behalf. The client application will use it as an authorization token to register Alice's medical records, which already are stored in their surgery's resource server, in AM.
The following example uses the Resource Owner Password Credentials grant:
$
curl \ --request POST \ --data 'grant_type=password' \ --data 'scope=uma_protection' \ --data 'username=alice' \ --data 'password=Ch4ng31t' \ --data 'client_id=UMA-Resource-Server' \ --data 'client_secret=password' \ https://openam.example.com:8443/openam/oauth2/realms/root/access_token
{ "access_token": "057ad16f-7dba-4049-9f34-e609d230d43a", "refresh_token": "340f82a4-9aa9-471c-ac42-f0ca1809c82b", "scope": "uma_protection", "token_type": "Bearer", "expires_in": 4999 }
The value returned in the
access_token
object is the PAT.Alice registers their medical records in AM as an UMA resource. Their client application must use the PAT token obtained before as authorization:
$
curl -X POST \ --header 'authorization: Bearer 057ad16f-7dba-4049-9f34-e609d230d43a' \
--header 'cache-control: no-cache' \ --header 'content-type: application/json' \ --data '{ "resource_scopes": [ "view", "comment", "download"
], "name": "my resource 106", "type": "type" }' \ https://openam.example.com:8443/openam/uma/realms/root/resource_set
{ "_id": "0d7790de-9066-4bb6-8e81-25b6f9d0b8853",
"user_access_policy_uri": "https://openam.example.com:8443/openam/XUI/?realm=/#uma/share/0d7790de-9066-4bb6-8e81-25b6f9d0b8853" }
Use the PAT previously acquired on behalf of Alice.
A set of actions or permissions that the resource supports. Since UMA is an OAuth 2.0/OpenID Connect extension, the permissions are in the form of scopes.
The value returned in the
_id
property is the ID of the new UMA resource.The resource is ready. Now Alice must create a policy to share it with Dr. Bob, specifying which actions Dr. Bob can do on the resource.
Alice logs in to AM, the UMA authorization sever:
$
curl \ --request POST \ --header "Content-Type: application/json" \ --header "X-OpenAM-Username: alice" \ --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":"AQIC5wM2LY4S...Q4MTE4NTA2*", "successUrl":"/openam/console", "realm":"/" }
The value returned in the
tokenId
object is Alice's session token.Using their client application, Alice creates a policy to share the newly created resource with Dr. Bob:
$
curl \ --request PUT \ --header "Accept-API-Version: resource=1.0" \ --header "Cache-Control: no-cache" \ --header "Content-Type: application/json" \
--header "iPlanetDirectoryPro: AQIC5wM2LY4S...Q4MTE4NTA2*" \ --header "If-None-Match: *" \ --data '{
"policyId": "0d7790de-9066-4bb6-8e81-25b6f9d0b8853", "permissions": [ { "subject": "b
ob", "scopes": [ "view", "comment" ] } ] }' \
https://openam.example.com:8443/openam/json/realms/root/users/alice/uma/policies/0d7790de-9066-4bb6-8e81-25b6f9d0b8853
{ "_id": "0d7790de-9066-4bb6-8e81-25b6f9d0b8853", "_rev": "-1985914901" }
Use Alice's session token. Administrative users such as
amAdmin
cannot create UMA resource policies on behalf of a resource owner.Use the ID of the UMA resource.
A subset of the permissions or scopes available for this resource. The requesting party,
"subject": "bob"
, can only view or comment on the resource, but not download it.Use the ID of the UMA resource, appended at the end of the URL.
The resource is now shared with Dr. Bob, who has permission to
view
andcomment
on Alice's records.
Requesting Access to a Resource
When the requesting party, Dr. Bob, needs to access Alice's records, he uses an application in their computer. The application makes a call to AM to request permission to see Alice's records. Once granted, the application can show that permission token to the server that stores Alice's records.
This, in a nutshell, is the UMA Grant flow.
Perform the steps in the following procedure to request access to Alice's records as Dr. Bob's client application:
Acquire a PAT on behalf of Alice. We will use it later to authorize a permission ticket for Dr. Bob.
The following example uses the Resource Owner Password Credentials grant:
$
curl \ --request POST \ --data 'grant_type=password' \ --data 'scope=uma_protection' \ --data 'username=alice' \ --data 'password=Ch4ng31t' \ --data 'client_id=UMA-Resource-Server' \ --data 'client_secret=password' \ https://openam.example.com:8443/openam/oauth2/realms/root/access_token
{ "access_token": "057ad16f-7dba-4049-9f34-e609d230d43a", "refresh_token": "340f82a4-9aa9-471c-ac42-f0ca1809c82b", "scope": "uma_protection", "token_type": "Bearer", "expires_in": 4999 }
The value returned in
access_token
is the PAT.Create a permission ticket for Dr. Bob's client application.
Permission tickets let requesting parties request access to a particular resource. In this case, Dr. Bob's client application needs a permission ticket to access Alice's medical records.
$
curl -X POST \ --header 'authorization: Bearer 057ad16f-7dba-4049-9f34-e609d230d43a' \
--header 'cache-control: no-cache' \ --header 'content-type: application/json' \ --data '[ { "resource_id" : "ef4d750e-3831-483b-b395-c6f059b5e15d0",
"resource_scopes" : ["download"] } ]' \ https://openam.example.com:8443/openam/uma/realms/root/permission_request
{ "ticket": "eyJ0eXAiOiJ...XPeJi3E"
}
Use the PAT previously acquired on behalf of Alice.
The ID of the protected resource. This is the ID of the resource created in "To Register an UMA Resource (REST)".
The permission ticket, which links Alice's identity to a resource, and to the action Dr. Bob's requesting to do.
Gather information about the requesting party.
To request access to Alice's records, Dr. Bob and their client application must prove their identity to the authorization server, AM. AM will issue them an ID token with their identity's details.
$
curl -X POST \ --data 'client_id=UmaClient' \ --data 'client_secret=password' --data 'grant_type=password' \ --data 'scope=openid' \ --data 'username=bob' \ --data 'password=Ch4ng31t' \ https://openam.example.com:8443/openam/oauth2/realms/root/access_token
{ "access_token": "f09f55e5-5e9c-48fe-aeaa-d377de88e8e6", "refresh_token": "ee2d35f6-5819-4734-8b3e-9af77a545563", "scope": "openid", "id_token": "eyJ0eXA...FBznEB5A", "token_type": "Bearer", "expires_in": 4999 }
The value of the
id_token
object, which is an OpenID Connect ID token, is the UMA claim token that provides information about Dr. Bob.Request an RPT for Dr. Bob so that they have access to Alice's records.
$
curl -X POST \ --data 'client_id=UmaClient' \ --data 'client_secret=password' \ --data 'grant_type=urn:ietf:params:oauth:grant-type:uma-ticket' \ --data 'ticket=eyJ0eXAiOiJ...XPeJi3E' \
--data 'claim_token=eyJ0eXA...FBznEB5A' \ --data 'claim_token_format=http://openid.net
/specs/openid-connect-core-1_0.html#IDToken' \ https://openam.example.com:8443/openam/oauth2/realms/root/access_token
{ "access_token": "Aw4a92ZoKsjadWKw2d4Rmcjv7DM", "token_type": "Bearer", "expires_in": 3599 }
Use the permission ticket previously obtained.
Use the claim token previously obtained.
The value of the
access_token
object is the RPT.Presenting the RPT, Dr. Bob's client application can now access Alice's records in their surgery's resource server.
Tip
Permission tickets have a lifetime of 180 seconds by default. AM will return a message similar to the following if the ticket has expired:
{ "error_description": "The provided access grant is invalid, expired, or revoked.", "error": "invalid_grant" }
Obtain a new permission ticket and try requesting the RPT again.
What's Next?
Now you can use the knowledge you gained by running through the example to develop and configure your own UMA environment.
The following table shows the different tasks you need to perform to do so, and the associated documentation:
Task | Resources |
---|---|
Learn about AM as the authorization service, and configure the UMA actors. | |
Learn more about resources, resource labels, and authorization policies, and their specific REST endpoints. | |
Discover how to extend the default UMA implementation to suit your environment's needs. |