diff --git a/SUMMARY.adoc b/SUMMARY.adoc index 776629abda..4ff26da77d 100755 --- a/SUMMARY.adoc +++ b/SUMMARY.adoc @@ -30,16 +30,17 @@ .. link:topics/policy/evaluation-api.adoc[Policy Evaluation API] . link:topics/policy-evaluation-tool/overview.adoc[Evaluating and Testing Policies] . link:topics/service/overview.adoc[Authorization Services] - .. link:topics/service/protection-api.adoc[Protection API] - ... link:topics/service/whatis-obtain-pat.adoc[What is a PAT and How to Obtain It] - ... link:topics/service/resources-api-papi.adoc[Managing Resources] - ... link:topics/service/permission-api-papi.adoc[Managing Permission Requests] - .. link:topics/service/authorization-api.adoc[Authorization API] - ... link:topics/service/whatis-obtain-aat.adoc[What is a AAT and How to Obtain It] - ... link:topics/service/authorization-api-aapi.adoc[Requesting Authorization Data and Token] - .. link:topics/service/entitlement-api.adoc[Entitlement API] - ... link:topics/service/whatis-obtain-eat.adoc[What is a EAT and How to Obtain It] - ... link:topics/service/entitlement-api-aapi.adoc[Requesting Entitlements] + .. link:topics/service/protection/protection-api.adoc[Protection API] + ... link:topics/service/protection/whatis-obtain-pat.adoc[What is a PAT and How to Obtain It] + ... link:topics/service/protection/resources-api-papi.adoc[Managing Resources] + ... link:topics/service/protection/permission-api-papi.adoc[Managing Permission Requests] + ... link:topics/service/protection/token-introspection.adoc[Introspecting a Requesting Party Token] + .. link:topics/service/authorization/authorization-api.adoc[Authorization API] + ... link:topics/service/authorization/whatis-obtain-aat.adoc[What is a AAT and How to Obtain It] + ... link:topics/service/authorization/authorization-api-aapi.adoc[Requesting Authorization Data and Token] + .. link:topics/service/entitlement/entitlement-api.adoc[Entitlement API] + ... link:topics/service/entitlement/whatis-obtain-eat.adoc[What is a EAT and How to Obtain It] + ... link:topics/service/entitlement/entitlement-api-aapi.adoc[Requesting Entitlements] .. link:topics/service/client-api.adoc[Authorization Client Java API] . link:topics/enforcer/overview.adoc[Policy Enforcers] .. link:topics/enforcer/keycloak-enforcement-filter.adoc[Keycloak Servlet Policy Enforcer] diff --git a/topics/enforcer/bearer-enforcement-filter.adoc b/topics/enforcer/bearer-enforcement-filter.adoc index 619c66333c..a77943ddbb 100755 --- a/topics/enforcer/bearer-enforcement-filter.adoc +++ b/topics/enforcer/bearer-enforcement-filter.adoc @@ -19,6 +19,14 @@ To configure it, change your web application descriptor (WEB-INF/web.xml) as fol ``` +When using this filter, client applications need to send a RPT as a *Bearer* token using the *Authorization* header in order to gain access to a protected resource. + +```bash +curl -X GET \ + -H "Authorization: Bearer %{RPT}" \ + "http://my-app/api/resource" +``` + === Configuration The BearerTokenEnforcementFilter can be configured by a simple JSON file. The file can be as simple as: diff --git a/topics/service/authorization-api-aapi.adoc b/topics/service/authorization/authorization-api-aapi.adoc similarity index 100% rename from topics/service/authorization-api-aapi.adoc rename to topics/service/authorization/authorization-api-aapi.adoc diff --git a/topics/service/authorization-api.adoc b/topics/service/authorization/authorization-api.adoc similarity index 100% rename from topics/service/authorization-api.adoc rename to topics/service/authorization/authorization-api.adoc diff --git a/topics/service/whatis-obtain-aat.adoc b/topics/service/authorization/whatis-obtain-aat.adoc similarity index 100% rename from topics/service/whatis-obtain-aat.adoc rename to topics/service/authorization/whatis-obtain-aat.adoc diff --git a/topics/service/entitlement-api-aapi.adoc b/topics/service/entitlement-api-aapi.adoc deleted file mode 100755 index 31a9dd6555..0000000000 --- a/topics/service/entitlement-api-aapi.adoc +++ /dev/null @@ -1,56 +0,0 @@ -== Requesting Entitlements - -Client applications can use a specific endpoint to obtain a special security token called *Requesting Party Token* or *RPT*. -This token consists of all the entitlements(or permissions) for an user as a result of the evaluation of the permissions and authorization policies associated with the resource(s) being requested. -With an RPT in hands, client applications can gain access to protected resources at the resource server. - -```bash -http://${host}:${port}/auth/realms/${realm_name}/authz/entitlement -``` - -When asking for entitlements using this endpoint, you need to provide the EAT (as a bearer token) representing user's identity and his consent to access authorization data on his behalf. - -```bash -curl -X GET \ - -H "Authorization: Bearer ${EAT}" \ - "http://localhost:8080/auth/realms/hello-world-authz/authz/entitlement/${resource_server_id}" -``` - -Where *${resource_server_id}* is the *client_id* for the client application registered as a resource server. - -As a result, you'll get a response from the server as follows: - -```json -{ - "rpt": ${RPT} -} -``` - -=== Requesting Party Token or RPT - -A RPT is basically a https://tools.ietf.org/html/rfc7519[JSON Web Token (JWT)] digitally signed using https://www.rfc-editor.org/rfc/rfc7515.txt[JSON Web Signature (JWS)]. -Its lifetime is the same as with the OAuth2 access token (EAT) that was used to obtain it. - -When you decode a RPT you will see something like that: - -```json -{ - "permissions": [ - { - "resource_set_id": "152251e6-f4cf-4464-8d91-f1b7960fa5fc", - "resource_set_name": "Hello World Resource" - "scopes": [] - } - ], - "accessToken": ${EAT}, - "jti": "d6109a09-78fd-4998-bf89-95730dfd0892-1464906679405", - "exp": 1464906971, - "nbf": 0, - "iat": 1464906671, - "sub": "f1888f4d-5172-4359-be0c-af338505d86c", - "typ": "kc_ett", - "azp": "hello-world-authz-service" -} -``` - -The *permissions* claim consists of all the permissions granted by the server. There is also a *accessToken* property holding the AAT that was used to issue the RPT. \ No newline at end of file diff --git a/topics/service/entitlement/entitlement-api-aapi.adoc b/topics/service/entitlement/entitlement-api-aapi.adoc new file mode 100755 index 0000000000..113b329ac6 --- /dev/null +++ b/topics/service/entitlement/entitlement-api-aapi.adoc @@ -0,0 +1,106 @@ +== Requesting Entitlements + +Client applications can use a specific endpoint to obtain a special security token called *Requesting Party Token* or *RPT*. +This token consists of all the entitlements(or permissions) for an user as a result of the evaluation of the permissions and authorization policies associated with the resource(s) being requested. +With an RPT in hands, client applications can gain access to protected resources at the resource server. + +```bash +http://${host}:${port}/auth/realms/${realm_name}/authz/entitlement +``` + +=== Obtaining Entitlements + +The easiest way to obtain entitlements for a specific user is using an HTTP GET request. + +```bash +curl -X GET \ + -H "Authorization: Bearer ${EAT}" \ + "http://localhost:8080/auth/realms/hello-world-authz/authz/entitlement/${resource_server_id}" +``` + +[NOTE] +When asking for entitlements using this endpoint, you need to provide the EAT (as a bearer token) representing user's identity and his consent to access authorization data on his behalf. + +Where *${resource_server_id}* is the *client_id* registered with the client application acting as a resource server. + +As a result, you'll get a response from the server as follows: + +```json +{ + "rpt": ${RPT} +} +``` + +When using this method to obtain entitlements, the server is going to respond the requesting client with *all* entitlements for an user, based on the evaluation of the permissions and +authorization policies associated with all resources managed by the resource server. + +=== Obtaining Entitlements for a Specific Set of Resources + +The entitlements endpoint also allows you to obtain user's entitlements for a set of one or more resources. + +```bash +curl -X POST -H "Authorization: Bearer ${EAT}" -d '{ + "permissions" : [ + { + "resource_set_name" : "Hello World Resource" + } + ] +}' "http://localhost:8080/auth/realms/hello-world-authz/authz/entitlement/hello-world-authz-service" +``` + +As a result, you'll get a response from the server as follows: + +```json +{ + "rpt": ${RPT} +} +``` + +Unlink the GET version, the server is going to respond with a RPT holding the permissions granted during the evaluation of the permissions and authorization policies + associated with the resources being requested. + +When asking for entitlements you can also specify the scopes you want to have access: + +```bash +curl -X POST -H "Authorization: Bearer ${EAT}" -d '{ + "permissions" : [ + { + "resource_set_name" : "Hello World Resource", + "scopes" : [ + "urn:my-app.com:scopes:view" + ] + } + ] +}' "http://localhost:8080/auth/realms/hello-world-authz/authz/entitlement/hello-world-authz-service" +``` + +=== Requesting Party Token or RPT + +A RPT is basically a https://tools.ietf.org/html/rfc7519[JSON Web Token (JWT)] digitally signed using https://www.rfc-editor.org/rfc/rfc7515.txt[JSON Web Signature (JWS)]. +Its lifetime is the same as with the OAuth2 access token (EAT) that was used to obtain it. + +When you decode a RPT you may see something like that: + +```json +{ + "permissions": [ + { + "resource_set_id": "152251e6-f4cf-4464-8d91-f1b7960fa5fc", + "resource_set_name": "Hello World Resource" + "scopes" : [ + "urn:my-app.com:scopes:view" + ] + } + ], + "accessToken": ${EAT}, + "jti": "d6109a09-78fd-4998-bf89-95730dfd0892-1464906679405", + "exp": 1464906971, + "nbf": 0, + "iat": 1464906671, + "sub": "f1888f4d-5172-4359-be0c-af338505d86c", + "typ": "kc_ett", + "azp": "hello-world-authz-service" +} +``` + +The *permissions* claim consists of all the permissions granted by the server. There is also a *accessToken* property holding the AAT that was used to issue the RPT. \ No newline at end of file diff --git a/topics/service/entitlement-api.adoc b/topics/service/entitlement/entitlement-api.adoc similarity index 100% rename from topics/service/entitlement-api.adoc rename to topics/service/entitlement/entitlement-api.adoc diff --git a/topics/service/whatis-obtain-eat.adoc b/topics/service/entitlement/whatis-obtain-eat.adoc similarity index 100% rename from topics/service/whatis-obtain-eat.adoc rename to topics/service/entitlement/whatis-obtain-eat.adoc diff --git a/topics/service/permission-api-papi.adoc b/topics/service/protection/permission-api-papi.adoc similarity index 100% rename from topics/service/permission-api-papi.adoc rename to topics/service/protection/permission-api-papi.adoc diff --git a/topics/service/protection-api.adoc b/topics/service/protection/protection-api.adoc similarity index 100% rename from topics/service/protection-api.adoc rename to topics/service/protection/protection-api.adoc diff --git a/topics/service/resources-api-papi.adoc b/topics/service/protection/resources-api-papi.adoc similarity index 100% rename from topics/service/resources-api-papi.adoc rename to topics/service/protection/resources-api-papi.adoc diff --git a/topics/service/protection/token-introspection.adoc b/topics/service/protection/token-introspection.adoc new file mode 100755 index 0000000000..8b49566b77 --- /dev/null +++ b/topics/service/protection/token-introspection.adoc @@ -0,0 +1,80 @@ +== Introspecting a Requesting Party Token + +Sometimes you may want to introspect RPTs in order to check its validity or even obtain the permissions within the token +to enforce authorization decisions at the resource server side. + +There are two main use cases where token introspection may help you: + +* When clients applications need to check the token validity in order to obtain a new one with the same or even additional permissions +* When enforcing authorization decisions at the resource server side, specially when none of the built-in link:../enforcer/overview.html[Policy Enforcers] fits to your application + +=== Obtaining information about a RPT + +The token introspection is basically a https://tools.ietf.org/html/rfc7662[OAuth2 Token Introspection] compliant endpoint from where you can obtain information about a RPT. + +```bash +http://${host}:${port}/auth/realms/${realm_name}/protocol/openid-connect/token/introspect +``` + +To introspect a RPT using this endpoint, you can send a request to the server as follows: + +```bash +curl -X POST \ + -H "Authorization: Basic aGVsbG8td29ybGQtYXV0aHotc2VydmljZTpzZWNyZXQ=" \ + -H "Content-Type: application/x-www-form-urlencoded" \ + -d 'token_type_hint=requesting_party_token&token=${RPT}' \ + "http://localhost:8080/auth/realms/hello-world-authz/protocol/openid-connect/token/introspect" +``` + +[NOTE] +The request above is using HTTP BASIC and passing client's credentials (client id and secret) to authenticate the client trying to introspect the token, but you can use any other client +authentication method supported by {{book.project.name}}. + +The introspection endpoint expects two parameters: + +* *token_type_hint* ++ +Use *requesting_party_token* as the value for this parameter. It indicates that you want to introspect a RPT ++ +* *token* ++ +Use the token string, just like it was returned by the server during the authorization process, as the value for this parameter + +As a result, the server should respond as follows: + +```json +{ + "permissions": [ + { + "resource_set_id": "90ccc6fc-b296-4cd1-881e-089e1ee15957", + "resource_set_name": "Hello World Resource" + } + ], + "exp": 1465314139, + "nbf": 0, + "iat": 1465313839, + "aud": "hello-world-authz-service", + "active": true +} +``` + +In case the RPT is not active, you should get this response instead: + +```json +{ + "active": false +} +``` + +=== Do I Need to Invoke the Server Every Time I want to Introspect a RPT ? + +Not really. Both link:../../service/authorization/authorization-api.html[Authorization] and link:../../service/entitlement/entitlement-api.html[Entitlement] APIs use the + https://tools.ietf.org/html/rfc7519[JSON Web Token (JWT)] specification as the default format for RPTs. + +In case you want to validate these tokens without a remote call to the introspection endpoint you can decode the RPT and check for its validity locally. Once you decode the token, +you can also use the permissions within the token to enforce authorization decisions. + +This is pretty much what the link:../enforcer/overview.html[Policy enforcers] do, just make sure to: + +* Validate RPT's signature (based on realm's public key) +* Check for token validity based on its _exp_, _iat_ and _aud_ claims \ No newline at end of file diff --git a/topics/service/whatis-obtain-pat.adoc b/topics/service/protection/whatis-obtain-pat.adoc similarity index 100% rename from topics/service/whatis-obtain-pat.adoc rename to topics/service/protection/whatis-obtain-pat.adoc