Merge pull request #6 from pedroigor/master

Servlet security quickstart
This commit is contained in:
Pedro Igor 2016-06-03 20:49:58 -03:00
commit 3e5a6a9281
10 changed files with 474 additions and 207 deletions

View file

@ -5,6 +5,7 @@
.. link:topics/overview/terminology.adoc[Terminology]
. link:topics/getting-started/getting-started.adoc[Getting Started]
.. link:topics/getting-started/hello-world.adoc[Hello Authorization World]
.. link:topics/getting-started/hello-world-servlet-authz.adoc[Securing a Servlet Application]
. link:topics/resource-server/overview.adoc[Managing Resource Servers]
.. link:topics/resource-server/view.adoc[Viewing Resource Servers]
.. link:topics/resource-server/create.adoc[Creating Resource Servers]

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View file

@ -1 +0,0 @@
== JAX-RS Policy Enforcer

View file

@ -1 +1,7 @@
== Policy Enforcers
== Policy Enforcers
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 using different programming languages. After all, {{book.project.name}} {{book.project.module}} is
fully RESTFUL-based, leveraging OAuth2 authorization capabilities to also support fine-grained authorization using a centralized authorization server.
image:../../images/pep-pattern-diagram.png[alt="PEP Overview"]

View file

@ -6,7 +6,9 @@ you to understand the basic steps to enable fine-grained authorization to an app
[NOTE]
This guide assume 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].
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 would be able to login to the
All the guides are based on the *{{book.project.name}} Demo Distribution*. Please download it before going further with any guide.
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:
image:../../images/gs-keycloak-console-page.png[alt="Keycloak Administration Console"]

View file

