keycloak-aplcache

Details

diff --git a/adapters/oidc/js/src/main/resources/keycloak-authz.js b/adapters/oidc/js/src/main/resources/keycloak-authz.js
index 7658352..dd18477 100644
--- a/adapters/oidc/js/src/main/resources/keycloak-authz.js
+++ b/adapters/oidc/js/src/main/resources/keycloak-authz.js
@@ -49,7 +49,7 @@
          */
         this.authorize = function (wwwAuthenticateHeader) {
             this.then = function (onGrant, onDeny, onError) {
-                if (wwwAuthenticateHeader.startsWith('UMA')) {
+                if (wwwAuthenticateHeader.indexOf('UMA') != -1) {
                     var params = wwwAuthenticateHeader.split(',');
 
                     for (i = 0; i < params.length; i++) {
@@ -96,7 +96,7 @@
                             ));
                         }
                     }
-                } else if (wwwAuthenticateHeader.startsWith('KC_ETT')) {
+                } else if (wwwAuthenticateHeader.indexOf('KC_ETT') != -1) {
                     var params = wwwAuthenticateHeader.substring('KC_ETT'.length).trim().split(',');
                     var clientId = null;
 
diff --git a/examples/authz/hello-world-authz-service/hello-world-authz-realm.json b/examples/authz/hello-world-authz-service/hello-world-authz-realm.json
index 3ab917c..022ee6f 100644
--- a/examples/authz/hello-world-authz-service/hello-world-authz-realm.json
+++ b/examples/authz/hello-world-authz-service/hello-world-authz-realm.json
@@ -1,9 +1,8 @@
 {
   "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",
+  "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" :
   [
diff --git a/examples/authz/hello-world-authz-service/pom.xml b/examples/authz/hello-world-authz-service/pom.xml
index 5b9b646..679dd72 100755
--- a/examples/authz/hello-world-authz-service/pom.xml
+++ b/examples/authz/hello-world-authz-service/pom.xml
@@ -34,7 +34,6 @@
     <name>Keycloak Authz: Hello World Example</name>
 
     <build>
-        <finalName>${project.artifactId}</finalName>
         <plugins>
             <plugin>
                 <groupId>org.jboss.as.plugins</groupId>
diff --git a/examples/authz/hello-world-authz-service/src/main/webapp/WEB-INF/keycloak.json b/examples/authz/hello-world-authz-service/src/main/webapp/WEB-INF/keycloak.json
index f303fe1..a492837 100644
--- a/examples/authz/hello-world-authz-service/src/main/webapp/WEB-INF/keycloak.json
+++ b/examples/authz/hello-world-authz-service/src/main/webapp/WEB-INF/keycloak.json
@@ -1,6 +1,6 @@
 {
   "realm": "hello-world-authz",
-  "realm-public-key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzMhNM9HXNQWhVf1m64zS67SIyQjj+tV5GR+MqlRTWDXdo8GAWHd+alY1urRhfRoqMy4F499+8wh2REKFykNt0ng6s6wWnEaKDboS3SAUV6lybcOAkwIOCtCZj1ItddKG3m64fzxDDQrcpkbiAvw3S8KJ4UJK+pyh9iX01duSDtM/HhPawsPdY8JSMfuo1IxQ2Vxw+8RKwbbdUeew6cyYGYAeFYwA66mlM3otB0RBHh4bjwg8297+2g53TdwM2rbCHRbrorMQD3031OTyFSp7lXCtoMLWRfAFnOP/2yZWZMXbiJheC0R3sLbU7Ef0/cUbYyk4Ckfq6pcYDR+VZBF7AwIDAQAB",
+  "realm-public-key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
   "auth-server-url": "http://localhost:8080/auth",
   "ssl-required": "external",
   "resource": "hello-world-authz-service",
diff --git a/examples/authz/photoz/photoz-html5-client/src/main/webapp/index.html b/examples/authz/photoz/photoz-html5-client/src/main/webapp/index.html
index f9375a2..98f0856 100755
--- a/examples/authz/photoz/photoz-html5-client/src/main/webapp/index.html
+++ b/examples/authz/photoz/photoz-html5-client/src/main/webapp/index.html
@@ -13,7 +13,6 @@
 
     <script src="http://localhost:8080/auth/js/keycloak.js"></script>
     <script src="http://localhost:8080/auth/js/keycloak-authz.js"></script>
-    <script src="js/security/keycloak-authorization.js" type="text/javascript"></script>
     <script src="js/identity.js" type="text/javascript"></script>
     <script src="js/app.js" type="text/javascript"></script>
 </head>
diff --git a/examples/authz/photoz/photoz-html5-client/src/main/webapp/keycloak.json b/examples/authz/photoz/photoz-html5-client/src/main/webapp/keycloak.json
index 4b4d193..c1dee24 100644
--- a/examples/authz/photoz/photoz-html5-client/src/main/webapp/keycloak.json
+++ b/examples/authz/photoz/photoz-html5-client/src/main/webapp/keycloak.json
@@ -1,12 +1,8 @@
 {
   "realm": "photoz",
-  "realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+  "realm-public-key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
   "auth-server-url" : "http://localhost:8080/auth",
   "ssl-required" : "external",
   "resource" : "photoz-html5-client",
-  "public-client" : true,
-  "use-resource-role-mappings": "false",
-  "scope" : {
-    "realm" : [ "user" ]
-  }
+  "public-client" : true
 }
\ No newline at end of file
diff --git a/examples/authz/photoz/photoz-html5-client/src/main/webapp/partials/admin/albums.html b/examples/authz/photoz/photoz-html5-client/src/main/webapp/partials/admin/albums.html
index bb381b9..da78224 100644
--- a/examples/authz/photoz/photoz-html5-client/src/main/webapp/partials/admin/albums.html
+++ b/examples/authz/photoz/photoz-html5-client/src/main/webapp/partials/admin/albums.html
@@ -10,7 +10,7 @@
             <td>
                 <ul>
                     <li data-ng-repeat="p in value">
-                        <a href="#/album/{{p.id}}">{{p.name}}</a> - [<a href="#" ng-click="deleteAlbum(p)">X</a>]
+                        <a href="#/album/{{p.id}}">{{p.name}}</a> - [<a href="#" id="delete-{{p.name}}" ng-click="deleteAlbum(p)">X</a>]
                     </li>
                 </ul>
             </td>
diff --git a/examples/authz/photoz/photoz-html5-client/src/main/webapp/partials/album/create.html b/examples/authz/photoz/photoz-html5-client/src/main/webapp/partials/album/create.html
index 556693c..d9ddd25 100644
--- a/examples/authz/photoz/photoz-html5-client/src/main/webapp/partials/album/create.html
+++ b/examples/authz/photoz/photoz-html5-client/src/main/webapp/partials/album/create.html
@@ -1,7 +1,7 @@
 <h1>Create an Album</h1>
 
 <form>
-    Name: <input type="text" ng-model="album.name"/>
+    Name: <input type="text" id="album.name" ng-model="album.name"/>
 
-    <button ng-click="create()">Save</button>
+    <button ng-click="create()" id="save-album">Save</button>
 </form>
diff --git a/examples/authz/photoz/photoz-html5-client/src/main/webapp/partials/home.html b/examples/authz/photoz/photoz-html5-client/src/main/webapp/partials/home.html
index 5e164b2..bd5853e 100644
--- a/examples/authz/photoz/photoz-html5-client/src/main/webapp/partials/home.html
+++ b/examples/authz/photoz/photoz-html5-client/src/main/webapp/partials/home.html
@@ -1,12 +1,12 @@
 <h2><span>Welcome To Photoz, {{Identity.claims.name}}</span> [<a href="" ng-click="Identity.logout()">Sign Out</a>]</h2>
-<div data-ng-show="Identity.isAdmin()"><b>Administration: </b> [<a href="#/admin/album">All Albums</a>]</div>
+<div data-ng-show="Identity.isAdmin()"><b>Administration: </b> [<a href="#/admin/album" id="admin-albums">All Albums</a>]</div>
 <hr/>
 <br/>
 <div data-ng-show="!Identity.isAdmin()">
-<a href="#/album/create">Create Album</a> | <a href="#/profile">My Profile</a>
+<a href="#/album/create" id="create-album">Create Album</a> | <a href="#/profile">My Profile</a>
 <br/>
 <br/>
-<span data-ng-show="albums.length == 0">You don't have any albums, yet.</span>
+<span data-ng-show="albums.length == 0" id="resource-list-empty">You don't have any albums, yet.</span>
 <table class="table" data-ng-show="albums.length > 0">
     <thead>
         <tr>
@@ -15,7 +15,7 @@
     </thead>
     <tbody>
         <tr data-ng-repeat="p in albums">
-            <td><a href="#/album/{{p.id}}">{{p.name}}</a> - [<a href="#" ng-click="deleteAlbum(p)">X</a>]</td>
+            <td><a href="#/album/{{p.id}}">{{p.name}}</a> - [<a href="#" id="delete-{{p.name}}" ng-click="deleteAlbum(p)">X</a>]</td>
         </tr>
     </tbody>
 </table>
diff --git a/examples/authz/photoz/photoz-realm.json b/examples/authz/photoz/photoz-realm.json
index 342665e..b3b2b81 100644
--- a/examples/authz/photoz/photoz-realm.json
+++ b/examples/authz/photoz/photoz-realm.json
@@ -92,17 +92,19 @@
       "publicClient": true,
       "redirectUris": [
         "/photoz-html5-client/*"
-      ]
+      ],
+      "webOrigins": ["*"]
     },
     {
       "clientId": "photoz-restful-api",
+      "secret": "secret",
       "enabled": true,
       "baseUrl": "/photoz-restful-api",
       "authorizationServicesEnabled" : true,
       "redirectUris": [
         "/photoz-restful-api/*"
       ],
-      "secret": "secret"
+      "webOrigins" : ["*"]
     }
   ]
 }
