diff --git a/SUMMARY.adoc b/SUMMARY.adoc
index bec52f8634..50e174ff17 100755
--- a/SUMMARY.adoc
+++ b/SUMMARY.adoc
@@ -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]
diff --git a/images/pep-pattern-diagram.png b/images/pep-pattern-diagram.png
new file mode 100644
index 0000000000..3e019cce88
Binary files /dev/null and b/images/pep-pattern-diagram.png differ
diff --git a/images/servlet-authz-app-structure.png b/images/servlet-authz-app-structure.png
new file mode 100644
index 0000000000..c6b1418bb3
Binary files /dev/null and b/images/servlet-authz-app-structure.png differ
diff --git a/topics/enforcer/jaxrs-enforcer.adoc b/topics/enforcer/jaxrs-enforcer.adoc
deleted file mode 100755
index 503f2ba8f9..0000000000
--- a/topics/enforcer/jaxrs-enforcer.adoc
+++ /dev/null
@@ -1 +0,0 @@
-== JAX-RS Policy Enforcer
\ No newline at end of file
diff --git a/topics/enforcer/overview.adoc b/topics/enforcer/overview.adoc
index 68f4036058..3320f6f29e 100755
--- a/topics/enforcer/overview.adoc
+++ b/topics/enforcer/overview.adoc
@@ -1 +1,7 @@
-== Policy Enforcers
\ No newline at end of file
+== 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"]
\ No newline at end of file
diff --git a/topics/getting-started/getting-started.adoc b/topics/getting-started/getting-started.adoc
index 412b84ede0..cb0166c098 100755
--- a/topics/getting-started/getting-started.adoc
+++ b/topics/getting-started/getting-started.adoc
@@ -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"]
\ No newline at end of file
diff --git a/topics/getting-started/hello-world-create-realm.adoc b/topics/getting-started/hello-world-create-realm.adoc
deleted file mode 100755
index 0962c385a7..0000000000
--- a/topics/getting-started/hello-world-create-realm.adoc
+++ /dev/null
@@ -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\"]"
- }
-}
-
-```
\ No newline at end of file
diff --git a/topics/getting-started/hello-world-entitlement.adoc b/topics/getting-started/hello-world-entitlement.adoc
deleted file mode 100755
index 52a3ed08af..0000000000
--- a/topics/getting-started/hello-world-entitlement.adoc
+++ /dev/null
@@ -1 +0,0 @@
-== Obtaining Permissions using the Entitlement API
\ No newline at end of file
diff --git a/topics/getting-started/hello-world-servlet-authz.adoc b/topics/getting-started/hello-world-servlet-authz.adoc
new file mode 100755
index 0000000000..9f878dc636
--- /dev/null
+++ b/topics/getting-started/hello-world-servlet-authz.adoc
@@ -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
+
+ Keycloak Authorization Enforcer
+ org.keycloak.authorization.policy.enforcer.servlet.KeycloakAdapterEnforcementFilter
+
+
+
+ Keycloak Authorization Enforcer
+ /*
+
+```
+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
+
+
+
+
+
+
+
+
+
+
+
+```
+
+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
+```
\ No newline at end of file
diff --git a/topics/getting-started/hello-world.adoc b/topics/getting-started/hello-world.adoc
index cb175f4732..6075057c7f 100755
--- a/topics/getting-started/hello-world.adoc
+++ b/topics/getting-started/hello-world.adoc
@@ -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"]