General cleanup and edits of the documentation

This commit is contained in:
Jen Malloy 2016-11-15 16:34:20 -05:00
parent 766a67e538
commit 08a5c03778
52 changed files with 473 additions and 520 deletions

View file

@ -1,7 +1,7 @@
== Obtaining the Authorization Context
When policy enforcement is enabled, the permissions obtained from the server are available through `org.keycloak.AuthorizationContext`.
This class provides several methods from where you can use to obtain permissions and check whether a permission was granted for a particular resource or scope.
This class provides several methods you can use to obtain permissions and ascertain whether a permission was granted for a particular resource or scope.
Obtaining the Authorization Context in a Servlet Container
```java
@ -14,11 +14,11 @@ Obtaining the Authorization Context in a Servlet Container
```
[NOTE]
Check the adapter configuration for more details about how you can obtain a `KeycloakSecurityContext`. The example above should be enough
For more details about how you can obtain a `KeycloakSecurityContext` consult the adapter configuration. The example above should be sufficient
to obtain the context when running an application using any of the servlet containers supported by {{book.project.name}}.
The authorization context helps give you even more control over the decisions taken and returned by the server. For instance, you can use it
to build a dynamic menu where the items are hidden/shown depending on the permissions associated with a resource or scope.
The authorization context helps give you more control over the decisions made and returned by the server. For example, you can use it
to build a dynamic menu where items are hidden or shown depending on the permissions associated with a resource or scope.
```java
if (authzContext.hasResourcePermission("Project Resource")) {
@ -34,10 +34,9 @@ if (authzContext.hasScopePermission("urn:project.com:project:create")) {
}
```
The `AuthorizationContext` represents one of the main capabilities of {{book.project.name}} {{book.project.module}}. From the examples above, you may notice that the protected resource is not
directly associated with the policies that govern them.
The `AuthorizationContext` represents one of the main capabilities of {{book.project.name}} {{book.project.module}}. From the examples above, you can see that the protected resource is not directly associated with the policies that govern them.
Consider some similar code using RBAC:
Consider some similar code using role-based access control (RBAC):
```java
if (User.hasRole('user')) {
@ -53,9 +52,8 @@ if (User.hasRole('project-manager')) {
}
```
Although both examples address the same requirements, they do it in different ways. In RBAC, roles only _implicitly_ define access for their resources. With {{book.project.name}} you gain the capability to create more manageable code that focuses directly on your resources whether you are using RBAC, ABAC, or any other BAC variant. Either you have the permission for a given resource or scope, or you don't.
Although both examples address the same requirements, they do so in different ways. In RBAC, roles only _implicitly_ define access for their resources. With {{book.project.name}} you gain the capability to create more manageable code that focuses directly on your resources whether you are using RBAC, attribute-based access control (ABAC), or any other BAC variant. Either you have the permission for a given resource or scope, or you don't.
Now, suppose your security requirements have changed and beside project managers, PMOs can also create new projects.
Now, suppose your security requirements have changed and in addition to project managers, PMOs can also create new projects.
Security requirements change, but with {{book.project.name}} you don't need to change your application code to address new requirements. Once your application is based on the resource and scope identifier,
you need only change the configuration of the permissions or policies associated with a particular resource in the authorization server. In this case, we would change the permissions and policies associated with the `Project Resource` and/or the scope `urn:project.com:project:create`.
Security requirements change, but with {{book.project.name}} there is no need to change your application code to address the new requirements. Once your application is based on the resource and scope identifier, you need only change the configuration of the permissions or policies associated with a particular resource in the authorization server. In this case, the permissions and policies associated with the `Project Resource` and/or the scope `urn:project.com:project:create` would be changed.

View file

@ -1,9 +1,9 @@
== JavaScript Integration
The {{book.project.name}} Server comes with a JavaScript library you can use to interact with a resource server protected by a policy enforcer.
This library is based on the https://keycloak.gitbooks.io/securing-client-applications-guide/content/topics/oidc/javascript-adapter.html[Keycloak JavaScript Adapter], which can be integrated to allow your client to obtain permissions from a {{book.project.name}} Server.
This library is based on the https://keycloak.gitbooks.io/securing-client-applications-guide/content/topics/oidc/javascript-adapter.html[Keycloak JavaScript adapter], which can be integrated to allow your client to obtain permissions from a {{book.project.name}} Server.
You can obtain this library from a running {{book.project.name}} Server instance by including the following `script` tag in your web page:
You can obtain this library from a running a {{book.project.name}} Server instance by including the following `script` tag in your web page:
```html
<script src="http://${KEYCLOAK_HOST}/auth/js/keycloak-authz.js"></script>
@ -16,30 +16,28 @@ var authorization = new KeycloakAuthorization(keycloak);
```
The *keycloak-authz.js* library provides two main features:
* Handle responses from a resource server protected by a link:overview.html[{{book.project.name}} Policy Enforcer] and obtain a requesting party token (RPT) with the necessary permissions to gain access to
the protected resources on the resource server.
* Handle responses from a resource server protected by a link:overview.html[{{book.project.name}} policy enforcer] and obtain a requesting party token (RPT) with the necessary permissions to gain access to the protected resources on the resource server.
** In this case, the library can handle whatever authorization protocol the resource server is using: link:../service/authorization/authorization-api.html[UMA] or link:../service/entitlement/entitlement-api.html[Entitlements].
* Obtain permissions from a {{book.project.name}} Server using the link:../service/entitlement/entitlement-api.html[Entitlement API]
* Obtain permissions from a {{book.project.name}} Server using the link:../service/entitlement/entitlement-api.html[Entitlement API].
In both cases, the library allows you to easily interact with both resource server and {{book.project.name}} {{book.project.module}} to obtain tokens with
permissions your client can use as bearer tokens to access the protected resources on a resource server.
=== Handling Authorization Responses from a Resource Server
If a resource server is protected by a policy enforcer, it will respond to client requests based on the permissions carried along with a link:keycloak-enforcement-bearer.html[bearer token].
If a resource server is protected by a policy enforcer, it responds to client requests based on the permissions carried along with a link:keycloak-enforcement-bearer.html[bearer token].
Typically, when you try to access a resource server with a bearer token that is lacking permissions to access a protected resource, the resource server
will respond with a *401* status code and a `WWW-Authenticate` header.
responds with a *401* status code and a `WWW-Authenticate` header.
The value of the `WWW-Authenticate` header depends on the authorization protocol in use by the resource server. Whatever protocol is in use, you can use a `KeycloakAuthorization` instance to
handle responses as follows:
The value of the `WWW-Authenticate` header depends on the authorization protocol in use by the resource server. Whatever protocol is in use, you can use a `KeycloakAuthorization` instance to handle responses as follows:
```javascript
var wwwAuthenticateHeader = ... // extract WWW-Authenticate Header from the response in case of a 401 status code
authorization.authorize(wwwAuthenticateHeader).then(function (rpt) {
// onGrant callback function.
// If authorization was successful you'll receive a RPT
// If authorization was successful you'll receive an RPT
// with the necessary permissions to access the resource server
}, function () {
// onDeny callback function.
@ -49,11 +47,11 @@ authorization.authorize(wwwAuthenticateHeader).then(function (rpt) {
});
```
The `authorize` function is completely asynchronous and supports a few callback functions in order to receive notifications from the server:
The `authorize` function is completely asynchronous and supports a few callback functions to receive notifications from the server:
* `onGrant` - the first argument of the function. If authorization was successful and the server returned an RPT with the requested permissions, the callback will receive the RPT
* `onDeny` - the second argument of the function. Only called if the server has denied the authorization request
* `onError` - the third argument of the function. Only called if the server responds unexpectedly
* `onGrant`: The first argument of the function. If authorization was successful and the server returned an RPT with the requested permissions, the callback receives the RPT.
* `onDeny`: The second argument of the function. Only called if the server has denied the authorization request.
* `onError`: The third argument of the function. Only called if the server responds unexpectedly.
Most applications should use the `onGrant` callback to retry a request after a 401 response. Subsequent requests should include the RPT as a bearer token for retries.
@ -64,21 +62,21 @@ The keycloak-authz.js library provides an `entitlement` function that you can us
```json
authorization.entitlement('my-resource-server-id').then(function (rpt) {
// onGrant callback function.
// If authorization was successful you'll receive a RPT
// If authorization was successful you'll receive an RPT
// with the necessary permissions to access the resource server
});
```
When using the `entitlement` function, you need to provide the _client_id_ of the resource server you want to access.
When using the `entitlement` function, you must provide the _client_id_ of the resource server you want to access.
The `entitlement` function is completely asynchronous and supports a few callback functions in order to receive notifications from the server:
The `entitlement` function is completely asynchronous and supports a few callback functions to receive notifications from the server:
* `onGrant` - the first argument of the function. If authorization was successful and the server returned an RPT with the requested permissions, the callback will receive the RPT
* `onDeny` - the second argument of the function. Only called if the server has denied the authorization request
* `onError` - the third argument of the function. Only called if the server responds unexpectedly
* `onGrant`: The first argument of the function. If authorization was successful and the server returned an RPT with the requested permissions, the callback receives the RPT.
* `onDeny`: The second argument of the function. Only called if the server has denied the authorization request.
* `onError`: The third argument of the function. Only called if the server responds unexpectedly.
=== Obtaining the RPT
If you have already obtained a RPT using any of the authorization functions provided by the library, you can always obtain the RPT as follows from the authorization object (assuming that it has been initialized by one of the techniques shown earlier):
If you have already obtained an RPT using any of the authorization functions provided by the library, you can always obtain the RPT as follows from the authorization object (assuming that it has been initialized by one of the techniques shown earlier):
```javascript
var rpt = authorization.rpt;

View file

@ -1,9 +1,9 @@
== Protecting a Stateless Service Using a Bearer Token
If the adapter is configured with the `bearer-only` configuration option, the policy enforcer will decide whether a request
is allowed to access a protected resource or not based on the permissions carried along with a bearer token.
If the adapter is configured with the `bearer-only` configuration option, the policy enforcer decides whether a request
to access a protected resource is allowed or denied based on the permissions of the bearer token.
. HTTP GET example passing a RPT as a bearer token
. HTTP GET example passing an RPT as a bearer token
```bash
GET /my-resource-server/my-protected-resource HTTP/1.1
Host: host.com
@ -11,7 +11,7 @@ Authorization: Bearer ${RPT}
...
```
In this example, you would have a *keycloak.json* file in your application similar to the following:
In this example, a *keycloak.json* file in your application is similar to the following:
.Example of WEB-INF/keycloak.json with the bearer-only configuration option
```json
@ -23,10 +23,10 @@ In this example, you would have a *keycloak.json* file in your application simil
=== Authorization Response
When a client tries to access a resource server with a bearer token that is lacking permissions to access a protected resource, the resource server
will respond with a *401* status code and a `WWW-Authenticate` header. The value of the `WWW-Authenticate` header depends on the authorization protocol
responds with a *401* status code and a `WWW-Authenticate` header. The value of the `WWW-Authenticate` header depends on the authorization protocol
in use by the resource server.
Here is an example of a response from a resource server which is using UMA as the authorization protocol:
Here is an example of a response from a resource server that is using UMA as the authorization protocol:
```bash
HTTP/1.1 401 Unauthorized
@ -40,7 +40,6 @@ HTTP/1.1 401 Unauthorized
WWW-Authenticate: KC_ETT realm="photoz-restful-api",as_uri="http://localhost:8080/auth/realms/photoz/authz/entitlement"
```
Once a client receives a response from the server, it should check the status code and `WWW-Authenticate` header in order to obtain
a RPT from a {{book.project.name}} Server.
Once a client receives a response from the server, it examines the status code and `WWW-Authenticate` header to obtain an RPT from the {{book.project.name}} Server.

View file