diff --git a/examples/authz/photoz/photoz-restful-api/pom.xml b/examples/authz/photoz/photoz-restful-api/pom.xml
index eea3c17..4db7bb2 100755
--- a/examples/authz/photoz/photoz-restful-api/pom.xml
+++ b/examples/authz/photoz/photoz-restful-api/pom.xml
@@ -25,6 +25,7 @@
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
             <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>javax.persistence</groupId>
diff --git a/examples/authz/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/album/AlbumService.java b/examples/authz/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/album/AlbumService.java
index be2f1eb..388c9e4 100644
--- a/examples/authz/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/album/AlbumService.java
+++ b/examples/authz/photoz/photoz-restful-api/src/main/java/org/keycloak/example/photoz/album/AlbumService.java
@@ -1,11 +1,14 @@
 package org.keycloak.example.photoz.album;
 
 import org.keycloak.authorization.client.AuthzClient;
+import org.keycloak.authorization.client.Configuration;
 import org.keycloak.authorization.client.representation.ResourceRepresentation;
 import org.keycloak.authorization.client.representation.ScopeRepresentation;
 import org.keycloak.authorization.client.resource.ProtectionResource;
 import org.keycloak.example.photoz.ErrorResponse;
 import org.keycloak.example.photoz.entity.Album;
