126 lines
4.9 KiB
Text
126 lines
4.9 KiB
Text
|
== Obtaining Permissions using UMA
|
||
|
|
||
|
One of the main features provided by {{book.project.name}} {{book.project.module}} is support for https://docs.kantarainitiative.org/uma/rec-uma-core.html[UMA] specification. UMA defines :
|
||
|
|
||
|
"`... how resource owners can control protected-resource access by clients operated by arbitrary requesting parties, where the resources reside on any number of resource servers, and where a centralized authorization server governs access based on resource owner policies.`"
|
||
|
|
||
|
[NOTE]
|
||
|
For now, {{book.project.name}} focus on API security and doesn't fully implement UMA. We don't support, yet, authorization flows where the user can manage their own resources and policies, share resources, and so forth.
|
||
|
|
||
|
=== Obtaining a Protection API Token (PAT)
|
||
|
The authorization process begins with a special type of token: the *Permission Ticket*. A permission ticket can only be obtained by a resource server using a OAuth2 access token with the scope
|
||
|
*uma_protection*. In UMA, the access token with the scope *uma_protection* is called a Protection API Token or PAT.
|
||
|
|
||
|
When we created the *hello-world-authz* realm, we also granted the scope *uma_protection* to the *hello-world-authz-service* client application. Considering that this application is also a *confidential* client,
|
||
|
you can obtain a PAT as follows:
|
||
|
|
||
|
```curl
|
||
|
curl -X POST \
|
||
|
-H "Authorization: Basic aGVsbG8td29ybGQtYXV0aHotc2VydmljZTpwYXNzd29yZA==" \
|
||
|
-H "Content-Type: application/x-www-form-urlencoded" \
|
||
|
-d 'grant_type=client_credentials' \
|
||
|
"http://localhost:8080/auth/realms/hello-world-authz/protocol/openid-connect/token"
|
||
|
```
|
||
|
|
||
|
As a result, you will get the following response from the server:
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"access_token": ${access_token},
|
||
|
"expires_in": 300,
|
||
|
"refresh_expires_in": 1800,
|
||
|
"refresh_token": ${refresh_token},
|
||
|
"token_type": "bearer",
|
||
|
"id_token": ${id_token},
|
||
|
"not-before-policy": 0,
|
||
|
"session_state": "ccea4a55-9aec-4024-b11c-44f6f168439e"
|
||
|
}
|
||
|
```
|
||
|
|
||
|
Here, the ${access_token} represents a PAT, which is basically an OAuth2 access token with the scope *uma_protection*. With this token, you can now obtain a permission ticket from the
|
||
|
Protection API.
|
||
|
|
||
|
=== Obtaining a Permission Ticket
|
||
|
|
||
|
Once you have a PAT, you can use it to access the Protection API in order to obtain a permission ticket as follows:
|
||
|
|
||
|
```json
|
||
|
curl -X POST \
|
||
|
-H "Authorization: Bearer ${access_token}" \
|
||
|
-d '
|
||
|
{
|
||
|
"resource_set_id" : "Hello World Resource"
|
||
|
}
|
||
|
' \
|
||
|
"http://localhost:8080/auth/realms/hello-world-authz/authz/protection/permission"
|
||
|
```
|
||
|
|
||
|
As a result, you will get the following response from the server:
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"ticket": ${permission_ticket}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
Here, we are asking the Protection API for a permission ticket representing the same extent of requested access that the resource server registered. In this case, the access request to
|
||
|
the _Hello World Resource_ resource.
|
||
|
|
||
|
=== Obtaining an Authorization API Token
|
||
|
|
||
|
The final step is obtain a *Requesting Party Token* or *RPT* with a set of authorization data, that will be used to actually gain access to protected resources at the resource server.
|
||
|
|
||
|
A RPT is obtained from the link:../service/authorization-api.html[Authorization API]. Just like the Protection API and Permission Tickets, the Authorization API also requires a special
|
||
|
OAuth2 access token to obtain a RPT. In UMA, this access token is called a *Authorization API Token* or *AAT*, which contains a scope *uma_authorization* in it.
|
||
|
|
||
|
The *uma_authorization* scope indicates that an user consented to allow a given client application to access authorization data on his behalf. When we created the *hello-world-authz* realm,
|
||
|
we also defined a client role to the users:
|
||
|
|
||
|
```json
|
||
|
"clientRoles" : {
|
||
|
"hello-world-authz-service" : [ "uma_authorization" ]
|
||
|
}
|
||
|
```
|
||
|
|
||
|
To obtain an AAT you can send a request to {{book.project.name}} as follows:
|
||
|
|
||
|
```bash
|
||
|
curl -X POST \
|
||
|
-H "Authorization: Basic aGVsbG8td29ybGQtYXV0aHotc2VydmljZTpwYXNzd29yZA==" \
|
||
|
-H "Content-Type: application/x-www-form-urlencoded" \
|
||
|
-d 'username=alice&password=password&grant_type=password' \
|
||
|
"http://localhost:8080/auth/realms/hello-world-authz/protocol/openid-connect/token"
|
||
|
```
|
||
|
As a result, you will get the following response from the server:
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"access_token": ${access_token},
|
||
|
"expires_in": 300,
|
||
|
"refresh_expires_in": 1800,
|
||
|
"refresh_token": ${refresh_token},
|
||
|
"token_type": "bearer",
|
||
|
"id_token": ${id_token},
|
||
|
"not-before-policy": 0,
|
||
|
"session_state": "3cad2afc-855b-47b7-8e4d-a21c66e312fb"
|
||
|
}
|
||
|
```
|
||
|
|
||
|
=== Obtaining a Requesting Party Token or RPT
|
||
|
|
||
|
Now that we have a AAT we can call the Authorization API and ask for a RPT.
|
||
|
|
||
|
```bash
|
||
|
curl -X POST
|
||
|
-H "Authorization: Bearer ${AAT}" -d '{
|
||
|
"ticket" : ${permission_ticket}
|
||
|
}' "http://localhost:8080/auth/realms/hello-world-authz/authz/authorize"
|
||
|
```
|
||
|
|
||
|
As a result, you will get the follow response from the server:
|
||
|
|
||
|
```json
|
||
|
{"rpt":"${rpt}"}
|
||
|
```
|
||
|
|
||
|
=== Obtaining Permissions using the Entitlement API
|