@ -1,17 +1,17 @@
== Keycloak Adapter Policy Enforcer
You can enforce authorization decisions to your applications if you are using {{book.project.name}} OIDC Adapters.
You can enforce authorization decisions for your applications if you are using {{book.project.name}} OIDC adapters.
When you enable policy enforcement to your {{book.project.name}} application, the corresponding adapter will intercept all requests to your application and enforce the authorization decisions obtained from the server.
When you enable policy enforcement for your {{book.project.name}} application, the corresponding adapter intercepts all requests to your application and enforces the authorization decisions obtained from the server.
Policy enforcement is strongly linked to your application's paths and the link:../resource/overview.html[Resources] you created for a resource server using the {{book.project.name}} Administration Console. By default,
when you create a resource server, {{book.project.name}} creates a link:../resource-server/default-config.html[Default Configuration] for your resource server so you can enable policy enforcement very quickly.
Policy enforcement is strongly linked to your application's paths and the link:../resource/overview.html[resources] you created for a resource server using the {{book.project.name}} Administration Console. By default,
when you create a resource server, {{book.project.name}} creates a link:../resource-server/default-config.html[default configuration] for your resource server so you can enable policy enforcement quickly.
The default configuration allows access for all resources in your application provided the authenticated user belongs to the same realm as the resource server being protected.
=== Policy Enforcement Configuration
To enable policy enforcement to your application, add the following property to your *keycloak.json* file:
To enable policy enforcement for your application, add the following property to your *keycloak.json* file:
.keycloak.json
```json
@ -66,22 +66,20 @@ Here is a description of each configuration option:
* *policy-enforcer*
+
Specify the configuration options that define how policies are actually enforced and optionally the paths you want to protect. If empty, the policy enforcer will query the server
for all resources associated with the resource server being protected. In this case, you need to make sure the resources are properly configured with a link:../resource/create.adoc#_uri[URI] property that matches the paths
you want to protect.
Specifies the configuration options that define how policies are actually enforced and optionally the paths you want to protect. If not specified, the policy enforcer queries the server
for all resources associated with the resource server being protected. In this case, you need to ensure the resources are properly configured with a link:../resource/create.adoc#_uri[URI] property that matches the paths you want to protect.
+
** *user-managed-access*
+
Tells the adapter to use the UMA protocol. If set, the adapter will ask the server for permission tickets and return them to clients according to the UMA specification. If not set,
the adapter will just rely on the requesting party token (RPT) sent to the server to actually enforce permissions.
Specifies that the adapter uses the UMA protocol. If specified, the adapter queries the server for permission tickets and return them to clients according to the UMA specification. If not specified, the adapter relies on the requesting party token (RPT) sent to the server to enforce permissions.
+
** *enforcement-mode*
+
Dictates how policies are enforced.
Specifies how policies are enforced.
+
*** *ENFORCING*
+
This is the default mode. Requests are denied by default even when there is no policy associated with a given resource.
(default mode) Requests are denied by default even when there is no policy associated with a given resource.
+
*** *PERMISSIVE*
+
@ -89,23 +87,23 @@ Requests are allowed even when there is no policy associated with a given resour
+
*** *DISABLED*
+
Completely disables the evaluation of policies and allow access to any resource.
Completely disables the evaluation of policies and allows access to any resource.
+
** *on-deny-redirect-to*
+
Defines a URL where a client request should be redirected when an "access denied" message is obtained from the server. By default, the adapter responds with a 403 HTTP status code.
Defines a URL where a client request is redirected when an "access denied" message is obtained from the server. By default, the adapter responds with a 403 HTTP status code.
+
** *paths*
+
Specify the paths to protect.
Specifies the paths to protect.
+
*** *name*
+
The name of a resource in the server that is to be associated with a given path. When used in conjunction with a *path*, the policy enforcer will ignore the resource's *URI* property and will use the path you provided instead.
The name of a resource on the server that is to be associated with a given path. When used in conjunction with a *path*, the policy enforcer ignores the resource's *URI* property and uses the path you provided instead.
*** *path*
+
A URI relative to the application's context path. If this option is provided, the policy enforcer will query the server for a resource with a *URI* with the same value. This option is REQUIRED.
Right now, we support very basic logic for path matching. Examples of valid paths are:
(required) A URI relative to the application's context path. If this option is specified, the policy enforcer queries the server for a resource with a *URI* with the same value.
Currently a very basic logic for path matching is supported. Examples of valid paths are:
+
**** Wildcards: `/*`
**** Suffix: `/*.html`
@ -114,13 +112,12 @@ Right now, we support very basic logic for path matching. Examples of valid path
**** Exact match: /resource
+
*** *methods*
The HTTP methods (aka "verbs" e.g., GET, POST, PATCH) to protect and how they are associated with the scopes for a given resource in the server.
+
The HTTP methods (for example, GET, POST, PATCH) to protect and how they are associated with the scopes for a given resource in the server.
+[/'']
**** *method*
+
The name of the HTTP method.
+
**** *scopes*
+
An array of strings with the scopes associated with the method. When you associate scopes with a specific method, the client trying to access a protected resource (or path) must provide
an RPT that grants permission to all scopes specified in the list. For instance, if you define a method _POST_ with a scope _create_, the RPT must contain a permission granting access to the _create_ scope when performing a POST to the path.
An array of strings with the scopes associated with the method. When you associate scopes with a specific method, the client trying to access a protected resource (or path) must provide an RPT that grants permission to all scopes specified in the list. For example, if you define a method _POST_ with a scope _create_, the RPT must contain a permission granting access to the _create_ scope when performing a POST to the path.

View file

@ -1,7 +1,7 @@
== Policy Enforcers
Policy Enforcement Point (PEP) is a design pattern and as such you can implement it in different ways. {{book.project.name}} provides all the necessary means
to implement PEPs for different platforms, environments, and even different programming languages. {{book.project.name}} {{book.project.module}} presents a RESTful API,
to implement PEPs for different platforms, environments, and programming languages. {{book.project.name}} {{book.project.module}} presents a RESTful API,
and leverages OAuth2 authorization capabilities for fine-grained authorization using a centralized authorization server.
image:../../images/pep-pattern-diagram.png[alt="PEP Overview"]

View file

@ -3,11 +3,11 @@
The {{book.project.name}} Authorization can also help you to quickly get started with the authorization services and understand how to apply the same concepts to your
own applications.
If you are using the {{book.project.name}} Demo Distribution and you have it properly extracted in your filesystem:
If you are using the {{book.project.name}} Demo Distribution and you have it properly extracted in your file system:
* **keycloak-demo-{{book.project.version}}.[zip|tar.gz]**
You can check out the available examples from the following directory:
you can check out the available examples from the following directory:
```bash
cd ${KEYCLOAK_DEMO_SERVER_DIR}/examples/authz
@ -17,14 +17,14 @@ Or you can get them from https://github.com/keycloak/keycloak/tree/{{book.projec
Each example has a `README` file with instructions about how to build, deploy, and test the example.
Here is a brief description of each of them:
Here is a brief description of each example:
.Authorization Examples
|===
|Name |Description
| https://github.com/keycloak/keycloak/tree/{{book.project.version}}/examples/authz/servlet-authz[hello-world-authz-service]
| A single page application which is protected by a policy enforcer that decides whether a user can access that page or not based on the permissions obtained from a Keycloak Server.
| A single-page application that is protected by a policy enforcer that decides whether a user can access that page based on the permissions obtained from a Keycloak Server.
| https://github.com/keycloak/keycloak/tree/{{book.project.version}}/examples/authz/servlet-authz[photoz]
| A simple application based on HTML5+AngularJS+JAX-RS that demonstrates how to enable fine-grained permissions to RESTFul based services and HTML5 clients.

View file

@ -1,13 +1,15 @@
== Before You Start
This guide is based on the *{{book.project.name}} Demo Distribution*. Please download it before going further with any guide.
This guide is based on the *{{book.project.name}} Demo Distribution*. Download the demo distribution before proceeding.
[NOTE]
This guide assumes that you are already familiar with {{book.project.name}} and that you are able to install and boot a {{book.project.name}} Server. For more information, please follow the intrusctions https://keycloak.gitbooks.io/getting-started-tutorials/content/[here].
This guide assumes that you are already familiar with {{book.project.name}} and that you are able to install and boot a {{book.project.name}} Server. For more information, see https://keycloak.gitbooks.io/getting-started-tutorials/content/[the Getting Started tutorials].
Make sure you have a {{book.project.name}} instance up and running on http://localhost:8080/auth[http://localhost:8080/auth]. If everything is OK, you should be able to login to the
_Administration Console_ and get a page like that:
Ensure you have a {{book.project.name}} instance running; the default configuration is http://localhost:8080/auth[http://localhost:8080/auth]. After logging in to the
Administration Console, a page similar to this one is displayed:
image:../../images/gs-keycloak-console-page.png[alt="Keycloak Administration Console"]
.{{book.project.name}} Administration Console
image:../../images/getting-started/kc-start-page.png[alt="Keycloak Administration Console"]
Source code for all examples can be obtained from *${KEYCLOAK_DEMO_SERVER_DIR}/examples/authz/*.
The source code for the getting started tutorials can be obtained from the demo distributions. The authorization-related examples
are located at *${KEYCLOAK_DEMO_SERVER_DIR}/examples/authz*.

View file

@ -1,29 +1,32 @@
== Creating a Realm
== Creating a Realm and a User
The first step is to create a realm. The realm we are about to create is very simple and consists of:
The first step is to create a realm and a user in that realm. The realm consists of:
* A single user
* A single client application, which we're going to turn into a link:../../overview/terminology.html[Resource Server] and enable
the authorization services
* A single client application, which then becomes a link:../../overview/terminology.html[resource server] for which you need to enable authorization services.
Create a realm with a name *hello-world-authz*. Once created, you should see a page similar to the following:
To create a realm and a user complete the following steps:
1. Create a realm with a name *hello-world-authz*. Once created, a page similar to the following is displayed:
.Realm hello-world-authz
image:../../../images/getting-started/hello-world/create-realm.png[alt="Realm hello-world-authz"]
Next, create a single user in your newly-created realm. Click on the `Users` left menu item. This will bring you
to the user list page. On the right side of the empty user list, you should see an `Add User` button. Click that to start creating the new user with the username of *alice*.
2. Create a user for your newly created realm. Click *Users*. The user list page opens.
Fill in the fields as shown below and click `Save`.
3. On the right side of the empty user list, click *Add User*.
4. Complete the fields as shown in the screenshot below to create a new user with the username of *alice* and then click *Save*.
.Add User
image:../../../images/getting-started/hello-world/create-user.png[alt="Add User"]
Next, set a password for the *alice* user by clicking on the `Credentials` tab to display the `Credentials` page.
5. Set a password for the *alice* user by clicking the *Credentials* tab.
.Set User Password
image:../../../images/getting-started/hello-world/reset-user-pwd.png[alt="Set User Password"]
Fill in the `New Password` and `Password Confirmation` fields with a password and click the `Temporary` switch to turn it `OFF`. Lastly,
click on the `Reset Password` button to set the user's password.
6. Complete the *New Password* and *Password Confirmation* fields with a password and click the *Temporary* switch to *OFF*.
7. Click *Reset Password* to set the user's password.

View file

@ -1,25 +1,27 @@
== Enabling Authorization Services
You can enable authorization services in any existing client application configured to use the OpenID Connect Protocol. However, in this guide we are
going to create a new client from scratch.
You can enable authorization services in an existing client application configured to use the OpenID Connect Protocol. You can also create a new client.
Click on the `Clients` left menu item to start creating a new client application and fill in the fields as shown below:
To create a new client, complete the following steps:
1. Click *Clients* to start creating a new client application and fill in the fields as shown in the screenshot below:
.Create Client Application
image:../../../images/getting-started/hello-world/create-client.png[alt="Create Client Application"]
Click on the `Save` button to create the client. This should display the `Client Details` page.
2. Click *Save*. The Client Details page is displayed.
.Client Details
image:../../../images/getting-started/hello-world/enable-authz.png[alt="Client Details"]
In this page, click the `Authorization Enabled` switch and turn it `ON`, then click the `Save` button.
After saving, a new `Authorization` tab will show up in the tab set for the client. Click on this tab and you should see a page similar to the following:
3. On the Client Details page, click the *Authorization Enabled* switch to *ON*, and then click *Save*.
A new *Authorization* tab is displayed for the client.
4. Click the *Authorization* tab and an Authorization Settings page similar to the following is displayed:
.Authorization Settings
image:../../../images/getting-started/hello-world/authz-settings.png[alt="Authorization Settings"]
When you enable authorization services for a client application, {{book.project.name}} automatically creates several link:../../resource-server/default-config.html[Default Settings] for
your client authorization configuration.
When you enable authorization services for a client application, {{book.project.name}} automatically creates several link:../../resource-server/default-config.html[default settings] for your client authorization configuration.
For more details about authorization configuration, please see link:../../resource-server/enable-authorization.html[Enabling Authorization Services].
For more information about authorization configuration, see link:../../resource-server/enable-authorization.html[Enabling Authorization Services].

View file

@ -1,25 +1,26 @@
== Build, Deploy and Test
== Building, Deploying, and Testing Your Application
Now that the *hello-world-authz-service* resource server (client) is properly configured and authorization services are enabled, we can deploy it to the server and see the results.
Now that the *hello-world-authz-service* resource server (or client) is properly configured and authorization services are enabled, it can be deployed to the server.
=== Generating the Adapter Configuration
=== Obtaining the Adapter Configuration
First, let's obtain the adapter configuration from the {{book.project.name}} Administration Console. Click on the `Clients` left menu item. In the client listing,
click on the *hello-world-authz-service* client application. This will bring you the `Client Details` page.
You must first obtain the adapter configuration before building and deploying the application.
To obtain the adapter configuration from the {{book.project.name}} Administration Console, complete the following steps.
1. Click *Clients*. In the client listing, click the *hello-world-authz-service* client application. The Client Details page opens.
.Client Details
image:../../../images/getting-started/hello-world/enable-authz.png[alt="Client Details"]
Click on the `Installation Tab`. From the `Format Option` dropdown, select `Keycloak OIDC JSON`. This will display the adapter configuration in JSON format. Copy the contents to the clipboard and create a file or use the `Download` button.
2. Click the *Installation* tab. From the Format Option dropdown list, select *Keycloak OIDC JSON*. The adapter configuration is displayed in JSON format. Click *Download*.
.Adapter Configuration
image:../../../images/getting-started/hello-world/adapter-config.png[alt="Adapter Configuration"]
Now, go to the *${KEYCLOAK_DEMO_SERVER_DIR}/examples/authz/hello-world-authz-service/src/main/webapp/WEB-INF*. There you'll find a *keycloak.json* file. Replace its contents with the adapter configuration
you just obtained from the {{book.project.name}} Administration Console.
3. Navigate to the *${KEYCLOAK_DEMO_SERVER_DIR}/examples/authz/hello-world-authz-service/src/main/webapp/WEB-INF* directory and locate the *keycloak.json* file. Replace its contents with the adapter configuration you obtained from step 2 and save the file.
By default, the policy enforcer responds with a `403` status code when the user lacks permissions to access protected resources on the resource server. However, you can also provide a
redirection URL for unauthorized users. To customize this, change the *keycloak.json* file you just updated and replace the `policy-enforcer` configuration with the following:
4. (optional) By default, the policy enforcer responds with a `403` status code when the user lacks permission to access protected resources on the resource server. However, you can also specify a redirection URL for unauthorized users. To specify a redirection URL, edit the *keycloak.json* file you updated in step 3 and replace the `policy-enforcer` configuration with the following:
```json
"policy-enforcer": {
@ -27,37 +28,35 @@ redirection URL for unauthorized users. To customize this, change the *keycloak.
}
```
That last configuration tells the policy enforcer to redirect users to a `/hello-world-authz-service/error.jsp` page if they don't have the necessary permissions to access a protected resource, rather than an unhelpful `403 Unauthrorized` message.
This change specifies to the policy enforcer to redirect users to a `/hello-world-authz-service/error.jsp` page if a user does not have the necessary permissions to access a protected resource, rather than an unhelpful `403 Unauthorized` message.
=== Build and Deploy the Application
=== Building and Deploying the Application
Lastly, go to the *${KEYCLOAK_DEMO_SERVER_DIR}/examples/authz/hello-world-authz-service/* and execute the following command:
To build and deploy the application, navigate to the *${KEYCLOAK_DEMO_SERVER_DIR}/examples/authz/hello-world-authz-service/* directory and execute the following command:
```bash
mvn clean package wildfly:deploy
```
=== Test the Application
=== Testing the Application
If your application was successfully deployed you should be able to access it at http://localhost:8080/hello-world-authz-service[http://localhost:8080/hello-world-authz-service].
The first page you should see is the {{book.project.name}} Login Page.
If your application was successfully deployed you can access it at http://localhost:8080/hello-world-authz-service[http://localhost:8080/hello-world-authz-service]. The {{book.project.name}} Login page opens.
.Login Page
image:../../../images/getting-started/hello-world/login-page.png[alt="Login Page"]
Try to login as *alice* using the password you set up for that user. After authenticating, you should see a page as follows:
Log in as *alice* using the password you specified for that user. After authenticating, the following page is displayed:
.Hello World Authz Main Page
image:../../../images/getting-started/hello-world/main-page.png[alt="Hello World Authz Main Page"]
The link:../../resource-server/default-config.html[Default Settings] defined by {{book.project.name}} when you enable authorization services for a client application provide a simple
policy that always grant access to the resources protected by this policy.
The link:../../resource-server/default-config.html[default settings] defined by {{book.project.name}} when you enable authorization services for a client application provide a simple
policy that always grants access to the resources protected by this policy.
You can start playing around by changing the default permissions and policies and check how your application will behave, or even create new policies using the different
link:../../policy/overview.html[Policy Types] provided by {{book.project.name}}.
You can start by changing the default permissions and policies and test how your application responds, or even create new policies using the different
link:../../policy/overview.html[policy types] provided by {{book.project.name}}.
There are a plenty of things you can do now to test this application. For instance, you can change the default policy by clicking on the `Authorization` tab for the client, then `Policies` tab, then click on `Default Policy` in the list to allow you to change it as follows:
There are a plenty of things you can do now to test this application. For example, you can change the default policy by clicking the Authorization tab for the client, then `Policies` tab, then click on `Default Policy` in the list to allow you to change it as follows:
```js
// The default value is $evaluation.grant(),
@ -66,18 +65,18 @@ $evaluation.deny();
```
Now, logout from the demo application and log in again. You should no longer be able to access the application.
Now, log out of the demo application and log in again. You can no longer access the application.
image:../../../images/getting-started/hello-world/access-denied-page.png[alt="Access Denied Page"]
Let's fix that now, but instead of changing the `Default Policy` code we are just going to change the `Logic` to `Negative` using the dropdown control below the policy code text area.
That should re-enable access to the application as we are just negating the result of that policy, which is by default denying all requests for access. Again, before testing this change, be sure to logout and log in again.
Let's fix that now, but instead of changing the `Default Policy` code we are going to change the `Logic` to `Negative` using the dropdown list below the policy code text area.
That re-enables access to the application as we are negating the result of that policy, which is by default denying all requests for access. Again, before testing this change, be sure to log out and log in again.
=== Next Steps
There are a lot of other things you can do from now on, such as:
There are additional things you can do, such as:
* Create a scope, define a policy and permission for it, and check on the application side if the user is allowed to perform some action (or anything else represented by the scope you created)
* Create different types of policies such as link:../../policy/role-policy.adoc[Role-Based], link:../../policy/user-policy.adoc[User-Based], link:../../policy/time-policy.adoc[Time-Based], link:../../policy/aggregated-policy.adoc[Aggregated Policies], link:../../policy/drools-policy.adoc[Drools-Based], and associate these policies with the `Default Permission`
* Apply multiple policies to the `Default Permission` and check behavior. For instance, try to mix multiple policies and change the `Decision Strategy` accordingly
* Check out the link:../../enforcer/authorization-context.adoc[Obtaining the Authorization Context] topic for more details about how to check for permissions inside your application
* Create a scope, define a policy and permission for it, and test it on the application side. Can the user perform an action (or anything else represented by the scope you created)?
* Create different types of policies such as link:../../policy/role-policy.adoc[role-based], link:../../policy/user-policy.adoc[user-based], link:../../policy/time-policy.adoc[time-based], link:../../policy/aggregated-policy.adoc[aggregated policies], or link:../../policy/drools-policy.adoc[Drools-based], and associate these policies with the `Default Permission`.
* Apply multiple policies to the `Default Permission` and test the behavior. For example, combine multiple policies and change the `Decision Strategy` accordingly.
* For more information about how to view and test permissions inside your application see link:../../enforcer/authorization-context.adoc[Obtaining the Authorization Context].

View file

@ -1,12 +1,12 @@
== Hello World
The purpose of this guide is to get you up and running as quickly as possible so that you can play with and test drive various authorization features provided by {{book.project.name}}.
This quick tour relies heavily on the default out-of-the-box database and server configuration and does not cover complex deployment options.
For more in-depth discussion of any features or configuration options, consult the appropriate detail sections for those features and options in this documentation.
The purpose of this getting started guide is to get you up and running as quickly as possible so that you can experiment with and test various authorization features provided by {{book.project.name}}.
This quick tour relies heavily on the default database and server configurations and does not cover complex deployment options.
For more information on features or configuration options, see the appropriate sections in this documentation.
From this guide you'll understand some key concepts around {{book.project.name}} {{book.project.module}}:
This guide explains key concepts about {{book.project.name}} {{book.project.module}}:
* Enabling fine-grained authorization to a client application
* Enabling fine-grained authorization for a client application
* Configuring a client application to be a resource server, with protected resources
* Defining permissions and authorization policies to govern access to protected resources
* Enabling policy enforcement in your applications
* Enabling policy enforcement in your applications.

View file

@ -4,14 +4,14 @@ All tutorials are based on the *{{book.project.name}} Demo Distribution*.
* *keycloak-demo-{{book.project.version}}.[zip|tar.gz]*
To unpack this file run the _unzip_ or _gunzip_ and _tar_ utilities. During this guide we'll reference the directory where you have unpacked
the demo distribution as *${KEYCLOAK_DEMO_SERVER_DIR}*.
To unpack this file run the _unzip_ or _gunzip_ and _tar_ utilities. Throughout this guide the directory where you have unpacked
the demo distribution is referenced as *${KEYCLOAK_DEMO_SERVER_DIR}*.
[NOTE]
This guide assumes that you are already familiar with {{book.project.name}} and that you are able to install and boot a {{book.project.name}} Server. For more information, please follow the instructions https://keycloak.gitbooks.io/getting-started-tutorials/content/[here].
This guide assumes that you are already familiar with {{book.project.name}} and that you are able to install and boot a {{book.project.name}} Server. For more information, see https://keycloak.gitbooks.io/getting-started-tutorials/content/[the Getting Started tutorials].
Make sure you have a {{book.project.name}} instance up and running, the default configuration is http://localhost:8080/auth[http://localhost:8080/auth]. If everything is OK, you should be able to login to the
_Administration Console_ and see a page similar to this:
Ensure you have a {{book.project.name}} instance running; the default configuration is http://localhost:8080/auth[http://localhost:8080/auth]. After logging in to the
Administration Console, a page similar to this one is displayed:
.{{book.project.name}} Administration Console
image:../../images/getting-started/kc-start-page.png[alt="Keycloak Administration Console"]

View file

@ -2,17 +2,17 @@
image:../../images/authz-arch-overview.png[alt="Keycloak AuthZ Architecture Overview"]
From a design perspective, the {{book.project.module}} are based on a well-defined set of authorization patterns providing these capabilities:
From a design perspective, {{book.project.module}} is based on a well-defined set of authorization patterns providing these capabilities:
* **Policy Administration Point (PAP)**
+
Provides a set of UIs based on {{book.project.name}} Administration Console to manage resource servers, resources, scopes, permissions, and policies.
Part of this also accomplished remotely through the use of the link:../service/protection/protection-api.adoc[Protection API].
Provides a set of UIs based on the {{book.project.name}} Administration Console to manage resource servers, resources, scopes, permissions, and policies.
Part of this is also accomplished remotely through the use of the link:../service/protection/protection-api.adoc[Protection API].
+
* **Policy Decision Point (PDP)**
+
Provides a distributable policy decision point to where authorization requests are sent and policies are evaluated accordingly with the permissions being requested. Part of this also accomplished remotely through the use of the
Provides a distributable policy decision point to where authorization requests are sent and policies are evaluated accordingly with the permissions being requested. Part of this is also accomplished remotely through the use of the
link:../service/authorization/authorization-api.adoc[Authorization] and link:../service/entitlement/entitlement-api.adoc[Entitlement] APIs.
+
@ -40,46 +40,40 @@ Three main processes define the necessary steps to understand how to use KC to e
image:../../images/resource-mgmt-process.png[alt="Resource Management Overview"]
First, you need to tell to {{book.project.name}} what are you looking to protect, which usually represents a web application or a set of one or more services. See link:../overview/terminology.html[Terminology] for more information about
Resource Servers.
First, you need to specify {{book.project.name}} what are you looking to protect, which usually represents a web application or a set of one or more services. For more information on resource servers see link:../overview/terminology.html[Terminology].
Resource Servers are managed using the {{book.project.name}} Administration Console. There you can enable any registered client application as a resource server and start managing the resources and scopes you want to protect.
Resource servers are managed using the {{book.project.name}} Administration Console. There you can enable any registered client application as a resource server and start managing the resources and scopes you want to protect.
image:../../images/rs-r-scopes.png[alt="Resource Server Overview"]
A Resource can be a web page, a RESTFul resource, a file in your filesystem, an EJB, etc. They can represent a group of resources (just like a Class in Java) or they can represent a single and specific resource.
A resource can be a web page, a RESTFul resource, a file in your file system, an EJB, and so on. They can represent a group of resources (just like a Class in Java) or they can represent a single and specific resource.
For instance, you may have a _Bank Account_ resource that represents all banking accounts and use it to define the authorization policies that are common to all banking accounts. However,
you may want to define specific policies for _Alice Account_ (a resource instance that belongs to a customer), where only the owner is allowed to access some information or perform an operation.
For instance, you might have a _Bank Account_ resource that represents all banking accounts and use it to define the authorization policies that are common to all banking accounts. However, you might want to define specific policies for _Alice Account_ (a resource instance that belongs to a customer), where only the owner is allowed to access some information or perform an operation.
Resources can be managed using {{book.project.name}} Administration Console or the link:../service/protection/protection-api.adoc[Protection API]. In the latter case, resource servers are able to
manage their resources remotely.
Resources can be managed using the {{book.project.name}} Administration Console or the link:../service/protection/protection-api.adoc[Protection API]. In the latter case, resource servers are able to manage their resources remotely.
Scopes usually represent the actions that can be performed on a resource, but they are not limited to that. You can also use scopes to represent a single or multiple attributes within a resource.
Scopes usually represent the actions that can be performed on a resource, but they are not limited to that. You can also use scopes to represent one or more attributes within a resource.
==== Permission and Policy Management
Once you have defined your resource server and all the resources you want to protect, you can start working with the fun part: *Permission and Policy Management*.
Once you have defined your resource server and all the resources you want to protect, you must set up permissions and policies.
This process involves all the necessary steps to actually define the security and access requirements that govern your resources.
image:../../images/policy-mgmt-process.png[alt="Permission and Policy Management Overview"]
Policies define the conditions that must be satisfied to access or perform operations on something (resource or scope), but they are not tied with what they are protecting. They are generic and can be reused
to build permissions or even more complex policies.
Policies define the conditions that must be satisfied to access or perform operations on something (resource or scope), but they are not tied to what they are protecting. They are generic and can be reused to build permissions or even more complex policies.
For instance, we may want to allow access to a group of resources only for users granted with a role "User Premium". For that, we can just define a simple RBAC (Role-based Access Control).
For instance,to allow access to a group of resources only for users granted with a role "User Premium,"" you can use RBAC (Role-based Access Control).
{{book.project.name}} provides a few built-in policy types(and their respective policy providers) covering the most common access control mechanisms. You can even create policies based on rules written using JavaScript or JBoss Drools.
{{book.project.name}} provides a few built-in policy types (and their respective policy providers) covering the most common access control mechanisms. You can even create policies based on rules written using JavaScript or JBoss Drools.
Once you have your policies defined, you can start defining your permissions. Differently than policies, permissions are tied coupled with the resource they are protecting. Here you specify
what you want to protect (resource or scope) and the policies that must be satisfied in order to _GRANT_ or _DENY_ that permission to someone asking for it.
Once you have your policies defined, you can start defining your permissions. Permissions are coupled with the resource they are protecting. Here you specify
what you want to protect (resource or scope) and the policies that must be satisfied to grant or deny permission.
==== Policy Enforcement
*Policy Enforcement* involves the necessary steps to actually enforce authorization decisions to a resource server. This is achieved by enabling a *Policy Enforcement Point* or PEP at the
resource server that is capable of communication with the authorization server, ask for authorization data and control access to protected resources based on the decisions and permissions returned
by the server.
*Policy Enforcement* involves the necessary steps to actually enforce authorization decisions to a resource server. This is achieved by enabling a *Policy Enforcement Point* or PEP at the resource server that is capable of communicating with the authorization server, ask for authorization data and control access to protected resources based on the decisions and permissions returned by the server.
image:../../images/pep-pattern-diagram.png[alt="PEP Overview"]
@ -88,18 +82,18 @@ image:../../images/pep-pattern-diagram.png[alt="PEP Overview"]
=== Authorization Services
Authorization Services consist of the following RESTFul APIs:
Authorization services consist of the following RESTFul APIs:
* *Protection API*
* *Authorization API*
* *Entitlement API*
Each of these services provide a specific API covering the different steps involved in the authorization process.
Each of these services provides a specific API covering the different steps involved in the authorization process.
==== Protection API
The *Protection API* is a https://docs.kantarainitiative.org/uma/rec-uma-core.html[UMA-compliant] endpoint providing a small set of operations
for resource servers in order help them managing their resources and scopes. Only resource servers are allowed to access this API, which also requires a
for resource servers to help them manage their resources and scopes. Only resource servers are allowed to access this API, which also requires a
*uma_protection* scope.
The operations provided by the Protection API can be organized in two main groups:
@ -109,25 +103,22 @@ The operations provided by the Protection API can be organized in two main group
** Delete Resource
** Find by Id
** Find All
** Find with filters (eg.: search by name, type or URI)
** Find with filters (for example, search by name, type, or URI)
* *Permission Management*
** Issue Permission Tickets
[NOTE]
By default, Remote Resource Management is enabled. You can change that using the {{book.project.name}} Administration Console and only allow resource management through the console.
When using the UMA protocol, the issuance of Permission Tickets by the Protection API is an important part of the whole authorization process. As we'll see later, they represent the permissions
being requested by client and that are sent to the server in order to obtain a final token with all permissions granted during the evaluation of the permissions and policies
associated with the resources and scopes being requested.
When using the UMA protocol, the issuance of Permission Tickets by the Protection API is an important part of the whole authorization process. As described in a subsequent section, they represent the permissions being requested by the client and that are sent to the server to obtain a final token with all permissions granted during the evaluation of the permissions and policies associated with the resources and scopes being requested.
For more information, see link:../service/protection/protection-api.adoc[Protection API].
==== Authorization API
The *Authorization API* is also a https://docs.kantarainitiative.org/uma/rec-uma-core.html[UMA-compliant] endpoint providing a single operation that exchanges an Access Token and link:./terminology.adoc#_permission_ticket[Permission Ticket].
with a *Requesting Party Token* or *RPT*.
The Authorization API is also a https://docs.kantarainitiative.org/uma/rec-uma-core.html[UMA-compliant] endpoint providing a single operation that exchanges an Access Token and link:./terminology.adoc#_permission_ticket[Permission Ticket] with a Requesting Party Token (RPT).
The RPT holds all permissions granted to a client and can be used to call a resource server in order to get access to its protected resources.
The RPT holds all permissions granted to a client and can be used to call a resource server to get access to its protected resources.
When asking a RPT you can also provide a previously issued RPT. In this case, the resulting RPT will consist of the union of the permissions from the previously RPT and the new ones
within a permission ticket.
@ -138,14 +129,14 @@ For more information, see link:../service/authorization/authorization-api.adoc[A
=== Entitlement API
The *Entitlement API* provides a 1-legged protocol to issue RPTs. Unlike the _Authorization API_, the Entitlement API only expects an Access Token.
The Entitlement API provides a 1-legged protocol to issue RPTs. Unlike the Authorization API, the Entitlement API only expects an access token.
From this API you can obtain all the entitlements or permissions for an user (based on the resources managed by a given resource server) or just the entitlements for a set of
From this API you can obtain all the entitlements or permissions for a user (based on the resources managed by a given resource server) or just the entitlements for a set of
one or more resources.
image:../../images/entitlement-calls.png[alt="Entitlement API Overview"]
For more informationm, see link:../service/entitlement/entitlement-api.adoc[Entitlement API].
For more information see link:../service/entitlement/entitlement-api.adoc[Entitlement API].

View file

@ -1,47 +1,43 @@
== Overview
{% if book.product %}
{{book.project.module}} is a Technology Preview feature and is not fully supported. The feature is disabled by default.
{{book.project.module}} is a Technology Preview feature and is not fully supported. This feature is disabled by default.
To enable {{book.project.module}} add the file `standalone/configuration/profile.properties` with the contents `profile=preview`
or start the server with `-Dkeycloak.profile=preview` to enable preview features.
To enable {{book.project.module}} add the `standalone/configuration/profile.properties` file with the contents `profile=preview`
or start the server with `-Dkeycloak.profile=preview` to enable all technology preview features.
{% endif %}
{{book.project.name}} supports fine-grained authorization policies and is able to mix and match different access control
{{book.project.name}} supports fine-grained authorization policies and is able to combine different access control
mechanisms such as:
* **Attribute-based Access Control**
* **Role-based Access Control**
* **User-based Access Control**
* **Context-based Access Control**
* **Rule-based Access Control**
* **Attribute-based access control (ABAC)**
* **Role-based access control (RBAC)**
* **User-based access control (UBAC)**
* **Context-based access control (CBAC)**
* **Rule-based access control**
** Using Javascript
** Using JBoss Drools
* **Time-based Access Control**
* **Support for custom ACMs through a Policy Provider SPI**
* **Time-based access control**
* **Support for custom access control mechanisms (ACMs) through a Policy Provider Service Provider Interface (SPI)**
{{book.project.name}} is based on a set of administrative UIs and a RESTful API, and provides the necessary means to create permissions
for your protected resources and scopes, associate these permissions with authorization policies, and enforce authorization
decisions in your applications and services.
for your protected resources and scopes, associate those permissions with authorization policies, and enforce authorization decisions in your applications and services.
Resource servers (applications or services serving protected resources) usually rely on some kind of information to decide if access should be granted to a protected resource. For RESTful-based resource servers,
that information is usually obtained from a security token, usually sent as a bearer token on every request to the server. For web applications that rely on a session to
authenticate their users, that information is usually stored in a user's session and retrieved from there on every single request.
Resource servers (applications or services serving protected resources) usually rely on some kind of information to decide if access should be granted to a protected resource. For RESTful-based resource servers, that information is usually obtained from a security token, usually sent as a bearer token on every request to the server. For web applications that rely on a session to authenticate users, that information is usually stored in a user's session and retrieved from there for each request.
Frequently, resource servers only perform authorization decisions based on _Role-based Access Control_ or _RBAC_, where the roles granted to the user trying to access protected resources are
checked against the roles mapped to these same resources. While roles are very useful and used by applications, they also have a few limitations:
Frequently, resource servers only perform authorization decisions based on role-based access control (RBAC), where the roles granted to the user trying to access protected resources are checked against the roles mapped to these same resources. While roles are very useful and used by applications, they also have a few limitations:
* Resources and roles are tightly coupled and changes to roles (such as adding, removing or changing an access context) may impact several resources
* Changes to your security requirements may imply deep changes to application code to reflect these changes
* Depending on your application size, role management may become difficult and error-prone
* It is not the most flexible access control mechanism. Roles do not represent who you are and lack context information. If you have a role, you can do something.
* Resources and roles are tightly coupled and changes to roles (such as adding, removing, or changing an access context) can impact multiple resources
* Changes to your security requirements can imply deep changes to application code to reflect these changes
* Depending on your application size, role management might become difficult and error-prone
* It is not the most flexible access control mechanism. Roles do not represent who you are and lack contextual information. If you have been granted a role, you have at least some access.
Considering that today we need to consider heterogeneous environments where users are distributed across different regions, with different local policies,
using different devices, and with a high demand for information sharing, {{book.project.name}} Authorization Services can help you improve the authorization capabilities of your applications and services by providing:
* Resource protection using fine-grained authorization policies and different access control mechanisms
* Centralized Resource, Permission and Policy Management
* Centralized Resource, Permission, and Policy Management
* Centralized Policy Decision Point
* REST security based on a set of REST-based Authorization Services
* Authorization Workflows and User-Managed Access
* The infrastructure to help avoid code replication across projects (and redeploys) and quickly adapt to changes in your security requirements
* REST security based on a set of REST-based authorization services
* Authorization workflows and User-Managed Access
* The infrastructure to help avoid code replication across projects (and redeploys) and quickly adapt to changes in your security requirements.

View file

@ -1,82 +1,74 @@
== Terminology
Before going further, it is important to understand some terms and concepts introduced by {{book.project.name}} {{book.project.module}}.
Before going further, it is important to understand these terms and concepts introduced by {{book.project.name}} {{book.project.module}}.
=== Resource Server
Per OAuth2 terminology, a Resource Server is the server hosting the protected resources and capable of accepting and responding to protected resource requests.
Per OAuth2 terminology, a resource server is the server hosting the protected resources and capable of accepting and responding to protected resource requests.
Resource servers usually rely on some kind of information to decide whether access to a protected resource should be granted or not. For RESTful-based resource servers,
Resource servers usually rely on some kind of information to decide whether access to a protected resource should be granted. For RESTful-based resource servers,
that information is usually carried in a security token, typically sent as a bearer token along with every request to the server. Web applications that rely on a session to
authenticate their users usually store that information in the user's session and retrieve it from there on every request.
authenticate users usually store that information in the user's session and retrieve it from there for each request.
In Keycloak, any *confidential* client application may act as a resource server. This client's resources and their respective scopes are
protected and ruled by a set of authorization policies.
In Keycloak, any *confidential* client application can act as a resource server. This client's resources and their respective scopes are protected and governed by a set of authorization policies.
=== Resource
A resource is part of the assets of an application and the organization. It can be a set of one or more endpoints, a classic web resource such as an HTML page, and so on.
In authorization policy terminology, a resource is the _object_ being protected.
Every single resource has a unique identifier which may represent a single resource or a set of resources. For instance, you may want to manage a _Banking Account Resource_ that represents and defines a set of authorization policies for all banking accounts.
But you may also have a different resource named _Alice's Banking Account_, which represents a single resource owned by a single customer, which may have its own set of authorization policies.
Every resource has a unique identifier that can represent a single resource or a set of resources. For instance, you can manage a _Banking Account Resource_ that represents and defines a set of authorization policies for all banking accounts. But you can also have a different resource named _Alice's Banking Account_, which represents a single resource owned by a single customer, which can have its own set of authorization policies.
=== Scope
A resource's scope is a bounded extent of access that is possible to perform on a resource. In authorization policy
terminology, a scope is one of the potentially many _verbs_ that can logically apply to a resource.
A resource's scope is a bounded extent of access that is possible to perform on a resource. In authorization policy terminology, a scope is one of the potentially many _verbs_ that can logically apply to a resource.
It usually indicates what can be done with a given resource. Example of scopes are _view_,
_edit_, _delete_, etc. However, it may also be related with some information provided by a resource. In this case, you
may have a _Project_ resource and a _cost_ scope, where _cost_ scope may be used to define specific policies
and permissions for those trying to access project's cost.
It usually indicates what can be done with a given resource. Example of scopes are view, edit, delete, and so on. However, scope can also be related to specific information provided by a resource. In this case, you can have a project resource and a cost scope, where the cost scope is used to define specific policies and permissions for users to access a project's cost.
=== Permission
Consider this simple and very common permission:
A permission associates the object being protected with the policies that must be evaluated in order to decide whether or not access should be granted.
A permission associates the object being protected with the policies that must be evaluated to determine whether access is granted.
* *X* CAN DO *Y* ON RESOURCE *Z*
** where ...
*** *X* represents one or more Users, Roles, Groups or a combination of them. You can also use claims and context here ...
*** *Y* represents an action to be performed, e.g., "write", "view", etc
*** *Z* represents a protected resource, e.g., "/accounts".
*** *X* represents one or more users, roles, or groups, or a combination of them. You can also use claims and context here.
*** *Y* represents an action to be performed, for example, write, view, and so on.
*** *Z* represents a protected resource, for example, "/accounts".
{{book.project.name}} provides a rich platform for building a range of permission strategies ranging from simple to very complex, rule-based dynamic permissions. It provides great flexibility and helps to:
{{book.project.name}} provides a rich platform for building a range of permission strategies ranging from simple to very complex, rule-based dynamic permissions. It provides flexibility and helps to:
* Reduce code refactoring and permission management costs
* Support a more flexible security model, helping you to easily adapt to changes in your security requirements
* Make changes at runtime -- applications only care about the resources and scopes being protected and not how they are actually protected
* Make changes at runtime; applications are only concerned about the resources and scopes being protected and not how they are protected.
=== Policy
A policy defines the conditions that must be satisfied to grant access to an object. Different than permissions, you don't specify the object being protected
but the conditions that must be satisfied to get access to a given object (e.g., resource, scope, or both).
Policies are strongly related to the different _access control mechanisms_ that you can use to actually protect your resources.
With policies, you can implement strategies for ABAC, RBAC, Context-based Access Control or any combination of these.
A policy defines the conditions that must be satisfied to grant access to an object. Unlike permissions, you do not specify the object being protected
but rather the conditions that must be satisfied for access to a given object (for example, resource, scope, or both).
Policies are strongly related to the different access control mechanisms (ACMs) that you can use to protect your resources.
With policies, you can implement strategies for attribute-based access control (ABAC), role-based access control (RBAC), context-based access control, or any combination of these.
Keycloak leverages the concept of policies and how you define them by providing the concept of *Aggregated Policies*, where you can build a "policy of policies" and still control the behavior of the evaluation.
Instead of writing a single and huge policy with all conditions that must be satisfied to get access to a given resource, the policies implementation in {{book.project.name}} {{book.project.module}} follows the *divide-and-conquer* technique.
That is, you can create individual policies, reuse them on different permissions, and build more complex policies by combining individual policies.
Keycloak leverages the concept of policies and how you define them by providing the concept of aggregated policies, where you can build a "policy of policies" and still control the behavior of the evaluation.
Instead of writing one large policy with all the conditions that must be satisfied for access to a given resource, the policies implementation in {{book.project.name}} {{book.project.module}} follows the divide-and-conquer technique.
That is, you can create individual policies, then reuse them with different permissions and build more complex policies by combining individual policies.
=== Policy Provider
Policy providers are implementations of specific policy types. {{book.project.name}} provides some built-in policies, backed by their corresponding
policy providers, and you are free to create your own policy types to support your specific requirements.
Policy providers are implementations of specific policy types. {{book.project.name}} provides built-in policies, backed by their corresponding
policy providers, and you can create your own policy types to support your specific requirements.
{{book.project.name}} provides a *SPI* (Service Provider Interface) that you can use to plug in your own policy provider implementations.
{{book.project.name}} provides a SPI (Service Provider Interface) that you can use to plug in your own policy provider implementations.
[[_permission_ticket]]
=== Permission Ticket
A Permission Ticket is a special type of token defined by the https://docs.kantarainitiative.org/uma/rec-uma-core.html[OAuth2's User-Managed Access (UMA) Profile] specification that provides an opaque structure whose form is determined by the authorization server. This
structure represents the resources and/or scopes being requested by a client as well a the policies that must be applied to a request for authorization data (requesting party token or RPT).
A permission ticket is a special type of token defined by the https://docs.kantarainitiative.org/uma/rec-uma-core.html[OAuth2's User-Managed Access (UMA) Profile] specification that provides an opaque structure whose form is determined by the authorization server. This
structure represents the resources and/or scopes being requested by a client as well as the policies that must be applied to a request for authorization data (requesting party token [RPT]).
In UMA, permission tickets are crucial to support *person-to-person sharing* and also *person-to-organization sharing*. Using permission tickets for *authorization workflows* enables a range of scenarios from simple to complex,
where resource owners and resource servers have complete control over their resources based on fine-grained policies that govern the access to these resources.
In UMA, permission tickets are crucial to support person-to-person sharing and also person-to-organization sharing. Using permission tickets for authorization workflows enables a range of scenarios from simple to complex, where resource owners and resource servers have complete control over their resources based on fine-grained policies that govern the access to these resources.
During the UMA flow, permission tickets are issued by the authorization server to a resource server, which in turn returns it back to the client trying to access a protected resource. Once the client
receives the ticket, it can make a request for a requesting party token (RPT) (a final token holding authorization data) by sending the ticket back to the authorization server.
In the UMA workflow, permission tickets are issued by the authorization server to a resource server, which returns the permission ticket to the client trying to access a protected resource. Once the client receives the ticket, it can make a request for an RPT (a final token holding authorization data) by sending the ticket back to the authorization server.
For more details, see link:../service/authorization/authorization-api.html[Authorization API] and the https://docs.kantarainitiative.org/uma/rec-uma-core.html[UMA] specification.
For more information on permission tickets, see link:../service/authorization/authorization-api.html[Authorization API] and the https://docs.kantarainitiative.org/uma/rec-uma-core.html[UMA] specification.

View file

@ -1,8 +1,8 @@
== Creating Resource-based Permissions
A Resource-based permission defines a set of one or more resources to protect using a set of one or more authorization policies.
A resource-based permission defines a set of one or more resources to protect using a set of one or more authorization policies.
To create a new Resource-based permission, select the option *Resource-based* in the dropdown located in the right upper corner of the permission listing.
To create a new resource-based permission, select *Resource-based* in the dropdown list in the upper right corner of the permission listing.
.Add Resource-Based Permission
image:../../images/permission/create-resource.png[alt="Add Resource-Based Permission"]
@ -11,21 +11,21 @@ image:../../images/permission/create-resource.png[alt="Add Resource-Based Permis
* *Name*
+
A human-readable and unique string describing the permission. We strongly suggest you to use names that are closely related with your business and security requirements, so you
can identify them more easily and also know what they actually mean.
A human-readable and unique string describing the permission. A best practice is to use names that are closely related to your business and security requirements, so you
can identify them more easily.
+
* *Description*
+
A string with more details about this permission.
A string containing details about this permission.
[[_apply_resource_type]]
* *Apply To Resource Type*
+
Specifies if this permission would be applied to all resources with a given type. When you select this field, you'll be prompted to enter the resource type to protect.
Specifies if the permission is applied to all resources with a given type. When selecting this field, you are prompted to enter the resource type to protect.
+
** Resource Type
+
Defines the resource type to protect. When defined, this permission is going to be evaluated for all resources matching the type.
Defines the resource type to protect. When defined, this permission is evaluated for all resources matching that type.
+
* *Resources*
+

View file

@ -1,10 +1,8 @@
== Creating Scope-based Permissions
A Scope-based permission defines a set of one or more scopes to protect using a set of one or more authorization policies. Unlike the resource-based permissions, this permission type
allows you to create permissions not only for a resource, but also for the scopes associated with it, providing more granularity when defining the permissions that govern your resources and the
actions that can be performed on them.
A scope-based permission defines a set of one or more scopes to protect using a set of one or more authorization policies. Unlike resource-based permissions, you can use this permission type to create permissions not only for a resource, but also for the scopes associated with it, providing more granularity when defining the permissions that govern your resources and the actions that can be performed on them.
To create a new Scope-based permission, select the option *Scope-based* in the dropdown located in the right upper corner of the permission listing.
To create a new scope-based permission, select *Scope-based* in the dropdown list in the upper right corner of the permission listing.
.Add Scope-Based Permission
image:../../images/permission/create-scope.png[alt="Add Scope-Based Permission"]
@ -13,16 +11,16 @@ image:../../images/permission/create-scope.png[alt="Add Scope-Based Permission"]
* *Name*
+
A human-readable and unique string describing the permission. We strongly suggest you to use names that are closely related with your business and security requirements, so you
can identify them more easily and also know what they actually mean.
A human-readable and unique string describing the permission. A best practice is to use names that are closely related to your business and security requirements, so you
can identify them more easily.
+
* *Description*
+
A string with more details about this permission.
A string containing details about this permission.
+
* *Resource*
+
Restrict the scopes to those associated with the selected resource. If not selected all scopes would be available.
Restricts the scopes to those associated with the selected resource. If none is selected, all scopes are available.
+
* *Scopes*
+

View file

@ -1,15 +1,15 @@
== Policy Decision Strategies
When associating policies to a permission, you may also define a decision strategy to specify how to evaluate the outcome of the associated policies to build a final decision.
When associating policies with a permission, you can also define a decision strategy to specify how to evaluate the outcome of the associated policies to determine access.
* *Unanimous*
+
This is the default strategy if none is provided. In this case, _all_ policies must evaluate to a positive decision in order for the final decision to be also positive.
The default strategy if none is provided. In this case, _all_ policies must evaluate to a positive decision for the final decision to be also positive.
+
* *Affirmative*
+
In this case, _at least one_ policy must evaluate to a positive decision in order for the final decision to be also positive.
In this case, _at least one_ policy must evaluate to a positive decision for the final decision to be also positive.
+
* *Consensus*
+
In this case, the number of positive decisions must be greater than the number of negative decisions. If the number of positive and negative decisions is the same, the final decision will be negative.
In this case, the number of positive decisions must be greater than the number of negative decisions. If the number of positive and negative decisions is equal, the final decision will be negative.

View file

@ -1,16 +1,16 @@
== Managing Permissions
A permission associates the object being protected and the policies that must be evaluated in order to decide whether access should be granted or not.
A permission associates the object being protected and the policies that must be evaluated to decide whether access should be granted.
After creating the resources you want to protect and the policies you want to use to actually protect these resources,
you can start managing permissions. For that, click on the *Permissions* tab when editing a resource server.
After creating the resources you want to protect and the policies you want to use to protect these resources,
you can start managing permissions. To manage permissions, click the *Permissions* tab when editing a resource server.
.Permissions
image:../../images/permission/view.png[alt="Permissions"]
Permissions can be created to protect two main types of objects:
* *Resource*
* *Scope*
* *Resources*
* *Scopes*
To create a permission, select the permission type you want to create from the dropdown located in the right upper corner of the permission listing. The following sections describe these two types in more detail.
To create a permission, select the permission type you want to create from the dropdown list in the upper right corner of the permission listing. The following sections describe these two types of objects in more detail.

View file

@ -1,18 +1,15 @@
== Typed Resource Permission
Resource permissions can also be used to define policies that are to be applied to all resources with a given link:../resource/create.adoc#_type[Type]. This form of resource-based permission can be very handy when you have resources sharing very common access requirements and constraints.
Resource permissions can also be used to define policies that are to be applied to all resources with a given link:../resource/create.adoc#_type[type]. This form of resource-based permission can be useful when you have resources sharing common access requirements and constraints.
Frequently, resources within an application can be categorized (or typed) based on the data they encapsulate or the functionality they provide. For instance, a financial application might manage different
banking accounts where each one belongs to a specific customer. Although they are different banking accounts, they share some common security requirements and constraints which are globally
defined by the banking organization. With typed resource permissions, you may want to define some common policies to apply to all banking accounts:
Frequently, resources within an application can be categorized (or typed) based on the data they encapsulate or the functionality they provide. For example, a financial application can manage different banking accounts where each one belongs to a specific customer. Although they are different banking accounts, they share common security requirements and constraints that are globally defined by the banking organization. With typed resource permissions, you can define common policies to apply to all banking accounts, such as:
* Only the owner can manage his account
* Only allow access from the owner's country and/or region
* Enforce a specific authentication method
* And so forth ...
To create a typed resource permission, click on link:./create-resource.adoc#_apply_resource_type[Apply to Resource Type] when creating a new resource-based permission. With `Apply to Resource Type` set to `On`,
you can specify the type that you want to protect as well the policies that are to be applied to govern access to all resources with type you have provided.
To create a typed resource permission, click link:./create-resource.adoc#_apply_resource_type[Apply to Resource Type] when creating a new resource-based permission. With `Apply to Resource Type` set to `On`,
you can specify the type that you want to protect as well as the policies that are to be applied to govern access to all resources with type you have specified.
.Example of a Typed Resource Permission
image:../../images/typed-resource-perm-example.png[alt="Example of a Typed Resource Permission"]

View file

@ -1,16 +1,16 @@
== Policy Evaluation Tool
When designing your policies, you can simulate authorization requests to check how your policies are being evaluated.
When designing your policies, you can simulate authorization requests to test how your policies are being evaluated.
The *Policy Evaluation Tool* can be accessed by clicking the `Evaluate` tab when editing a resource server. There you may provide different inputs to simulate real authorization requests and check the effect of your policies.
You can access the Policy Evaluation Tool by clicking the `Evaluate` tab when editing a resource server. There you can specify different inputs to simulate real authorization requests and test the effect of your policies.
image:../../images/policy-evaluation-tool.png[alt="Policy Evaluation Tool"]
=== Providing Identity Information
The *Identity Information* filters can be used to specify the user asking for permissions.
The *Identity Information* filters can be used to specify the user requesting permissions.
You can also click *Entitlement* button to obtain all permissions for the user your selected.
You can also click *Entitlement* to obtain all permissions for the user your selected.
=== Providing Contextual Information
@ -18,8 +18,7 @@ The *Contextual Information* filters can be used to define additional attributes
=== Providing the Permissions
The *Permissions* filters can be used to build an authorization request. There you can ask for permissions for a set of one or more resources and scopes. In case you want
to simulate authorization requests based on all protected resources and scopes, click on the `Add` button without provide any `Resources` and `Scopes`.
The *Permissions* filters can be used to build an authorization request. You can request permissions for a set of one or more resources and scopes. If you want
to simulate authorization requests based on all protected resources and scopes, click *Add* without specifying any `Resources` or `Scopes`.
When you've filled in the necessary values, click the `Evaluate` button to yield a result.
When you've specified your desired values, click *Evaluate*.

View file

@ -1,28 +1,26 @@
== Aggregated Policies
As mentioned earlier, Keycloak allows you to build a policy of policies, a concept that we call *Aggregated Policies*. Policy aggregation allows you to reuse existing policies to build more complex ones and keep your permissions even more decoupled from the
policies that are actually evaluated during the processing of authorization requests.
As mentioned previously, Keycloak allows you to build a policy of policies, a concept referred to as policy aggregation. You can use policy aggregation to reuse existing policies to build more complex ones and keep your permissions even more decoupled from the policies that are evaluated during the processing of authorization requests.
To create a new Aggregated policy, select the option *Aggregated* in the dropdown located in the right upper corner of the permission listing.
To create a new aggregated policy, select *Aggregated* in the dropdown list located in the right upper corner of the permission listing.
.Add Aggregated Policy
.Add an Aggregated Policy
image:../../images/policy/create-aggregated.png[alt="Add Aggregated Policy"]
Let's suppose you have a resource called _Confidential Resource_ that can be accessed only by users from the _keycloak.org_ domain and from a certain range of IP addresses.
You may want to create a single policy with both conditions. However, you may want to reuse the domain part of this policy to apply to permissions that operates regardless of originating network.
You can create a single policy with both conditions. However, you want to reuse the domain part of this policy to apply to permissions that operates regardless of the originating network.
Keycloak allows you to create separate policies for both domain and network conditions and create a third policy based on
the combination of these two policies. With an *Aggregated Policy*, you can freely combine other policies and then apply the new aggregated policy to any permission you want.
You can create separate policies for both domain and network conditions and create a third policy based on the combination of these two policies. With an aggregated policy, you can freely combine other policies and then apply the new aggregated policy to any permission you want.
[NOTE]
When creating aggregated policies, be mindful that you are not introducing a circular reference/dependency between policies. If a circular dependency is detected, Keycloak will not let you create or update the policy.
When creating aggregated policies, be mindful that you are not introducing a circular reference or dependency between policies. If a circular dependency is detected, you cannot create or update the policy.
=== Configuration
* *Name*
+
A human-readable and unique string describing the policy. We strongly suggest that you use names that are closely related with your business and security requirements, so you
can identify them more easily and also know what they actually mean.
can identify them more easily and also know what they mean.
+
* *Description*
+
@ -42,11 +40,11 @@ The link:logic.html[Logic] of this policy to apply after the other conditions ha
=== Decision Strategy for Aggregated Policies
When creating aggregated policies, you can also define the decision strategy that will be used during to calculate the final decision based on the outcome from each policy.
When creating aggregated policies, you can also define the decision strategy that will be used to determine the final decision based on the outcome from each policy.
* *Unanimous*
+
This is the default strategy if none is provided. In this case, _all_ policies must evaluate to a positive decision in order for the final decision to be also positive.
The default strategy if none is provided. In this case, _all_ policies must evaluate to a positive decision for the final decision to be also positive.
+
* *Affirmative*
+

View file

@ -1,9 +1,10 @@
== Drools-Based Policy
This type of policy allows you to define conditions for your permissions using http://www.drools.org[Drools], which is a rule evaluation environment. It is one of the _Rule-Based_ policy types
With this type of policy you can define conditions for your permissions using http://www.drools.org[Drools], which is a rule evaluation environment. It is one of the _Rule-Based_ policy types
supported by {{book.project.name}}, and provides flexibility to write any policy based on the link:evaluation-api.adoc[Evaluation API].
To create a new Drools-based policy, select the option *Drools* in the dropdown located in the right upper corner of the permission listing.
To create a new Drools-based policy, in the dropdown list in the right upper corner of the permission listing,
select *Drools*.
.Add Drools Policy
image:../../images/policy/create-drools.png[alt="Add Drools Policy"]
@ -37,7 +38,7 @@ The version of the artifact.
+
* *Module*
+
The module used by this policy. You must provide a module in order to select a specific session from where rules will be loaded from.
The module used by this policy. You must provide a module to select a specific session from which rules will be loaded.
+
* *Session*
+
@ -53,7 +54,7 @@ The link:logic.html[Logic] of this policy to apply after the other conditions ha
=== Examples
Here is a simple example of a Drools-Based policy that uses Attribute-Based Access Control (ABAC) to define a condition that evaluates to a GRANT
Here is a simple example of a Drools-based policy that uses attribute-based access control (ABAC) to define a condition that evaluates to a GRANT
only if the authenticated user is the owner of the requested resource:
```javascript
@ -87,4 +88,4 @@ rule "Authorize Using Identity Information"
end
```
For more details about what you can access from the `org.keycloak.authorization.policy.evaluation.Evaluation` interface, see link:./evaluation-api.adoc[Evaluation API].
For more information about what you can access from the `org.keycloak.authorization.policy.evaluation.Evaluation` interface, see link:./evaluation-api.adoc[Evaluation API].

View file

@ -1,11 +1,11 @@
== Evaluation API
When writing rule-based policies using JavaScript or JBoss Drools, {{book.project.name}} provides an *Evaluation API* which provides useful information to help decide whether a permission should be granted or not.
When writing rule-based policies using JavaScript or JBoss Drools, {{book.project.name}} provides an Evaluation API that provides useful information to help determine whether a permission should be granted.
This API consists of a few interfaces that provides you access to information such as:
* The permission being requested
* The identity asking for a permission, from where you can obtain claims/attributes
* The identity that is requesting the permission, from which you can obtain claims/attributes
* Runtime environment and any other attribute associated with the execution context
The main interface is *org.keycloak.authorization.policy.evaluation.Evaluation*, which defines the following contract:
@ -39,13 +39,11 @@ public interface Evaluation {
}
```
[NOTE]
For more details about the Evaluation API refer to http://www.keycloak.org/docs/javadocs/index.html[JavaDocs].
For more information about the Evaluation API see the http://www.keycloak.org/docs/javadocs/index.html[JavaDocs].
When processing an authorization request, {{book.project.name}} creates an `Evaluation` instance before evaluating any policy. This instance is then passed to each policy in order to obtain
a decision, which would be a *GRANT* or a *DENY*.
When processing an authorization request, {{book.project.name}} creates an `Evaluation` instance before evaluating any policy. This instance is then passed to each policy to determine whether access is *GRANT* or *DENY*.
Policies take their decisions by invoking the `grant()` or `deny()` methods on an `Evaluation` instance. By default, the state of the `Evaluation` instance is denied, which means that your policies
need to explicitly invoke the `grant()` method if they want to tell the policy evaluation engine that the permission should be granted.
Policies determine this by invoking the `grant()` or `deny()` methods on an `Evaluation` instance. By default, the state of the `Evaluation` instance is denied, which means that your policies must explicitly invoke the `grant()` method to indicate to the policy evaluation engine that permission should be granted.
=== The Evaluation Context
@ -76,7 +74,7 @@ From this interface, policies can obtain:
* Information about the execution context and runtime environment
The `Identity` is built based on the OAuth2 Access Token that was sent along with the authorization request, and this construct has access to all claims
extracted from the original token. For instance, if you are using a _Protocol Mapper_ to include a custom claim in a OAuth2 Access Token you can also access this claim
extracted from the original token. For example, if you are using a _Protocol Mapper_ to include a custom claim in a OAuth2 Access Token you can also access this claim
from a policy and use it to build your conditions.
The `EvaluationContext` also gives you access to attributes related to both the execution and runtime environments. For now, there only a few built-in attributes.

View file

@ -1,9 +1,9 @@
== JavaScript-Based Policy
This type of policy allows you to define conditions for your permissions using JavaScript. It is one of the _Rule-Based_ policy types
You can use this type of policy to define conditions for your permissions using JavaScript. It is one of the rule-based policy types
supported by {{book.project.name}}, and provides flexibility to write any policy based on the link:evaluation-api.adoc[Evaluation API].
To create a new JavaScript-based policy, select the option *JavaScript* in the dropdown located in the right upper corner of the permission listing.
To create a new JavaScript-based policy, select *JavaScript* in the dropdown list in the upper right corner of the permission listing.
.Add JavaScript Policy
image:../../images/policy/create-js.png[alt="Add JavaScript Policy"]
@ -12,12 +12,12 @@ image:../../images/policy/create-js.png[alt="Add JavaScript Policy"]
* *Name*
+
A human-readable and unique string describing the policy. We strongly suggest that you use names that are closely related with your business and security requirements, so you
can identify them more easily and also know what they actually mean.
A human-readable and unique string describing the policy. A best practice is to use names that are closely related to your business and security requirements, so you
can identify them more easily.
+
* *Description*
+
A string with more details about this policy.
A string containing details about this policy.
+
* *Code*
+
@ -29,7 +29,7 @@ The link:logic.html[Logic] of this policy to apply after the other conditions ha
=== Examples
Here is a simple example of a JavaScript-Based policy that uses Attribute-Based Access Control (ABAC) to define a condition based on an attribute
Here is a simple example of a JavaScript-based policy that uses attribute-based access control (ABAC) to define a condition based on an attribute
obtained from the execution context:
```javascript
@ -41,7 +41,7 @@ if (contextAttributes.containsValue('kc.client.network.ip_address', '127.0.0.1')
}
```
You can also use RBAC:
You can also use role-based access control (RBAC):
```javascript
var identity = $evaluation.getIdentity();
@ -51,7 +51,7 @@ if (identity.hasRole('keycloak_user')) {
}
```
Or even a mix of different access control mechanisms:
Or a combination of several access control mechanisms:
```javascript
var context = $evaluation.getContext();
@ -64,5 +64,4 @@ if (identity.hasRole('admin') || email.endsWith('@keycloak.org')) {
}
```
When writing your own rules, keep in mind that the *$evaluation* object is just a object implementing *org.keycloak.authorization.policy.evaluation.Evaluation*. For more details about what you can access from this interface,
see link:evaluation-api.adoc[Evaluation API].
When writing your own rules, keep in mind that the *$evaluation* object is an object implementing *org.keycloak.authorization.policy.evaluation.Evaluation*. For more information about what you can access from this interface, see the link:evaluation-api.adoc[Evaluation API].

View file

@ -1,7 +1,7 @@
== Positive and Negative Logic
Policies may be configured with a *Positive* or *Negative* logic. In a nutshell, this option allows you to define whether the policy result should be kept as it is or be negated.
Policies can be configured with positive or negative logic. Briefly, you can use this option to define whether the policy result should be kept as it is or be negated.
For instance, suppose you want to create a policy where only users *not* granted with a specific role should be allowed to do something. In this case,
you may create a _Role-based Policy_ using that role and set its *Logic* field to *Negative*. If you keep *Positive*, which
For example, suppose you want to create a policy where only users *not* granted with a specific role should be given access. In this case,
you can create a role-based policy using that role and set its *Logic* field to *Negative*. If you keep *Positive*, which
is the default behavior, the policy result will be kept as it is.

View file

@ -1,12 +1,12 @@
== Managing Policies
As mentioned earlier, policies define the conditions that must be satisfied before granting access to an object.
As mentioned previously, policies define the conditions that must be satisfied before granting access to an object.
You can view all policies associated with a resource server by clicking on the *Policy* tab when editing a resource server.
You can view all policies associated with a resource server by clicking the *Policy* tab when editing a resource server.
.Policies
image:../../images/policy/view.png[alt="Policies"]
On this tab, you'll find the list of policies as well as options to create and edit a policy.
On this tab, you can view the list of previously created policies as well as create and edit a policy.
To create a new policy, select a policy type in the dropdown `Create policy` located in the right upper corner of the policy listing. Details about each policy type are described in this section.
To create a new policy, in the upper right corner of the policy list, select a policy type from the `Create policy` dropdown list. Details about each policy type are described in this section.

View file

@ -1,13 +1,12 @@
== Defining a Role as Required
When creating a role-based policy, you may mark a specific role as `Required`. When you do that, the policy will grant access
only if the user asking for access is granted with *all* the *required* roles. Both realm and client roles can be configured as such.
When creating a role-based policy, you can specify a specific role as `Required`. When you do that, the policy will grant access
only if the user requesting access has been granted *all* the *required* roles. Both realm and client roles can be configured as such.
.Example of Required Role
image:../../images/policy/create-role.png[alt="Example of Required Role"]
To mark a role as required, mark the `Required` checkbox on the role you want to configure as required.
To specify a role as required, select the `Required` checkbox for the role you want to configure as required.
Required roles can be very handy when your policy defines multiple roles but only a subset of them are mandatory. In this case, you can mix realm and client roles to enable an
even more fine-grained RBAC model for your application. For instance, you may have policies specific for a client and require a specific client role associated with that client. Or you can just
enforce that access is granted only in the presence of a specific realm role. Or even have both approaches within the same policy.
Required roles can be useful when your policy defines multiple roles but only a subset of them are mandatory. In this case, you can combine realm and client roles to enable an
even more fine-grained role-based access control (RBAC) model for your application. For example, you can have policies specific for a client and require a specific client role associated with that client. Or you can enforce that access is granted only in the presence of a specific realm role. You can also combine both approaches within the same policy.

View file

@ -1,17 +1,12 @@
== Role-Based Policy
This type of policy allows you to define conditions for your permissions where only a set of one or more roles is allowed
to access an object.
You can use this type of policy to define conditions for your permissions where a set of one or more roles is permitted to access an object.
By default, roles added to this policy are not marked as required and the policy will grant access if the user asking for access has any of these roles. However, {{book.project.name}} also allows you
to mark a specific role as link:role-policy-required-role.adoc[required] in case you want to enforce the presence of a role. You can even mix required and non-required roles, regardless of whether they are realm
or client roles.
By default, roles added to this policy are not specified as required and the policy will grant access if the user requesting access has been granted any of these roles. However, you can specify a specific role as link:role-policy-required-role.adoc[required] if you want to enforce a specific role. You can also combine required and non-required roles, regardless of whether they are realm or client roles.
Role policies can be very useful when you need a more restricted role-based access control (RBAC), where specific roles must be present in order to grant access to an object. For instance,
you may enforce that a user must consent to letting a client application (which is acting on his behalf) access his resources. Here you can benefit from {{book.project.name}} Client Scope Mapping to
enable consent pages or even enforce clients to explicitly provide a scope when obtaining access tokens from a {{book.project.name}} server.
Role policies can be useful when you need more restricted role-based access control (RBAC), where specific roles must be enforced to grant access to an object. For instance, you can enforce that a user must consent to allowing a client application (which is acting on the user's behalf) to access the user's resources. You can use {{book.project.name}} Client Scope Mapping to enable consent pages or even enforce clients to explicitly provide a scope when obtaining access tokens from a {{book.project.name}} server.
To create a new Role-based policy, select the option *Role-Based* in the dropdown located in the right upper corner of the permission listing.
To create a new role-based policy, select *Role-Based* in the dropdown list in the upper right corner of the permission listing.
.Add Role-Based Policy
image:../../images/policy/create-role.png[alt="Add Role-Based Policy"]
@ -20,20 +15,20 @@ image:../../images/policy/create-role.png[alt="Add Role-Based Policy"]
* *Name*
+
A human-readable and unique string describing the policy. We strongly suggest that you use names that are closely related with your business and security requirements, so you
can identify them more easily and also know what they actually mean.
A human-readable and unique string describing the policy. A best practice is to use names that are closely related to your business and security requirements, so you
can identify them more easily.
+
* *Description*
+
A string with more details about this policy.
A string containing details about this policy.
+
* *Realm Roles*
+
Specifies which *realm* role(s) are allowed by this policy.
Specifies which *realm* roles are permitted by this policy.
+
* *Client Roles*
+
Specifies which *client* role(s) are allowed by this policy. To enable this field you need to select a `Client` first.
Specifies which *client* roles are permitted by this policy. To enable this field must first select a `Client`.
+
* *Logic*
+

View file

@ -1,8 +1,8 @@
== Time-Based Policy
This type of policy allows you to define time conditions for your permissions.
You can use this type of policy to define time conditions for your permissions.
To create a new Time-based policy, select the option *Time* in the dropdown located in the right upper corner of the permission listing.
To create a new time-based policy, select *Time* in the dropdown list in the upper right corner of the permission listing.
.Add Time Policy
image:../../images/policy/create-time.png[alt="Add Time Policy"]
@ -11,44 +11,44 @@ image:../../images/policy/create-time.png[alt="Add Time Policy"]
* *Name*
+
A human-readable and unique string describing the policy. We strongly suggest that you use names that are closely related with your business and security requirements, so you
can identify them more easily and also know what they actually mean.
A human-readable and unique string describing the policy. A best practice is to use names that are closely related to your business and security requirements, so you
can identify them more easily.
+
* *Description*
+
A string with more details about this policy.
A string containing details about this policy.
+
* *Not Before*
+
Defines the time before which the policy MUST NOT be granted. Permission is granted only if the current date/time is after or equal to this value.
Defines the time before which access must *not* be granted. Permission is granted only if the current date/time is later than or equal to this value.
+
+
* *Not On or After*
+
Defines the time after which the policy MUST NOT be granted. Permission is granted only if the current date/time is before or equal to this value.
Defines the time after which access must *not* be granted. Permission is granted only if the current date/time is earlier than or equal to this value.
+
* *Day of Month*
+
Defines the day of month which the policy MUST be granted. You can also provide a range by filling the second field. In this case, permission is granted only if current day of month is between or equal to the two values you provided.
Defines the day of month that access must be granted. You can also specify a range of dates. In this case, permission is granted only if the current day of the month is between or equal to the two values specified.
+
* *Month*
+
Defines the month which the policy MUST be granted. You can also provide a range by filling the second field. In this case, permission is granted only if current month is between or equal to the two values you provided.
Defines the month that access must be granted. You can also specify a range of months. In this case, permission is granted only if the current month is between or equal to the two values specified.
+
* *Year*
+
Defines the year which the policy MUST be granted. You can also provide a range by filling the second field. In this case, permission is granted only if current year is between or equal to the two values you provided.
Defines the year that access must be granted. You can also specify a range of years. In this case, permission is granted only if the current year is between or equal to the two values specified.
+
* *Hour*
+
Defines the hour which the policy MUST be granted. You can also provide a range by filling the second field. In this case, permission is granted only if current hour is between or equal to the two values you provided.
Defines the hour that access must be granted. You can also specify a range of hours. In this case, permission is granted only if current hour is between or equal to the two values specified.
+
* *Minute*
+
Defines the minute which the policy MUST be granted. You can also provide a range by filling the second field. In this case, permission is granted only if current minute is between or equal to the two values you provided.
Defines the minute that access must be granted. You can also specify a range of minutes. In this case, permission is granted only if the current minute is between or equal to the two values specified.
+
* *Logic*
+
The link:logic.html[Logic] of this policy to apply after the other conditions have been evaluated.
Permissions are only granted if all conditions are satisfied. {{book.project.name}} will perform an _AND_ based on the outcome of each condition.
Access is only granted if all conditions are satisfied. {{book.project.name}} will perform an _AND_ based on the outcome of each condition.

View file

@ -1,27 +1,26 @@
== User-Based Policy
This type of policy allows you to define conditions for your permissions where only a set of one or more users is allowed
to access an object.
You can use this type of policy to define conditions for your permissions where a set of one or more users is permitted to access an object.
To create a new User-based policy, select the option *User-Based* in the dropdown located in the right upper corner of the permission listing.
To create a new user-based policy, select *User-Based* in the dropdown list in the upper right corner of the permission listing.
.Add User-Based Policy
.Add a User-Based Policy
image:../../images/policy/create-user.png[alt="Add User-Based Policy"]
=== Configuration
* *Name*
+
A human-readable and unique string describing the policy. We strongly suggest that you use names that are closely related with your business and security requirements, so you
can identify them more easily and also know what they actually mean.
A human-readable and unique string identifying the policy. A best practice is to use names that are closely related to your business and security requirements, so you
can identify them more easily.
+
* *Description*
+
A string with more details about this policy.
A string containing details about this policy.
+
* *Users*
+
Specifies which user(s) are allowed by this policy.
Specifies which users are given access by this policy.
+
* *Logic*
+

View file

@ -1,25 +1,27 @@
== Creating a Client Application
The first step to enable {{book.project.name}} {{book.project.module}} is create the client application that you want to turn into a resource server. For that, click on the `Clients` left menu item.
The first step to enable {{book.project.name}} {{book.project.module}} is to create the client application that you want to turn into a resource server.
To create a client application, complete the following steps:
1. Click *Clients*.
.Clients
image:../../images/resource-server/client-list.png[alt="Clients"]
In this page, click on the `Create` button on the right.
2. On this page, click *Create*.
.Create Client
image:../../images/resource-server/client-create.png[alt="Create Client"]
Fill in the fields as follows:
* Enter the `Client ID` of the client. For example, _my-resource-server_.
* Enter the `Root URL` for your application. For instance:
3. Type the `Client ID` of the client. For example, _my-resource-server_.
4. Type the `Root URL` for your application. For example:
+
```bash
http://${host}:${port}/my-resource-server
```
Finally, click `Save`. This will create the client and bring you to the client `Settings` tab. You should see a page similar to this:
5. Click *Save*. The client is created and the client Settings page opens. A page similar to the following is displayed:
.Client Settings
image:../../images/resource-server/client-enable-authz.png[alt="Client Settings"]

View file

@ -8,39 +8,38 @@ The default configuration consists of:
* A policy that always grants access to the resources protected by this policy.
* A permission that governs access to all resources based on the default policy.
The default protected resource is called *Default Resource* and you can see it if you click on the `Resources` tab.
The default protected resource is referred to as the *default resource* and you can view it if you navigate to the *Resources* tab.
.Default Resource
image:../../images/resource-server/default-resource.png[alt="Default Resource"]
This resource defines a `Type` namely `urn:my-resource-server:resources:default` and a `URI` `/*`. Here, the `URI` field defines a
wildcard pattern that tells {{book.project.name}} that this resource represents all the paths in your application. In other words,
when enabling link:../enforcer/overview.html[Policy Enforcement] for your application, all the permissions associated with the resource
will be checked before granting access.
This resource defines a `Type`, namely `urn:my-resource-server:resources:default` and a `URI` `/*`. Here, the `URI` field defines a
wildcard pattern that indicates to {{book.project.name}} that this resource represents all the paths in your application. In other words,
when enabling link:../enforcer/overview.html[policy enforcement] for your application, all the permissions associated with the resource
will be examined before granting access.
The `Type` mentioned earlier defines a value that can be used to create link:../permission/typed-resource-permission.adoc[Typed Resource Permissions] that must be applied
The `Type` mentioned previously defines a value that can be used to create link:../permission/typed-resource-permission.adoc[typed resource permissions] that must be applied
to the default resource or any other resource you create using the same type.
The default policy is called *Only From Realm Policy* and you can see it if you click on the `Policies` tab.
The default policy is referred to as the *only from realm policy* and you can view it if you navigate to the *Policies* tab.
.Default Policy
image:../../images/resource-server/default-policy.png[alt="Default Policy"]
This policy is a link:../policy/js-policy.html[JavaScript-Based Policy] defining a condition that always grants access to the resources protected by this policy. If you click on this policy you'll see that it defines a rule as follows:
This policy is a link:../policy/js-policy.html[JavaScript-based policy] defining a condition that always grants access to the resources protected by this policy. If you click this policy you can see that it defines a rule as follows:
```js
// by default, grants any permission associated with this policy
$evaluation.grant();
```
Lastly, the default permission is called *Default Permission* and you can see it if you click on the `Permissions` tab.
Lastly, the default permission is referred to as the *default permission* and you can view it if you navigate to the *Permissions* tab.
.Default Permission
image:../../images/resource-server/default-permission.png[alt="Default Permission"]
This permission is a link:../permission/overview.html[Resource-Based Permission], defining that a set of one or more policies should
be applied to all resources with a given type.
This permission is a link:../permission/overview.html[resource-based permission], defining a set of one or more policies that are applied to all resources with a given type.
== Post-Configuration Instructions
== Changing the Default Configuration
You are not forced to keep the default configuration if you don't want to. You can remove the default resource, policy, and permission definitions and introduce your own.
You can change the default configuration by removing the default resource, policy, or permission definitions and creating your own.

View file

@ -1,18 +1,16 @@
== Enabling Authorization Services
To turn your OIDC Client Application into a resource server and enable fine-grained authorization, click on the `Authorization Enabled` switch and turn it `ON`.
To turn your OIDC Client Application into a resource server and enable fine-grained authorization, click the *Authorization Enabled* switch to *ON* and click *Save*.
.Enabling Authorization Services
image:../../images/resource-server/client-enable-authz.png[alt="Enabling Authorization Services"]
Finally, click `Save`. When the save is complete,
a new `Authorization` tab will show up in the tab set for this client. Click on this tab and you should see a page similar to the following:
A new Authorization tab is displayed for this client. Click the *Authorization* tab and a page similar to the following is displayed:
.Resource Server Settings
image:../../images/resource-server/authz-settings.png[alt="Resource Server Settings"]
The `Authorization` tab provides a few additional tabs covering the different steps that you should follow to actually protect your application's resources. Each tab is covered separately by
a specific topic in this documentation. But here is a quick description about each one:
The Authorization tab contains additional sub-tabs covering the different steps that you must follow to actually protect your application's resources. Each tab is covered separately by a specific topic in this documentation. But here is a quick description about each one:
* *Settings*
+
@ -20,35 +18,35 @@ General settings for your resource server. More details about this page in this
* *Resource*
+
From this tab, you can manage your application's link:../resource/overview.html[Resources].
From this page, you can manage your application's link:../resource/overview.html[resources].
* *Scope*
+
From this tab, you can manage link:../resource/overview.html[Scopes].
From this page, you can manage link:../resource/overview.html[scopes].
* *Policies*
+
From this tab, you can manage link:../policy/overview.html[Authorization Policies] and define the conditions that must be met in order to grant a permission.
From this page, you can manage link:../policy/overview.html[authorization policies] and define the conditions that must be met to grant a permission.
* *Permissions*
+
From this tab, you can manage the link:../permission/overview.html[Permissions] for your protected resources and scopes by linking them with the policies you created.
From this page, you can manage the link:../permission/overview.html[permissions] for your protected resources and scopes by linking them with the policies you created.
* *Evaluate*
+
From this tab, you can link:../policy-evaluation-tool/overview.html[Simulate Authorization Requests] and check the result of the evaluation of the permissions and authorization policies you have defined.
From this page, you can link:../policy-evaluation-tool/overview.html[simulate authorization requests] and view the result of the evaluation of the permissions and authorization policies you have defined.
=== Resource Server Settings
Lets walk through each configuration item on this page.
On the Resource Server Settings page, you can configure the policy enforcement mode, allow remote resource management, and export the authorization configuration settings.
* *Policy Enforcement Mode*
+
Dictates how policies are enforced when processing authorization requests sent to the server.
Specifies how policies are enforced when processing authorization requests sent to the server.
+
** *Enforcing*
+
This is the default mode. Requests are denied by default even when there is no policy associated with a given resource.
(default mode) Requests are denied by default even when there is no policy associated with a given resource.
+
** *Permissive*
+
@ -56,13 +54,13 @@ Requests are allowed even when there is no policy associated with a given resour
+
** *Disabled*
+
Completely disables the evaluation of policies and allows access to any resource.
Disables the evaluation of all policies and allows access to all resources.
+
* *Allow Remote Resource Management*
+
Should resources be managed remotely by the resource server? If false, resources can be managed only from this admin console.
Specifies whether resources can be managed remotely by the resource server. If false, resources can be managed only from the administration console.
+
* *Export Settings*
+
In this section you can export the authorization configuration settings to a JSON file. Click the `Export` button to display the complete JSON configuration for you to download. The configuration contains everything defined for a resource server: protected resources, scopes, permissions and policies.
You can export the authorization configuration settings to a JSON file. Click *Export* to display the complete JSON configuration for download. The configuration file contains everything defined for a resource server: protected resources, scopes, permissions, and policies.

View file

@ -1,25 +1,27 @@
== Exporting and Importing Configuration
== Exporting and Importing Configuration Files
The configuration settings for a resource server can be exported and downloaded. The resulting configuration contains settings you've introduced for the resource server (client).
Import/Export is helpful when you would like to create an initial configuration for a resource server or to update an existing configuration. The configuration contains definitions for:
The configuration settings for a resource server (or client) can be exported and downloaded. You can also import an existing configuration file for a resource server. Importing and exporting a configuration file is helpful when you want to create an initial configuration for a resource server or to update an existing configuration. The configuration file contains definitions for:
* Protected Resources and Scopes
* Protected resources and scopes
* Policies
* Permissions
To export configuration, go to the `Resource Server Settings` page.
=== Exporting a Configuration File
To export a configuration file, complete the following steps:
1. Navigate to the *Resource Server Settings* page.
.Resource Server Settings
image:../../images/resource-server/authz-settings.png[alt="Resource Server Settings"]
In this page, you'll see a `Export Settings` section, which provides a single `Export` button. Click on that button and you'll see.
2. On this page, in the Export Settings section, click *Export*.
.Export Settings
image:../../images/resource-server/authz-export.png[alt="Export Settings"]
The configuration is exported in JSON format and displyed in a text area, which you can copy and paste. You may also click the `Download` button to download the configuration as a file.
The configuration file is exported in JSON format and displayed in a text area, from which you can copy and paste. You can also click *Download* to download the configuration file and save it.
=== Importing
=== Importing a Configuration File
To import a file with the configuration for a resource server, click on the `Select file` to open a file chooser dialog to select a file in your
filesystem containing the configuration you want to import.
To import a configuration file for a resource server, click *Select file* to select a file containing the configuration you want to import.

View file

@ -1,8 +1,7 @@
== Managing Resource Servers
According to the OAuth2 specification, a Resource Server is the server hosting the protected resources and capable of accepting and responding to protected resource requests.
According to the OAuth2 specification, a resource server is a server hosting the protected resources and capable of accepting and responding to protected resource requests.
In {{book.project.name}}, resource servers are provided with a rich platform for enabling fine-grained authorization to their protected resources, where authorization decisions can be made
based on different access control mechanisms.
In {{book.project.name}}, resource servers are provided with a rich platform for enabling fine-grained authorization for their protected resources, where authorization decisions can be made based on different access control mechanisms.
Any client application can be configured to support fine-grained permissions. When you do that, you are conceptually turning the client application into a resource server.
Any client application can be configured to support fine-grained permissions. In doing so, you are conceptually turning the client application into a resource server.

View file

@ -1,9 +1,9 @@
== Creating Resources
Creating a resource is straightforward and generic. Your main concern is the granularity of the resources you create. In other words, resources can
be created to represent a set of one or more resources and the way you define them is crucial to start managing permissions.
be created to represent a set of one or more resources and the way you define them is crucial to managing permissions.
To create a new resource, click on the `Create` button in the right upper corner of the resource listing.
To create a new resource, click *Create* in the right upper corner of the resource listing.
.Add Resource
image:../../images/resource/create.png[alt="Add Resource"]
@ -28,16 +28,16 @@ is usually the relative path used to serve these resources.
+
* *Scopes*
+
One more scopes to associate with the resource
One or more scopes to associate with the resource.
=== Typed Resources
The type field of a resource may be used to group different resources together, so they can be protected using a common set of permissions.
The type field of a resource can be used to group different resources together, so they can be protected using a common set of permissions.
=== Resource Owners
Resources also have an owner. By default, resources are owned by the resource server.
However, resources can also be associated with your users, so you can create permissions based on the resource owner. For example, only the resource owner is allowed to delete or update a given resource.
However, resources can also be associated with users, so you can create permissions based on the resource owner. For example, only the resource owner is allowed to delete or update a given resource.
=== Managing Resources Remotely
@ -48,4 +48,4 @@ specify the user identifier to configure a resource as belonging to a specific u
[NOTE]
{{book.project.name}} provides resource servers complete control over their resources. In the future, we should be able to
allow users to control their own resources as well, approve authorization requests and manage permissions, especially when using the UMA protocol.
allow users to control their own resources as well as approve authorization requests and manage permissions, especially when using the UMA protocol.

View file

@ -1,4 +1,4 @@
== Managing Resources and Scopes
Resource management is straightforward and generic. After creating a resource server, you can start creating the resources and scopes that you want to protect.
Resources and scopes can be managed by clicking on the *Resource* and *Scope* tabs, respectively. Details about `Resources` and `Scopes` are described in this section
Resources and scopes can be managed by navigating to the *Resource* and *Scope* tabs, respectively.

View file

@ -1,11 +1,11 @@
=== Viewing Resources
When you click on *Resource* tab, you'll see a page that lists the resources associated with a resource server.
On the *Resource* page, you see a list of the resources associated with a resource server.
.Resources
image:../../images/resource/view.png[alt="Resources"]
The resource list provides some very useful information about the protected resources, such as:
The resource list provides information about the protected resources, such as:
* Type
* URI
@ -13,7 +13,7 @@ The resource list provides some very useful information about the protected reso
* Associated scopes, if any
* Associated permissions
From this list, you can also directly create a permission by clicking on the `Create Permission` button for the resource you want to create the permission.
From this list, you can also directly create a permission by clicking *Create Permission* for the resource for which you want to create the permission.
[NOTE]
Before creating permissions to your resources, make sure you have already defined the policies you want to associate with the permission.
Before creating permissions for your resources, be sure you have already defined the policies that you want to associate with the permission.

View file

@ -1,17 +1,17 @@
== Requesting Authorization Data and Token
Client applications using the UMA protocol can use a specific endpoint to obtain a special security token called *Requesting Party Token* or *RPT*.
This token consists of all the permissions granted to 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 hand, client applications can gain access to protected resources at the resource server.
Client applications using the UMA protocol can use a specific endpoint to obtain a special security token called a requesting party token (RPT).
This token consists of all the permissions granted to a user as a result of the evaluation of the permissions and authorization policies associated with the resources being requested.
With an RPT, client applications can gain access to protected resources at the resource server.
```bash
http://${host}:${port}/auth/realms/${realm_name}/authz/authorize
```
When asking for a RPT, you need to provide two things:
When requesting an RPT, you need to provide two things:
* A link:../protection/permission-api-papi.adoc[Permission Ticket] with the resources you want to access
* The link:./whatis-obtain-aat.adoc[AAT] (as a bearer token) representing user's identity and his consent to access authorization data on his behalf.
* A link:../protection/permission-api-papi.adoc[permission ticket] with the resources you want to access
* The link:./whatis-obtain-aat.adoc[authorization API token (AAT)] (as a bearer token) representing a user's identity and his consent to access authorization data on his behalf.
```bash
curl -X POST
@ -20,18 +20,18 @@ curl -X POST
}' "http://localhost:8080/auth/realms/hello-world-authz/authz/authorize"
```
As a result, you will get the following response from the server:
As a result, the server response is:
```json
{"rpt":"${RPT}"}
```
=== Requesting Party Token or RPT
=== Requesting Party Token
A RPT is 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)].
A Requesting Party Token (RPT) is 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)].
The token is built based on the AAT sent by the client during the authorization process.
When you decode a RPT you will see something like that:
When you decode an RPT you will see something like:
```json
{

View file

@ -3,5 +3,5 @@
The Authorization API provides a UMA-compliant endpoint for obtaining authorization data from the server, where the authorization data represents the result of the evaluation
of all permissions and authorization policies associated with the resources being requested.
Unlike the Protection API, any client application can access the Authorization API endpoint, which requires a special OAuth2 access token called *Authorization API Token* or *AAT*.
In UMA, a AAT is just a token with a scope *uma_authorization*.
Unlike the Protection API, any client application can access the Authorization API endpoint, which requires a special OAuth2 access token called an authorization API token (AAT).
In UMA, an AAT is a token with the scope *uma_authorization*.

View file

@ -1,17 +1,17 @@
== What is a AAT and How to Obtain it ?
== Authorization API Token
An *Authorization API Token* or *AAT* is a special OAuth2 Access Token with the scope *uma_authorization*. When you create a user, {{book.project.name}} automatically
assigns a role _uma_authorization_ to the user. The _uma_authorization_ role is a _default realm role_ as you can see from this page.
An authorization API token (AAT) is a special OAuth2 access token with the scope *uma_authorization*. When you create a user, {{book.project.name}} automatically
assigns the role _uma_authorization_ to the user. The _uma_authorization_ role is a default realm role.
.Default Role uma_authorization
image:../../../images/service/rs-uma-authorization-role.png[alt="Default Role uma_authorization "]
An AAT enables a client application to query the server for user permissions.
Client applications can obtain an AAT from {{book.project.name}} just like any other OAuth2 Access Token. Usually, client applications obtain AATs after the user is successfully
authenticated in {{book.project.name}}. By default, the _authorization_code_ grant type is used to authenticate users, and the server will issue an OAuth2 Access Token to the client application acting on their behalf.
Client applications can obtain an AAT from {{book.project.name}} like any other OAuth2 access token. Usually, client applications obtain AATs after the user is successfully
authenticated in {{book.project.name}}. By default, the _authorization_code_ grant type is used to authenticate users, and the server will issue an OAuth2 access token to the client application acting on their behalf.
For demonstration purposes, the example below uses Resource Owner Password Credentials Grant Type to request an AAT.
The example below uses the Resource Owner Password Credentials Grant Type to request an AAT:
```bash
curl -X POST \
@ -21,7 +21,7 @@ curl -X POST \
"http://localhost:8080/auth/realms/${realm_name}/protocol/openid-connect/token"
```
As a result, you will get the following response from the server:
As a result, the server response is:
```json
{

View file

@ -1,6 +1,6 @@
== Authorization Client API
If you are using Java, you can access all {{book.project.name}} {{book.project.module}} using a Client API.
If you are using Java, you can access all {{book.project.name}} {{book.project.module}} using a client API.
=== Maven Dependency
@ -29,20 +29,20 @@ The client configuration is defined in a JSON file as follows:
}
```
* *realm*
* *realm* (required)
+
Name of the realm. This is REQUIRED.
The name of the realm.
* *auth-server-url*
* *auth-server-url* (required)
+
The base URL of the Keycloak server. All other Keycloak pages and REST service endpoints are derived from this. It is usually of the form https://host:port/auth. This is REQUIRED.
The base URL of the Keycloak server. All other Keycloak pages and REST service endpoints are derived from this. It is usually in the form https://host:port/auth.
* *resource*
* *resource* (required)
+
The client-id of the application. Each application has a client-id that is used to identify the application. This is REQUIRED.
The client-id of the application. Each application has a client-id that is used to identify the application.
* *credentials*
Specify the credentials of the application. This is an object notation where the key is the credential type and the value is the value of the credential type. Currently only secret/password is supported. This is REQUIRED.
* *credentials* (required)
Specifies the credentials of the application. This is an object notation where the key is the credential type and the value is the value of the credential type. Currently only secret/password is supported.
=== Obtaining User Entitlements
@ -52,12 +52,12 @@ Here is an example illustrating how to obtain user entitlements:
// create a new instance based on the configuration defined in keycloak-authz.json
AuthzClient authzClient = AuthzClient.create();
// obtain an Entitlement API Token in order to get access to the Entitlement API.
// this token is just an access token issued to a client on behalf of an user
// obtain an Entitlement API Token to get access to the Entitlement API.
// this token is an access token issued to a client on behalf of an user
// with a scope = kc_entitlement
String eat = getEntitlementAPIToken(authzClient);
// send the entitlement request to the server in order to
// send the entitlement request to the server to
// obtain an RPT with all permissions granted to the user
EntitlementResponse response = authzClient.entitlement(eat)
.getAll("hello-world-authz-service");
@ -74,8 +74,8 @@ Here is an example illustrating how to obtain user entitlements for a set of one
// create a new instance based on the configuration defined in keycloak-authz.json
AuthzClient authzClient = AuthzClient.create();
// obtain an Entitlement API Token in order to get access to the Entitlement API.
// this token is just an access token issued to a client on behalf of an user
// obtain an Entitlement API Token to get access to the Entitlement API.
// this token is an access token issued to a client on behalf of an user
// with a scope = kc_entitlement
String eat = getEntitlementAPIToken(authzClient);
@ -87,7 +87,7 @@ permission.setResourceSetName("Hello World Resource");
request.addPermission(permission);
// send the entitlement request to the server in order to obtain a RPT
// send the entitlement request to the server to obtain an RPT
// with all permissions granted to the user
EntitlementResponse response = authzClient.entitlement(eat)
.get("hello-world-authz-service", request);

View file

@ -1,8 +1,8 @@
== Requesting Entitlements
Client applications can use a specific endpoint to obtain a special security token called a *Requesting Party Token* or *RPT*.
This token consists of all the entitlements (or permissions) for a user as a result of the evaluation of the permissions and authorization policies associated with the resource(s) being requested.
With an RPT in hand, client applications can gain access to protected resources at the resource server.
Client applications can use a specific endpoint to obtain a special security token called a requesting party token (RPT).
This token consists of all the entitlements (or permissions) for a user as a result of the evaluation of the permissions and authorization policies associated with the resources being requested.
With an RPT, client applications can gain access to protected resources at the resource server.
```bash
http://${host}:${port}/auth/realms/${realm_name}/authz/entitlement
@ -19,11 +19,11 @@ curl -X GET \
```
[NOTE]
When asking for entitlements using this endpoint, you need to provide the access_token (as a bearer token) representing a user's identity and his consent to access authorization data on his behalf.
When requesting entitlements using this endpoint, you must provide the access_token (as a bearer token) representing a user's identity and his consent to access authorization data on his behalf.
In the curl example, *${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:
As a result, the server response is:
```json
{
@ -31,12 +31,12 @@ As a result, you'll get a response from the server as follows:
}
```
Using this method to obtain entitlements, the server will respond to the requesting client with *all* entitlements for a user, based on the evaluation of the permissions and
Using this method to obtain entitlements, the server responds to the requesting client with *all* entitlements for a user, based on the evaluation of the permissions and
authorization policies associated with the resources managed by the resource server.
=== Obtaining Entitlements for a Specific Set of Resources
The entitlements endpoint also allows you to obtain a user's entitlements for a set of one or more resources. For example, using curl:
You can also use the entitlements endpoint to obtain a user's entitlements for a set of one or more resources. For example, using curl:
```bash
curl -X POST -H "Authorization: Bearer ${access_token}" -d '{
@ -48,7 +48,7 @@ curl -X POST -H "Authorization: Bearer ${access_token}" -d '{
}' "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:
As a result, the server response is:
```json
{
@ -56,10 +56,10 @@ As a result, you'll get a response from the server as follows:
}
```
Unlike the GET version, the server is going to respond with an RPT holding the permissions granted during the evaluation of the permissions and authorization policies
Unlike the GET version, the server responds with an 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. Using curl:
When requesting entitlements, you can also specify the scopes you want to access. For example, using curl:
```bash
curl -X POST -H "Authorization: Bearer ${access_token}" -d '{
@ -74,12 +74,11 @@ curl -X POST -H "Authorization: Bearer ${access_token}" -d '{
}' "http://localhost:8080/auth/realms/hello-world-authz/authz/entitlement/hello-world-authz-service"
```
=== Requesting Party Token or RPT
=== Requesting Party Token
A RPT is 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)].
The token is built based on the access_token sent by the client during the authorization process.
A requesting party token (RPT) is 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)]. The token is built based on the access_token sent by the client during the authorization process.
When you decode a RPT, you will see a payload similar to the following:
When you decode an RPT, you see a payload similar to the following:
```json
{

View file

@ -1,9 +1,9 @@
== Entitlements API
== Entitlement API
The *Entitlement API* provides a 1-legged protocol for obtaining authorization data from the server, where the authorization data
The Entitlement API provides a 1-legged protocol for obtaining authorization data from the server, where the authorization data
represents the result of the evaluation of all permissions and authorization policies associated with the resources being requested.
Unlike the _Authorization API_, the Entitlement API is not UMA-compliant and doesn't require permission tickets.
Unlike the _Authorization API_, the Entitlement API is not UMA-compliant and does not require permission tickets.
The purpose of this API is provide a more lightweight API for obtaining authorization data, where the client in possession of a valid
OAuth2 Access Token is able to obtain the necessary authorization data on behalf of its users.
The purpose of this API is provide a more lightweight API for obtaining authorization data, where a client in possession of a valid
OAuth2 access token is able to obtain the necessary authorization data on behalf of its users.

View file

@ -1,11 +1,11 @@
== What is a EAT and How to Obtain it ?
== Entitlement API Tokens
An *Entitlement API Token* or *EAT* is a special OAuth2 Access Token with the scope *kc_entitlement*.
An entitlement API token (EAT) is a special OAuth2 access token with the scope *kc_entitlement*.
Client applications can obtain an EAT from {{book.project.name}} just like any other OAuth2 Access Token. Usually, client applications are going to obtain EATs after the user is successfully
authenticated in {{book.project.name}}. By default the _authorizaton_code_ grant type is used to authenticate users and issue OAuth2 Access Token to the client application acting on their behalf.
Client applications can obtain an EAT from {{book.project.name}} like any other OAuth2 access token. Usually, client applications obtain EATs after the user is successfully
authenticated in {{book.project.name}}. By default the _authorizaton_code_ grant type is used to authenticate a user and issue an OAuth2 access token to the client application acting on the user's behalf.
For demonstrations purposes, the example below uses Resource Owner Password Credentials Grant Type to ask for a EAT.
For demonstration purposes, the example below uses Resource Owner Password Credentials Grant Type to request an EAT:
```bash
curl -X POST \
@ -15,7 +15,7 @@ curl -X POST \
"http://localhost:8080/auth/realms/${realm_name}/protocol/openid-connect/token"
```
As a result, you will get the following response from the server:
As a result, the server response is:
```json
{
@ -32,5 +32,4 @@ As a result, you will get the following response from the server:
== About the kc_entitlement scope
The *kc_entitlement* scope can be created just like any other _realm role_. Or even as a _client role_. Once you created it, just grant this role to
the users of your realm.
The *kc_entitlement* scope can be created like any other _realm role_, or as a _client role_. Once created, grant this role to the users of your realm.

View file

@ -2,5 +2,5 @@
{{book.project.name}} {{book.project.module}} are based on OAuth2's User-Managed Access (UMA) Profile.
This section describes the different RESTful endpoints that you can interact with in order to enable fine-grained authorization
to your application and services.
This section describes the different RESTful endpoints that you can interact with to enable fine-grained authorization
for your applications and services.

View file

@ -1,21 +1,18 @@
== Managing Permission Requests
Resource servers using the UMA protocol can use a specific endpoint to manage permission requests. This endpoint provides a UMA-compliant flow for registering permissions requests and obtaining a *Permission Ticket*.
Resource servers using the UMA protocol can use a specific endpoint to manage permission requests. This endpoint provides a UMA-compliant flow for registering permission requests and obtaining a permission ticket.
```bash
http://${host}:${port}/auth/realms/${realm_name}/authz/protection/permission
```
A link:../../overview/terminology.adoc#_permission_ticket[Permission Ticket] is a special security token type representing a permission request. Per the UMA specification, a permission ticket is:
A link:../../overview/terminology.adoc#_permission_ticket[permission ticket] is a special security token type representing a permission request. Per the UMA specification, a permission ticket is:
`A correlation handle that is conveyed from an authorization server to a resource server, from a resource server to a client, and ultimately from a client back to an authorization server, to enable the authorization server to assess the correct policies to apply to a request for authorization data.`
[NOTE]
_Permission ticket support is limited_.
In the full UMA protocol, resource servers can register permission requests in the server to support authorization flows where a resource owner (the user that owns a resource being requested) can
approve access to his resources by third parties among other things. This represents one of the main features of the UMA specification -- where resource owners can control their own resources
and the policies that govern them. Right now, the UMA implementation support is very limited in this regard. For example, the system doesn't store permission tickets on the server and we are basically using UMA to provide API security and base our authorization offerings.
This situation should be temporary. In the future, we plan to fully support UMA and cover other use cases.
In the full UMA protocol, resource servers can register permission requests in the server to support authorization flows where a resource owner (the user that owns a resource being requested) can approve access to his resources by third parties, among other ways. This represents one of the main features of the UMA specification: resource owners can control their own resources and the policies that govern them. Currently {{book.project.name}} UMA implementation support is very limited in this regard. For example, the system does not store permission tickets on the server and we are essentially using UMA to provide API security and base our authorization offerings. In the future, full support of UMA and other use cases is planned.
In most cases, you won't need to deal with this endpoint directly. {{book.project.name}} provides a link:../enforcer/overview.html[Policy Enforcer] that enables UMA for your
In most cases, you won't need to deal with this endpoint directly. {{book.project.name}} provides a link:../enforcer/overview.html[policy enforcer] that enables UMA for your
resource server so it can obtain a permission ticket from the authorization server, return this ticket to client application, and enforce authorization decisions based on a final requesting party token (RPT).

View file

@ -4,11 +4,11 @@ The Protection API provides a UMA-compliant set of endpoints providing:
* *Resource Registration*
+
With this endpoint, resource servers can manage their resources remotely and enable link::../../../../enforcer/overview.adoc[Policy Enforcers] to query the server for the resources that need protection.
With this endpoint, resource servers can manage their resources remotely and enable link::../../../../enforcer/overview.adoc[policy enforcers] to query the server for the resources that need protection.
* *Permission Registration*
+
In the UMA protocol, resource servers access this endpoint which issues permission tickets.
In the UMA protocol, resource servers access this endpoint, which issues permission tickets.
An important requirement for this API is that _only_ resource servers are allowed to access its endpoints using a special OAuth2 access token called *Protection API Token* or *PAT*.
In UMA, a PAT is just a token with a scope *uma_protection*.
An important requirement for this API is that _only_ resource servers are allowed to access its endpoints using a special OAuth2 access token called a protection API token (PAT).
In UMA, a PAT is a token with the scope *uma_protection*.

View file

@ -15,4 +15,4 @@ This endpoint provides registration operations outlined as follows (entire path
* List resource set descriptions: GET /resource_set
* List resource set descriptions using a filter: GET /resource_set?filter=${filter}
For more details about the contract for each of these operations, please refer to https://docs.kantarainitiative.org/uma/rec-oauth-resource-reg-v1_0_1.html[UMA Resource Set Registration].
For more information about the contract for each of these operations, see https://docs.kantarainitiative.org/uma/rec-oauth-resource-reg-v1_0_1.html[UMA Resource Set Registration].

View file

@ -1,16 +1,15 @@
== 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.
Sometimes you might want to introspect a requesting party token (RPT) to check its validity or obtain the permissions within the token to enforce authorization decisions on the resource server side.
There are two main use cases where token introspection may help you:
There are two main use cases where token introspection can help you:
* When client 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, especially when none of the built-in link:../../enforcer/overview.html[Policy Enforcers] fits your application
* When client applications need to query the token validity to obtain a new one with the same or additional permissions
* When enforcing authorization decisions at the resource server side, especially when none of the built-in link:../../enforcer/overview.html[policy enforcers] fits your application
=== Obtaining Information about a RPT
The token introspection is essentially a https://tools.ietf.org/html/rfc7662[OAuth2 Token Introspection]-compliant endpoint from which you can obtain information about a RPT.
The token introspection is essentially a https://tools.ietf.org/html/rfc7662[OAuth2 token introspection]-compliant endpoint from which you can obtain information about a RPT.
```bash
http://${host}:${port}/auth/realms/${realm_name}/protocol/openid-connect/token/introspect
@ -27,20 +26,19 @@ curl -X POST \
```
[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 request above is using HTTP BASIC and passing the client's credentials (client ID and secret) to authenticate the client attempting 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.
Use *requesting_party_token* as the value for this parameter, which indicates that you want to introspect an RPT.
+
* *token*
+
Use the token string, just as it was returned by the server during the authorization process, as the value for this parameter.
Use the token string as 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:
As a result, the server response is:
```json
{
@ -58,7 +56,7 @@ As a result, the server should respond as follows:
}
```
If the RPT is not active, you will get this response instead:
If the RPT is not active, this response is returned instead:
```json
{
@ -68,13 +66,13 @@ If the RPT is not active, you will get this response instead:
=== 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.
No. 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.
If you want to validate these tokens without a call to the remote introspection endpoint, you can decode the RPT and check for its validity locally. Once you decode the token,
If you want to validate these tokens without a call to the remote introspection endpoint, you can decode the RPT and query for its validity locally. Once you decode the token,
you can also use the permissions within the token to enforce authorization decisions.
This is essentially what the link:../../enforcer/overview.html[Policy Enforcers] do, just be sure to:
This is essentially what the link:../../enforcer/overview.html[policy enforcers] do. Be sure to:
* Validate RPT's signature (based on realm's public key)
* Check for token validity based on its _exp_, _iat_ and _aud_ claims
* Validate the signature of the RPT (based on the realm's public key)
* Query for token validity based on its _exp_, _iat_, and _aud_ claims

View file

@ -1,12 +1,12 @@
== What is a PAT and How to Obtain It?
A *Protection API Token* (PAT) is a special OAuth2 Access Token with a scope defined as *uma_protection*. When you create a resource server, {{book.project.name}} automatically
creates a role _uma_protection_ for the corresponding client application and associates it with the client's service account.
A *protection API token* (PAT) is a special OAuth2 access token with a scope defined as *uma_protection*. When you create a resource server, {{book.project.name}} automatically
creates a role, _uma_protection_, for the corresponding client application and associates it with the client's service account.
.Service Account granted with *uma_protection* role
image:../../../images/service/rs-uma-protection-role.png[alt="Service Account granted with uma_protection role"]
Resource servers can obtain a PAT from {{book.project.name}} just like any other OAuth2 Access Token. For example, using curl:
Resource servers can obtain a PAT from {{book.project.name}} like any other OAuth2 access token. For example, using curl:
```bash
curl -X POST \
@ -16,11 +16,7 @@ curl -X POST \
"http://localhost:8080/auth/realms/${realm_name}/protocol/openid-connect/token"
```
The example above is using the *client_credentials* grant type to obtain a PAT from the server. As a result, the server would return a response similar to the following:
[NOTE]
{{book.project.name}} can authenticate your client application in different ways. We are using *client_credentials* grant type for the sake of simplicity,
which basically requires a _client_id_ and a _client_secret_. You can choose any other supported authentication method.
The example above is using the *client_credentials* grant type to obtain a PAT from the server. As a result, the server returns a response similar to the following:
```bash
{
@ -34,3 +30,7 @@ which basically requires a _client_id_ and a _client_secret_. You can choose any
"session_state": "ccea4a55-9aec-4024-b11c-44f6f168439e"
}
```
[NOTE]
{{book.project.name}} can authenticate your client application in different ways. For simplicity, the *client_credentials* grant type is used here,
which requires a _client_id_ and a _client_secret_. You can choose to use any supported authentication method.