@ -1,202 +0,0 @@
=== Creating the Hello World AuthZ Realm
For this guide, we are going to create a *hello-world-authz* realm. Just import the following JSON file to create the new realm:
```json
{
"realm" : "hello-world-authz",
"enabled" : true,
"privateKey" : "MIIEpQIBAAKCAQEAzMhNM9HXNQWhVf1m64zS67SIyQjj+tV5GR+MqlRTWDXdo8GAWHd+alY1urRhfRoqMy4F499+8wh2REKFykNt0ng6s6wWnEaKDboS3SAUV6lybcOAkwIOCtCZj1ItddKG3m64fzxDDQrcpkbiAvw3S8KJ4UJK+pyh9iX01duSDtM/HhPawsPdY8JSMfuo1IxQ2Vxw+8RKwbbdUeew6cyYGYAeFYwA66mlM3otB0RBHh4bjwg8297+2g53TdwM2rbCHRbrorMQD3031OTyFSp7lXCtoMLWRfAFnOP/2yZWZMXbiJheC0R3sLbU7Ef0/cUbYyk4Ckfq6pcYDR+VZBF7AwIDAQABAoIBAAwa4wVnKBOIS6srmYPfBTDNsTBBCEjxiYEErmn7JhoWxQ1DCPUxyxU6F177/q9Idqoj1FFOCtEO9P6/9+ym470HQmEQkR2Xxd1d3HOZy9oKuCro3ZbTDkVxY0JnlyxZz4MihGFxDH2e4MArfHy0sAgYbdIU+x2pWKGWSMzDd/TMSOExhc/sIQAg6ljbPCLLXCPQFAncoHRyGPrkRZs6UTZi5SJuCglVa2/3G+0drDdPuA83/mwsZfIBqQgbGbFgtq5T5C6CKMkPOQ42Rcclm7kEr6riTkJRo23EO1iOJVpxzI0tbxZsJAsW7zeqv0wWRyUgVfQAje6OdsNexp5aCtECgYEA6nMHCQ9xXvufCyzpIbYGxdAGqH6m1AR5gXerHqRiGNx+8UUt/E9cy/HTOhmZDK/eC4BT9tImeF01l1oSU/+wGKfux0SeAQchBhhq8GD6jmrtgczKAfZHp0Zrht7o9qu9KE7ZNWRmY1foJN9yNYmzY6qqHEy+zNo9amcqT7UZKO8CgYEA35sp9fMpMqkJE+NEJ9Ph/t2081BEkC0DYIuETZRSi+Ek5AliWTyEkg+oisTbWzi6fMQHS7W+M1SQP6djksLQNPP+353DKgup5gtKS+K/y2xNd7fSsNmkjW1bdJJpID7WzwwmwdahHxpcnFFuEXi5FkG3Vqmtd3cD0TYL33JlRy0CgYEA0+a3eybsDy9Zpp4m8IM3R98nxW8DlimdMLlafs2QpGvWiHdAgwWwF90wTxkHzgG+raKFQVbb0npcj7mnSyiUnxRZqt2H+eHZpUq4jR76F3LpzCGui2tvg+8QDMy4vwqmYyIxDCL8r9mqRnl3HpChBPoh2oY7BahTTjKEeZpzbR0CgYEAoNnVjX+mGzNNvGi4Fo5s/BIwoPcU20IGM+Uo/0W7O7Rx/Thi7x6BnzB0ZZ7GzRA51paNSQEsGXCzc5bOIjzR2cXLisDKK+zIAxwMDhrHLWZzM7OgdGeb38DTEUBhLzkE/VwYZUgoD1+/TxOkwhy9yCzt3gGhL1cF//GJCOwZvuECgYEAgsO4rdYScgCpsyePnHsFk+YtqtdORnmttF3JFcL3w2QneXuRwg2uW2Kfz8CVphrR9eOU0tiw38w6QTHIVeyRY8qqlHtiXj6dEYz7frh/k4hI29HwFx43rRpnAnN8kBEJYBYdbjaQ35Wsqkfu1tvHJ+6fxSwvQu/TVdGp0OfilAY=",
"publicKey" : "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzMhNM9HXNQWhVf1m64zS67SIyQjj+tV5GR+MqlRTWDXdo8GAWHd+alY1urRhfRoqMy4F499+8wh2REKFykNt0ng6s6wWnEaKDboS3SAUV6lybcOAkwIOCtCZj1ItddKG3m64fzxDDQrcpkbiAvw3S8KJ4UJK+pyh9iX01duSDtM/HhPawsPdY8JSMfuo1IxQ2Vxw+8RKwbbdUeew6cyYGYAeFYwA66mlM3otB0RBHh4bjwg8297+2g53TdwM2rbCHRbrorMQD3031OTyFSp7lXCtoMLWRfAFnOP/2yZWZMXbiJheC0R3sLbU7Ef0/cUbYyk4Ckfq6pcYDR+VZBF7AwIDAQAB",
"certificate" : "MIICsTCCAZkCBgFVETX4AzANBgkqhkiG9w0BAQsFADAcMRowGAYDVQQDDBFIZWxsbyBXb3JsZCBBdXRoWjAeFw0xNjA2MDIxMzAxMzdaFw0yNjA2MDIxMzAzMTdaMBwxGjAYBgNVBAMMEUhlbGxvIFdvcmxkIEF1dGhaMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzMhNM9HXNQWhVf1m64zS67SIyQjj+tV5GR+MqlRTWDXdo8GAWHd+alY1urRhfRoqMy4F499+8wh2REKFykNt0ng6s6wWnEaKDboS3SAUV6lybcOAkwIOCtCZj1ItddKG3m64fzxDDQrcpkbiAvw3S8KJ4UJK+pyh9iX01duSDtM/HhPawsPdY8JSMfuo1IxQ2Vxw+8RKwbbdUeew6cyYGYAeFYwA66mlM3otB0RBHh4bjwg8297+2g53TdwM2rbCHRbrorMQD3031OTyFSp7lXCtoMLWRfAFnOP/2yZWZMXbiJheC0R3sLbU7Ef0/cUbYyk4Ckfq6pcYDR+VZBF7AwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQANm5gIT/c50lwjawM686gNXpppLA928WsCOn9NIIWjSKekP8Bf9S73kf7vWcsEppm5B8rRyRxolXmzwghv74L7uVDg8Injjgj+XbPVQP+cJqWpSaMZHF7UfWe0/4M945Xcbmsl5q+m9PmrPG0AaaZhqXHcp4ehB1H+awyRqiERpJUuwZNycw2+2kjDADpsFf8hZVUd1F6ReYyOkqUyUjbL+jYTC7ZBNa7Ok+w6HCXWgkgVATAgQXJRM3w14IOc5MH/vfMCrCl/eNQLbjGl9y7u8PKwh3MXHDO2OLqtg6hOTSrOGUPJZGmGtUAl+2/R7FzoWkML/BNe2hjsL6UJwg91",
"requiredCredentials" : [ "password" ],
"roles" : {
"realm" : [
{
"name" : "uma_protection"
}
]
},
"users" :
[
{
"username" : "alice",
"enabled" : true,
"credentials" : [ {
"type" : "password",
"value" : "password"
} ],
"clientRoles" : {
"hello-world-authz-service" : [ "uma_authorization" ]
}
},
{
"username" : "jdoe",
"enabled" : true,
"credentials" : [ {
"type" : "password",
"value" : "password"
} ],
"clientRoles" : {
"hello-world-authz-service" : [ "uma_authorization" ]
}
},
{
"username" : "service-account-hello-world-authz-service",
"enabled" : true,
"serviceAccountClientId" : "hello-world-authz-service",
"realmRoles" : [ "uma_protection"]
}
],
"clients" : [
{
"clientId" : "hello-world-authz-service",
"secret" : "password",
"serviceAccountsEnabled" : true,
"enabled" : true,
"redirectUris" : [ "http://localhost:8080/hello-world-authz-service" ],
"directAccessGrantsEnabled" : true,
"publicClient" : false
}
]
}
```
The realm *hello-world-authz* consists of:
** Two users: _alice_ and _jdoe_
** One client application: _hello-world-authz-service_
** One global role: _uma_protection_
** One client role: _uma_authorization_
The _hello-world-authz-service_ is the application with the resources we want to protect. In other words, it will act as a link:../overview/terminology.html[Resource Server].
In {{book.project.name}} a resource server is just a regular client application with some specific characteristics. It _must_ be a *confidential* client application as defined by:
```json
"publicClient" : false
```
It must have a *client_id*, *client_secret* and *Service Account* enabled:
```json
"clients" : [
{
"clientId" : "hello-world-authz-service",
"secret" : "7801be7c-437a-44ae-be34-67da32f024eb",
"serviceAccountsEnabled" : true,
...
}
]
```
And finally, an user mapping to the client's service account:
```json
{
"username" : "service-account-my-resource-server",
"enabled" : true,
"serviceAccountClientId" : "hello-world-authz-service",
"realmRoles" : [ "uma_protection"]
}
```
In the latter case, we are also granting the *uma_protection* role to the client's service account. As you'll see, that will be necessary in order to get access to the link:../service/protection-api.html[Protection API].
=== Creating a Resource Server and Protecting Resources
Now that we have the *hello-world-authz* realm properly configured, we need to enable the *hello-world-authz-service* as a resource server. For that, click on the *Authorization* in the left menu bar.
image:../../images/gs-keycloak-authz-page.png[alt="Keycloak Authorization Page"]
To create a resource server you can click on the *Create* button.
image:../../images/gs-keycloak-authz-create-rs-page.png[alt="Create Resource Server"]
From that page you can create a resource server by manually filling that form or you can just import a JSON file with the configuration you want. For this guide, we'll just import a JSON file as follows:
```json
{
"clientId": "hello-world-authz-service",
"resources": [
{
"name": "Hello World Resource"
}
],
"policies": [
{
"name": "Only Special Users Policy",
"type": "user",
"logic": "POSITIVE",
"config": {
"users": "[\"alice\"]"
}
},
{
"name": "Hello World Resource Permission",
"type": "resource",
"config": {
"resources": "[\"Hello World Resource\"]",
"applyPolicies": "[\"Only Special Users Policy\"]"
}
}
]
}
```
After importing the JSON file above, you would see a page like that:
image:../../images/gs-authz-hello-rs-created-page.png[alt="Resource Server Successfully Created"]
You may take some time now exploring the resource server we just created. But first, let's understand what we just created.
The resource server was created based on the *hello-world-authz-service* client application, as you can see from the following configuration:
```json
{
"clientId": "hello-world-authz-service",
...
}
```
What we did was basically tell {{book.project.name}} that we want that client application acting as a resource server, so we can start creating the resources we want to protect as well the permissions
and authorization policies we want to use to actually protect the resources.
The purpose of this guide is keep things simple to get you started, so our newly created resource server has a single protected resource, as defined by the following configuration:
```json
{
...
"resources": [
{
"name": "Hello World Resource"
}
],
...
}
```
The *Hello World Resource* represents a set of one or more resources we want to protect. It can map to a single or to multiple resources in an application.
In order to protect it, we need to create the authorization policies and permissions we want to apply. Policies define the conditions that must be satisfied to grant a permission. Where a
permission is the link between a resource and the policies(or conditions) we want to enforce when someone wants to access a resource.
In this example, we have a single policy *Only Special Users Policy*. This policy tells that only the specified users are allowed to access _something_ (we don't know what, yet. That is up to the permission).
[NOTE]
{{book.project.name}} provides a few link:../policy/overview.html[policy types] that you can start using out-of-the-box. There are policies for RBAC, time constraints or even rules written using JavaScript or JBoss Drools.
The last step when protecting a resource is to define a permission. For that, we have defined a *Hello World Resource Permission* that links the resource we want to protect, _Hello World Resource_, with the
policy we want to apply to that resource, _Only Special Users Policy_.
```json
{
"name": "Hello World Resource Permission",
"type": "resource",
"config": {
"resources": "[\"Hello World Resource\"]",
"applyPolicies": "[\"Only Special Users Policy\"]"
}
}
```

View file

@ -1 +0,0 @@
== Obtaining Permissions using the Entitlement API

View file

@ -0,0 +1,456 @@
== Securing a Servlet Application
This guide will show you how to:
* Create a realm with the necessary configuration to enable fine-grained authorization to a servlet application
* Create a resource server and the resources that must be protected
* Create permissions, authorization policies and how to apply them to your protected resources
* Configure the {{book.project.name}} Authorization Enforcer Filter to your servlet application
The application we are using in this guide is one of the examples provided by the {{book.project.name}} Demo Distribution. You can find all the source code
under *examples/authz/servlet-authz/*.
[NOTE]
Before going further, make sure you followed all the instructions in the link:../getting-started/getting-started.html[Getting Started] guide.
=== About the Servlet Application
The application we are about to create is a very simple. In a nutshell, it implements the following security requirements:
* An _Administration Area_ that only administrators can access
* An _User Premium Area_ that only users with a premium plan can access
* A dynamic menu that is generated accordingly with the permissions issued by a {{book.project.name}} Server to an authenticated user
image:../../images/servlet-authz-app-structure.png[alt="Servlet Authz Application Structure"]
=== Creating the Servlet Authz Realm
For this guide, we are going to create a *servlet-authz* realm. Just import the following JSON file to create the new realm:
```json
{
"realm": "servlet-authz",
"enabled": true,
"privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
"publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"requiredCredentials": [
"password"
],
"users": [
{
"username": "alice",
"enabled": true,
"credentials": [
{
"type": "password",
"value": "alice"
}
],
"realmRoles": [
"user"
],
"clientRoles": {
"servlet-authz-app": [
"uma_authorization",
"kc_entitlement"
]
}
},
{
"username": "jdoe",
"enabled": true,
"credentials": [
{
"type": "password",
"value": "jdoe"
}
],
"realmRoles": [
"user",
"user_premium"
],
"clientRoles": {
"servlet-authz-app": [
"uma_authorization",
"kc_entitlement"
]
}
},
{
"username": "admin",
"enabled": true,
"credentials": [
{
"type": "password",
"value": "admin"
}
],
"realmRoles": [
"user",
"admin"
],
"clientRoles": {
"realm-management": [
"realm-admin"
],
"servlet-authz-app": [
"uma_authorization",
"kc_entitlement"
]
}
},
{
"username": "service-account-servlet-authz-app",
"enabled": true,
"serviceAccountClientId": "servlet-authz-app",
"realmRoles": [
"uma_protection"
]
}
],
"roles": {
"realm": [
{
"name": "user",
"description": "User privileges"
},
{
"name": "admin",
"description": "Administrator privileges"
},
{
"name": "user_premium",
"description": "User Premium privileges"
},
{
"name": "uma_protection",
"description": "Allows access to the Protection API"
}
]
},
"clients": [
{
"clientId": "servlet-authz-app",
"enabled": true,
"publicClient": false,
"baseUrl": "/servlet-authz-app",
"adminUrl": "/servlet-authz-app",
"bearerOnly": false,
"serviceAccountsEnabled": true,
"redirectUris": [
"/servlet-authz-app/*"
],
"secret": "secret"
}
]
}
```
=== Creating a Resource Server and Protecting Resources
Now that we have the *servlet-authz* realm properly configured, we need to enable the *servlet-authz-app* as a resource server. For that, click on the *Authorization* in the left menu bar.
image:../../images/gs-keycloak-authz-page.png[alt="Keycloak Authorization Page"]
To create a resource server you can click on the *Create* button.
image:../../images/gs-keycloak-authz-create-rs-page.png[alt="Create Resource Server"]
From that page you can create a resource server by manually filling that form or you can just import a JSON file with the configuration you want. For this guide, we'll just import a JSON file as follows:
```json
{
"clientId": "servlet-authz-app",
"allowRemoteResourceManagement": true,
"allowEntitlements": true,
"policyEnforcementMode": "ENFORCING",
"resources": [
{
"name": "Admin Resource",
"uri": "/protected/admin/*",
"type": "http://servlet-authz/protected/admin",
"scopes": [
{
"name": "urn:servlet-authz:protected:admin:access"
}
]
},
{
"name": "Protected Resource",
"uri": "/*",
"type": "http://servlet-authz/protected/resource",
"scopes": [
{
"name": "urn:servlet-authz:protected:resource:access"
}
]
},
{
"name": "Premium Resource",
"uri": "/protected/premium/*",
"type": "urn:servlet-authz:protected:resource",
"scopes": [
{
"name": "urn:servlet-authz:protected:premium:access"
}
]
},
{
"name": "Main Page",
"type": "urn:servlet-authz:protected:resource",
"scopes": [
{
"name": "urn:servlet-authz:page:main:actionForAdmin"
},
{
"name": "urn:servlet-authz:page:main:actionForUser"
},
{
"name": "urn:servlet-authz:page:main:actionForPremiumUser"
}
]
}
],
"policies": [
{
"name": "Any Admin Policy",
"description": "Defines that adminsitrators can do something",
"type": "role",
"config": {
"roles": "[\"admin\"]"
}
},
{
"name": "Any User Policy",
"description": "Defines that any user can do something",
"type": "role",
"config": {
"roles": "[\"user\"]"
}
},
{
"name": "Only Premium User Policy",
"description": "Defines that only premium users can do something",
"type": "role",
"logic": "POSITIVE",
"config": {
"roles": "[\"user_premium\"]"
}
},
{
"name": "All Users Policy",
"description": "Defines that all users can do something",
"type": "aggregate",
"decisionStrategy": "AFFIRMATIVE",
"config": {
"applyPolicies": "[\"Any User Policy\",\"Any Admin Policy\",\"Only Premium User Policy\"]"
}
},
{
"name": "Premium Resource Permission",
"description": "A policy that defines access to premium resources",
"type": "resource",
"decisionStrategy": "UNANIMOUS",
"config": {
"resources": "[\"Premium Resource\"]",
"applyPolicies": "[\"Only Premium User Policy\"]"
}
},
{
"name": "Administrative Resource Permission",
"description": "A policy that defines access to administrative resources",
"type": "resource",
"decisionStrategy": "UNANIMOUS",
"config": {
"resources": "[\"Admin Resource\"]",
"applyPolicies": "[\"Any Admin Policy\"]"
}
},
{
"name": "Protected Resource Permission",
"description": "A policy that defines access to any protected resource",
"type": "resource",
"decisionStrategy": "AFFIRMATIVE",
"config": {
"resources": "[\"Protected Resource\"]",
"applyPolicies": "[\"All Users Policy\"]"
}
},
{
"name": "Action 1 on Main Page Resource Permission",
"description": "A policy that defines access to action 1 on the main page",
"type": "scope",
"decisionStrategy": "AFFIRMATIVE",
"config": {
"scopes": "[\"urn:servlet-authz:page:main:actionForAdmin\"]",
"applyPolicies": "[\"Any Admin Policy\"]"
}
},
{
"name": "Action 2 on Main Page Resource Permission",
"description": "A policy that defines access to action 2 on the main page",
"type": "scope",
"decisionStrategy": "AFFIRMATIVE",
"config": {
"scopes": "[\"urn:servlet-authz:page:main:actionForUser\"]",
"applyPolicies": "[\"Any User Policy\"]"
}
},
{
"name": "Action 3 on Main Page Resource Permission",
"description": "A policy that defines access to action 3 on the main page",
"type": "scope",
"decisionStrategy": "AFFIRMATIVE",
"config": {
"scopes": "[\"urn:servlet-authz:page:main:actionForPremiumUser\"]",
"applyPolicies": "[\"Only Premium User Policy\"]"
}
}
]
}
```
[NOTE]
All this configuration can also be done using the {{book.project.name}} Administration Console. We are using the import tool just for demonstration purposes
=== A Quick Overview of the Permissions and Policies
The resource server configuration tells a lot about what we are really protecting. It is basically describing the security requirements we have discussed earlier.
Fist of all, we define four resources:
* Admin Resource
* Protected Resource
* Premium Resource
* Main Page
As the name implies, each of these resources are related with the requirements we previously discussed, representing the different areas or group of resources we want to protect.
As you may notice, each of these resources (except Main Page) defines an *uri* property. This property represents the path we want to protect and they map directly, or indirectly by using a pattern,
to the resources served by the application.
Let's take the _Protected Resource_ as an example:
```json
{
"name": "Protected Resource",
"uri": "/*",
"type": "http://servlet-authz/protected/resource",
"scopes": [
{
"name": "urn:servlet-authz:protected:resource:access"
}
]
},
```
This resource represents all resources in the application, as you can see from the pattern used in the *uri* property. It also defines a single scope/action to indicate that users, if granted, can access this resource.
Now, let's see what are the permissions and authorization policies configured to this resource:
```json
...
{
"name": "Protected Resource Permission",
"description": "A policy that defines access to any protected resource",
"type": "resource",
"decisionStrategy": "AFFIRMATIVE",
"config": {
"resources": "[\"Protected Resource\"]",
"applyPolicies": "[\"All Users Policy\"]"
}
},
...
```
The definition above is a permission that links the _Protected Resource_ with the policies we want to apply. In this case, we are applying a single _All Users Policy_.
Policies define the conditions to be meet in order to access something. In this case, the _All Users Policy_ is composed of two other policies, a special policy type called link:../policy/aggregated-policy.html[Aggregated Policies].
```json
...
{
"name": "All Users Policy",
"description": "Defines that all users can do something",
"type": "aggregate",
"decisionStrategy": "AFFIRMATIVE",
"config": {
"applyPolicies": "[\"Any User Policy\",\"Any Admin Policy\",\"Only Premium User Policy\"]"
}
},
...
```
{{book.project.name}} provides a few built-in policy types (and their respective policy providers) implementing different access control mechanisms (RBAC, GBAC, Rule-based, Time-based, etc) that you can use to build your own policies and permissions.
Aggregated policies are very useful in order to group related policies together and make policy management less painful.
=== Configuring the Keycloak Enforcement Filter
Now that we have all the configuration for our resource server in place, we can configure the authorization enforcement filter to actually protected the resources.
Just like any other Servlet Filter, you just need to include the following configuration in your web application descriptor (WEB-INF/web.xml):
```xml
<filter>
<filter-name>Keycloak Authorization Enforcer</filter-name>
<filter-class>org.keycloak.authorization.policy.enforcer.servlet.KeycloakAdapterEnforcementFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Keycloak Authorization Enforcer</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
```
The *org.keycloak.authorization.policy.enforcer.servlet.KeycloakAdapterEnforcementFilter* is shipped with the {{book.project.name}} OIDC Adapters distribution. In order to make it available to
your application at runtime, you must create a *META-INF/jboss-deployment-structure.xml* at the application root directory. If you are using maven, this file can be placed under *src/main/webapp/META-INF/jboss-deployment-structure.xml*:
```xml
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="org.keycloak.keycloak-authz-servlet-enforcer" services="import"/>
<module name="org.jboss.resteasy.resteasy-jackson2-provider" services="import"/>
</dependencies>
<exclusions>
<module name="org.jboss.resteasy.resteasy-jackson-provider"/>
</exclusions>
</deployment>
</jboss-deployment-structure>
```
For last, you need to create a *META-INF/keycloak-authz.json*. If you are using Maven, this file goes inside *src/main/resources*:
```json
{
"client": {
"configurationUrl": "http://localhost:8080/auth/realms/servlet-authz/authz/uma_configuration",
"clientId": "servlet-authz-app",
"clientSecret": "secret"
},
"enforcer": {}
}
```
=== Running and Using the Application
All the source code for this application is at *${KEYCLOAK_DEMO_SERVER_DIR}/examples/authz/servlet-authz/*.
There you can execute the following command to _deploy_ the application to the running server:
```bash
mvn clean package wildfly:deploy
```
That should be enough to get the application properly packaged and deployed to a _running_ {{book.project.name}} server.
If the application was properly deployed, you can try to access it at http://localhost:8080/auth[http://localhost:8080/servlet-authz-app] and use the following credentials to login into the application:
If everything is correct, you will be redirect to Keycloak login page. You can login to the application with the following credentials:
* username: alice / password: alice (regular user)
* username: jdoe / password: jdoe (premium user)
* username: admin / password: admin (administrator)
To _undeploy_ the application, please execute the following command:
```bash
mvn wildfly:undeploy
```

View file

@ -10,6 +10,9 @@ This guide will show you how to:
The purpose of this guide is to give you a generic overview of {{book.project.name}} {{book.project.module}} so you can understand
some core concepts and start protecting your applications and services despite the platform they are running on.
[NOTE]
Before going further, make sure you followed all the instructions in the link:../getting-started/getting-started.html[Getting Started] guide.
=== Creating the Hello World AuthZ Realm
For this guide, we are going to create a *hello-world-authz* realm. Just import the following JSON file to create the new realm:
@ -94,7 +97,7 @@ It must have a *client_id*, *client_secret* and *Service Account* enabled:
"clients" : [
{
"clientId" : "hello-world-authz-service",
"secret" : "7801be7c-437a-44ae-be34-67da32f024eb",
"secret" : "password",
"serviceAccountsEnabled" : true,
...
}
@ -156,6 +159,9 @@ From that page you can create a resource server by manually filling that form or
```
[NOTE]
All this configuration can also be done using the {{book.project.name}} Administration Console. We are using the import tool just for demonstration purposes
After importing the JSON file above, you would see a page like that:
image:../../images/gs-authz-hello-rs-created-page.png[alt="Resource Server Successfully Created"]