+import org.keycloak.representations.adapters.config.AdapterConfig;
+import org.keycloak.util.JsonSerialization;
 
 import javax.ejb.Stateless;
 import javax.persistence.EntityManager;
@@ -38,9 +41,18 @@ public class AlbumService {
     @PersistenceContext
     private EntityManager entityManager;
 
+    @Context
+    private HttpServletRequest request;
+
+    private AuthzClient authzClient;
+
+    public AlbumService() {
+
+    }
+
     @POST
     @Consumes("application/json")
-    public Response create(@Context HttpServletRequest request, Album newAlbum) {
+    public Response create(Album newAlbum) {
         Principal userPrincipal = request.getUserPrincipal();
 
         newAlbum.setUserId(userPrincipal.getName());
@@ -78,7 +90,7 @@ public class AlbumService {
 
     @GET
     @Produces("application/json")
-    public Response findAll(@Context HttpServletRequest request) {
+    public Response findAll() {
         return Response.ok(this.entityManager.createQuery("from Album where userId = '" + request.getUserPrincipal().getName() + "'").getResultList()).build();
     }
 
@@ -107,7 +119,7 @@ public class AlbumService {
 
             albumResource.setOwner(album.getUserId());
 
-            AuthzClient.create().protection().resource().create(albumResource);
+            getAuthzClient().protection().resource().create(albumResource);
         } catch (Exception e) {
             throw new RuntimeException("Could not register protected resource.", e);
         }
@@ -117,7 +129,7 @@ public class AlbumService {
         String uri = "/album/" + album.getId();
 
         try {
-            ProtectionResource protection = AuthzClient.create().protection();
+            ProtectionResource protection = getAuthzClient().protection();
             Set<String> search = protection.resource().findByFilter("uri=" + uri);
 
             if (search.isEmpty()) {
@@ -129,4 +141,19 @@ public class AlbumService {
             throw new RuntimeException("Could not search protected resource.", e);
         }
     }
+
+    private AuthzClient getAuthzClient() {
+        if (this.authzClient == null) {
+            try {
+                AdapterConfig adapterConfig = JsonSerialization.readValue(this.request.getServletContext().getResourceAsStream("/WEB-INF/keycloak.json"), AdapterConfig.class);
+                Configuration configuration = new Configuration(adapterConfig.getAuthServerUrl(), adapterConfig.getRealm(), adapterConfig.getResource(), adapterConfig.getCredentials(), null);
+
+                this.authzClient = AuthzClient.create(configuration);
+            } catch (Exception e) {
+                throw new RuntimeException("Could not create authorization client.", e);
+            }
+        }
+
+        return this.authzClient;
+    }
 }
diff --git a/examples/authz/photoz/photoz-restful-api-authz-service.json b/examples/authz/photoz/photoz-restful-api-authz-service.json
index 1d0356c..ff9ee9c 100644
--- a/examples/authz/photoz/photoz-restful-api-authz-service.json
+++ b/examples/authz/photoz/photoz-restful-api-authz-service.json
@@ -152,7 +152,7 @@
       }
     },
     {
-      "name": "Delete Album Policy",
+      "name": "Delete Album Permission",
       "description": "A policy that only allows the owner to delete his albums.",
       "type": "scope",
       "logic": "POSITIVE",
diff --git a/examples/authz/servlet-authz/src/main/webapp/index.jsp b/examples/authz/servlet-authz/src/main/webapp/index.jsp
index 78c5444..3fbfca2 100755
--- a/examples/authz/servlet-authz/src/main/webapp/index.jsp
+++ b/examples/authz/servlet-authz/src/main/webapp/index.jsp
@@ -1,6 +1,6 @@
 <%@page import="org.keycloak.AuthorizationContext" %>
 <%@ page import="org.keycloak.KeycloakSecurityContext" %>
-<%@ page import="org.keycloak.representations.authorization.Permission" %>
+<%@ page import="org.keycloak.representations.idm.authorization.Permission" %>
 
 <%
     KeycloakSecurityContext keycloakSecurityContext = (KeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName());
diff --git a/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-controller.js b/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-controller.js
index ecbe9d5..216a5a9 100644
--- a/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-controller.js
+++ b/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-controller.js
@@ -6,7 +6,7 @@ module.controller('ResourceServerCtrl', function($scope, realm, ResourceServer) 
     });
 });
 
-module.controller('ResourceServerDetailCtrl', function($scope, $http, $route, $location, $upload, realm, ResourceServer, client, AuthzDialog, Notifications) {
+module.controller('ResourceServerDetailCtrl', function($scope, $http, $route, $location, $upload, $modal, realm, ResourceServer, client, AuthzDialog, Notifications) {
     $scope.realm = realm;
     $scope.client = client;
 
@@ -31,8 +31,7 @@ module.controller('ResourceServerDetailCtrl', function($scope, $http, $route, $l
         }
 
         $scope.reset = function() {
-            $scope.server = angular.copy(data);
-            $scope.changed = false;
+            $route.reload();
         }
 
         $scope.export = function() {
@@ -54,38 +53,29 @@ module.controller('ResourceServerDetailCtrl', function($scope, $http, $route, $l
             delete $scope.settings
         }
 
-        $scope.onFileSelect = function($files) {
-            $scope.files = $files;
+        $scope.onFileSelect = function($fileContent) {
+            $scope.server = angular.copy(JSON.parse($fileContent));
+            $scope.importing = true;
         };
 
-        $scope.clearFileSelect = function() {
-            $scope.files = null;
-        }
-
-        $scope.uploadFile = function() {
-            //$files: an array of files selected, each file has name, size, and type.
-            for (var i = 0; i < $scope.files.length; i++) {
-                var $file = $scope.files[i];
-                $scope.upload = $upload.upload({
-                    url: authUrl + '/admin/realms/' + $route.current.params.realm  + '/clients/' + client.id + '/authz/resource-server', //upload.php script, node.js route, or servlet url
-                    // method: POST or PUT,
-                    // headers: {'headerKey': 'headerValue'}, withCredential: true,
-                    data: {myObj: ""},
-                    file: $file
-                    /* set file formData name for 'Content-Desposition' header. Default: 'file' */
-                    //fileFormDataName: myFile,
-                    /* customize how data is added to formData. See #40#issuecomment-28612000 for example */
-                    //formDataAppender: function(formData, key, val){}
-                }).progress(function(evt) {
-                    console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total));
-                }).success(function(data, status, headers) {
-                    $route.reload();
-                    Notifications.success("The resource server has been updated.");
-                }).error(function() {
-                    Notifications.error("The resource server can not be uploaded. Please verify the file.");
-                });
-            }
+        $scope.viewImportDetails = function() {
+            $modal.open({
+                templateUrl: resourceUrl + '/partials/modal/view-object.html',
+                controller: 'ObjectModalCtrl',
+                resolve: {
+                    object: function () {
+                        return $scope.server;
+                    }
+                }
+            })
         };
+
+        $scope.import = function () {
+            ResourceServer.import({realm : realm.realm, client : client.id}, $scope.server, function() {
+                $route.reload();
+                Notifications.success("The resource server has been updated.");
+            });
+        }
     });
 });
 
diff --git a/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-services.js b/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-services.js
index c74db28..e611430 100644
--- a/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-services.js
+++ b/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-services.js
@@ -4,6 +4,7 @@ module.factory('ResourceServer', function($resource) {
         client: '@client'
     }, {
         'update' : {method : 'PUT'},
+        'import' : {url: authUrl + '/admin/realms/:realm/clients/:client/authz/resource-server/import', method : 'POST'},
         'settings' : {url: authUrl + '/admin/realms/:realm/clients/:client/authz/resource-server/settings', method : 'GET'}
     });
 });
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/resource-server-detail.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/resource-server-detail.html
index 918cadf..2b3cd70 100644
--- a/themes/src/main/resources/theme/base/admin/resources/partials/authz/resource-server-detail.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/resource-server-detail.html
@@ -7,22 +7,24 @@
             <div class="form-group">
                 <label for="import-file" class="col-sm-2 control-label">Import</label>
                 <div class="col-md-6">
-                    <div class="controls kc-button-input-file" data-ng-show="!files || files.length == 0">
+                    <div class="controls kc-button-input-file" data-ng-show="!importing">
                         <label for="import-file" class="btn btn-default">Select file <i class="pficon pficon-import"></i></label>
-                        <input id="import-file" type="file" class="hidden" ng-file-select="onFileSelect($files)">
+                        <input id="import-file" type="file" class="hidden" kc-on-read-file="onFileSelect($fileContent)">
+                    </div>
+                    <div class="col-md-6" data-ng-show="importing">
+                        <input type="button" class="btn btn-default" data-ng-click="viewImportDetails()" value="{{:: 'view-details' | translate}}"/>
                     </div>
-                    <span class="kc-uploaded-file" data-ng-show="files.length > 0">{{files[0].name}}</span>
                 </div>
                 <kc-tooltip>Import a JSON file containing all settings for this resource server.</kc-tooltip>
             </div>
             <div class="form-group">
-                <div class="col-md-10 col-md-offset-2">
-                    <button type="submit" data-ng-disabled="files.length == 0" data-ng-click="uploadFile()" class="btn btn-primary">Upload</button>
-                    <button type="submit" data-ng-disabled="files.length == 0" data-ng-click="clearFileSelect()" class="btn btn-default" data-ng-show="files.length > 0">Cancel</button>
+                <div class="col-md-10 col-md-offset-2" data-ng-show="importing">
+                    <button class="btn btn-default" data-ng-click="import()" data-ng-disabled="!changed">Import</button>
+                    <button kc-cancel data-ng-click="reset()">Cancel</button>
                 </div>
             </div>
         </fieldset>
-        <fieldset class="border-top" data-ng-hide="files.length > 0">
+        <fieldset class="border-top" data-ng-hide="importing">
             <div class="form-group">
                 <label class="col-md-2 control-label" for="server.policyEnforcementMode">Policy Enforcement Mode</label>
                 <div class="col-md-2">
@@ -54,7 +56,7 @@
             </div>
         </fieldset>
 
-        <fieldset class="border-top" data-ng-show="!files || files.length == 0">
+        <fieldset class="border-top" data-ng-show="server.id">
             <legend><span class="text">Export Settings</span>
                 <kc-tooltip>Here you can export all settings for this resource server.</kc-tooltip>
             </legend>