keycloak-aplcache

Merge pull request #244 from stianst/master Added view roles,

2/26/2014 2:39:51 PM

Changes

Details

diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js
index fae6147..62142ed 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js
@@ -521,6 +521,8 @@ module.factory('errorInterceptor', function($q, $window, $rootScope, $location, 
                 console.log('session timeout?');
                 Auth.loggedIn = false;
                 window.location = '/auth/rest/admin/login?path=' + $location.path();
+            } else if (response.status == 403) {
+                Notifications.error("Forbidden");
             } else if (response.status == 404) {
                 Notifications.error("Not found");
             } else if (response.status) {
@@ -785,6 +787,7 @@ module.directive('kcReadOnly', function() {
                 element.find('input').attr('disabled', 'disabled');
                 element.find('button').attr('disabled', 'disabled');
                 element.find('select').attr('disabled', 'disabled');
+                element.find('textarea').attr('disabled', 'disabled');
             }
         }
     };
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js
index eb54464..8220e9c 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js
@@ -22,6 +22,22 @@ module.controller('GlobalCtrl', function($scope, $http, Auth, Current, $location
         $scope.access = {
             admin: data.admin,
 
+            get viewRealm() {
+                return getAccess(Current.realm.realm, 'view-realm') || this.viewRealm;
+            },
+
+            get viewApplications() {
+                return getAccess(Current.realm.realm, 'view-applications') || this.manageApplications;
+            },
+
+            get viewClients() {
+                return getAccess(Current.realm.realm, 'view-clients') || this.manageClients;
+            },
+
+            get viewUsers() {
+                return getAccess(Current.realm.realm, 'view-users') || this.manageClients;
+            },
+
             get manageRealm() {
                 return getAccess(Current.realm.realm, 'manage-realm');
             },
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-credentials.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-credentials.html
index 8716490..a839ccf 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-credentials.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-credentials.html
@@ -16,7 +16,7 @@
             <li class="active">Credentials</li>
         </ol>
         <h2 data-ng-hide="create"><span>{{application.name}}</span> Credentials</h2>
-        <form class="form-horizontal" name="credentialForm" novalidate>
+        <form class="form-horizontal" name="credentialForm" novalidate kc-read-only="!access.manageApplications">
             <fieldset >
                 <legend><span class="text">Client Secret</span></legend>
                 <div class="form-group">
@@ -27,7 +27,7 @@
                     </div>
                 </div>
             </fieldset>
-            <div class="pull-right form-actions">
+            <div class="pull-right form-actions" data-ng-show="access.manageApplications">
                 <button type="submit" data-ng-click="changePassword()" class="btn btn-primary btn-lg">Regenerate Secret
                 </button>
             </div>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-detail.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-detail.html
index be13612..f123d1c 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-detail.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-detail.html
@@ -23,7 +23,7 @@
             <li class="active">Settings</li>
         </ol>
         <h2 data-ng-hide="create"><span>{{application.name}}</span> Settings</h2>
-        <form class="form-horizontal" name="applicationForm" novalidate>
+        <form class="form-horizontal" name="applicationForm" novalidate kc-read-only="!access.manageApplications">
             <fieldset class="border-top">
                 <div class="form-group">
                     <label class="col-sm-2 control-label" for="name">Name <span class="required" data-ng-show="create">*</span></label>
@@ -108,11 +108,11 @@
                 </div>
             </fieldset>
 
-            <div class="pull-right form-actions" data-ng-show="create">
+            <div class="pull-right form-actions" data-ng-show="create && access.manageApplications">
                 <button kc-cancel data-ng-click="cancel()">Cancel</button>
                 <button kc-save data-ng-show="changed">Save</button>
             </div>
-            <div class="pull-right form-actions" data-ng-show="!create">
+            <div class="pull-right form-actions" data-ng-show="!create && access.manageApplications">
                 <button kc-reset data-ng-show="changed">Clear changes</button>
                 <button kc-save  data-ng-show="changed">Save</button>
                 <button kc-delete data-ng-click="remove()" data-ng-hide="changed">Delete</button>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-role-detail.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-role-detail.html
index 3f6437f..e103b12 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-role-detail.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-role-detail.html
@@ -29,7 +29,7 @@
         <h2 data-ng-hide="create"><span>{{application.name}}</span> {{role.name}}</h2>
         <h2 data-ng-show="create"><span>{{application.name}}</span> Add Role</h2>
 
-        <form class="form-horizontal" name="realmForm" novalidate>
+        <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageApplications">
             <span class="fieldset-notice"><span class="required">*</span> Required fields</span>
 
             <fieldset class="border-top">
@@ -134,11 +134,11 @@
                 </div>
             </fieldset>
 
-            <div class="pull-right form-actions" data-ng-show="create">
+            <div class="pull-right form-actions" data-ng-show="create && access.manageApplications">
                 <button kc-cancel data-ng-click="cancel()">Cancel</button>
                 <button kc-save data-ng-show="changed">Save</button>
             </div>
-            <div class="pull-right form-actions" data-ng-show="!create">
+            <div class="pull-right form-actions" data-ng-show="!create && access.manageApplications">
                 <button kc-reset data-ng-show="changed">Clear changes</button>
                 <button kc-save  data-ng-show="changed">Save</button>
                 <button kc-delete data-ng-click="remove()" data-ng-hide="changed">Delete</button>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-role-list.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-role-list.html
index f6031f2..087d11d 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-role-list.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-role-list.html
@@ -21,7 +21,7 @@
         <table class="table">
             <thead>
             <tr>
-                <th class="kc-table-actions" colspan="3">
+                <th class="kc-table-actions" colspan="3" data-ng-show="access.manageApplications">
                     <div class="pull-right">
                         <a class="btn btn-primary" href="#/create/role/{{realm.realm}}/applications/{{application.name}}">Add Role</a>
                         <!-- <button class="remove disabled">Remove</button> -->
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-scope-mappings.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-scope-mappings.html
index 9432d99..865f9d6 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-scope-mappings.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-scope-mappings.html
@@ -19,7 +19,7 @@
         </ol>
         <h2><span>{{application.name}}</span> Scope Mappings</h2>
         <p class="subtitle"></p>
-        <form class="form-horizontal" name="realmForm" novalidate>
+        <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageApplications">
             <fieldset>
                 <legend><span class="text">Realm Roles</span></legend>
                 <div class="form-group col-sm-10">
@@ -59,7 +59,7 @@
                     <div class="col-sm-4">
                         <div class="input-group">
                             <div class="select-kc">
-                                <select id="applications" name="applications" ng-change="changeApplication()" ng-model="targetApp" ng-options="a.name for a in (applications|remove:application:'id')">
+                                <select id="applications" name="applications" ng-change="changeApplication()" ng-model="targetApp" ng-options="a.name for a in (applications|remove:application:'id')" ng-disabled="false">
                                     <option value="" selected> Select an Application </option>
                                 </select>
                             </div>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-credentials.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-credentials.html
index 03ad7f7..f931492 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-credentials.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-credentials.html
@@ -15,7 +15,7 @@
             <li class="active">Credentials</li>
         </ol>
         <h2 data-ng-hide="create"><span>{{oauth.name}}</span> Credentials</h2>
-        <form class="form-horizontal" name="credentialForm" novalidate>
+        <form class="form-horizontal" name="credentialForm" novalidate kc-read-only="!access.manageClients">
             <fieldset >
                 <legend><span class="text">Client Secret</span></legend>
                 <div class="form-group">
@@ -26,7 +26,7 @@
                     </div>
                 </div>
             </fieldset>
-            <div class="pull-right form-actions">
+            <div class="pull-right form-actions" data-ng-show="access.manageClients">
                 <button type="submit" data-ng-click="changePassword()" class="btn btn-primary btn-lg">Regenerate Secret
                 </button>
             </div>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-detail.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-detail.html
index 7ac2ed7..01e1835 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-detail.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-detail.html
@@ -21,7 +21,7 @@
             <li class="active">Settings</li>
         </ol>
         <h2 data-ng-hide="create"><span>{{oauth.name}}</span> Settings</h2>
-        <form class="form-horizontal" name="oauthForm" novalidate>
+        <form class="form-horizontal" name="oauthForm" novalidate kc-read-only="!access.manageClients">
             <fieldset class="border-top">
 
                 <div class="form-group">
@@ -90,11 +90,11 @@
                 </div>
             </fieldset>
 
-            <div class="pull-right form-actions" data-ng-show="create">
+            <div class="pull-right form-actions" data-ng-show="create && access.manageClients">
                 <button kc-cancel data-ng-click="cancel()">Cancel</button>
                 <button kc-save data-ng-show="changed">Save</button>
             </div>
-            <div class="pull-right form-actions" data-ng-show="!create">
+            <div class="pull-right form-actions" data-ng-show="!create && access.manageClients">
                 <button kc-reset data-ng-show="changed">Clear changes</button>
                 <button kc-save  data-ng-show="changed">Save</button>
                 <button kc-delete data-ng-click="remove()" data-ng-hide="changed">Delete</button>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-scope-mappings.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-scope-mappings.html
index 111a98c..424fab2 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-scope-mappings.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-scope-mappings.html
@@ -17,7 +17,7 @@
         </ol>
         <h2><span>{{oauth.name}}</span> Scope Mappings</h2>
         <p class="subtitle"></p>
-        <form class="form-horizontal" name="realmForm" novalidate>
+        <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageClients">
             <fieldset>
                 <legend><span class="text">Realm Roles</span></legend>
                 <div class="form-group col-sm-10">
@@ -57,7 +57,7 @@
                     <div class="col-sm-4">
                         <div class="input-group">
                             <div class="select-kc">
-                                <select id="applications" name="applications" ng-change="changeApplication()" ng-model="targetApp" ng-options="a.name for a in (applications)">
+                                <select id="applications" name="applications" ng-change="changeApplication()" ng-model="targetApp" ng-options="a.name for a in (applications)" ng-disabled="false">
                                     <option value="" selected> Select an Application </option>
                                 </select>
                             </div>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-credentials.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-credentials.html
index aad2f6d..0a595cd 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-credentials.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-credentials.html
@@ -9,9 +9,9 @@
             <li class="active">Required Credentials</li>
         </ol>
         <h2><span>{{realm.realm}}</span> Credentials</h2>
-        <form class="form-horizontal" name="realmForm" novalidate>
+        <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm">
             <fieldset class="border-top">
-                <legend uncollapsed><span class="text">Realm Credentials Settings</span></legend>
+                <legend><span class="text">Realm Credentials Settings</span></legend>
                 <div class="form-group">
                     <label class="col-sm-2 control-label" for="user" class="control-label two-lines">Required User Credentials</label>
 
@@ -21,7 +21,7 @@
                 </div>
             </fieldset>
             <fieldset class="border-top">
-                <legend uncollapsed><span class="text">Realm Password Policy</span></legend>
+                <legend><span class="text">Realm Password Policy</span></legend>
                 <table class="table">
                     <caption class="hidden">Table of Password Policies</caption>
                     <thead>
@@ -63,7 +63,7 @@
                     </tbody>
                 </table>
             </fieldset>
-            <div class="pull-right form-actions">
+            <div class="pull-right form-actions" data-ng-show="access.manageRealm">
                 <button kc-reset data-ng-show="changed">Clear changes</button>
                 <button kc-save data-ng-show="changed">Save</button>
             </div>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-default-roles.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-default-roles.html
index 1dc2751..a947e30 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-default-roles.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-default-roles.html
@@ -8,7 +8,7 @@
             <li class="active">Registration</li>
         </ol>
         <h2><span>{{realm.realm}}</span> Default Roles</h2>
-        <form class="form-horizontal" name="realmForm" novalidate>
+        <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm">
             <fieldset>
                 <legend><span class="text">Realm Default Roles</span> </legend>
                 <div class="form-group">
@@ -48,7 +48,7 @@
                     <div class="col-sm-4">
                         <div class="input-group">
                             <div class="select-kc">
-                                <select id="applications" name="applications" ng-change="changeApplication()" ng-model="application" ng-options="a.name for a in applications">
+                                <select id="applications" name="applications" ng-change="changeApplication()" ng-model="application" ng-options="a.name for a in applications" ng-disabled="false">
                                     <option value="" selected> Select an Application...</option>
                                 </select>
                             </div>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-detail.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-detail.html
index 055231c..4fa18c0 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-detail.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-detail.html
@@ -7,11 +7,11 @@
             <li><a href="#/realms/{{realm.realm}}">Settings</a></li>
             <li class="active">General</li>
         </ol>
-        <div data-ng-show="access.manageRealm">
+        <div data-ng-show="access.viewRealm">
             <h2 class="pull-left" data-ng-show="createRealm">Add Realm</h2>
             <h2 data-ng-hide="createRealm"><span>{{realm.realm}}</span> General Settings</h2>
             <p class="subtitle" data-ng-show="createRealm"><span class="required">*</span> Required fields</p>
-            <form class="form-horizontal" name="realmForm" novalidate>
+            <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm">
                 <fieldset>
                     <legend class="aj-collapse open"><span class="text">Required Settings</span></legend>
                     <div class="form-group">
@@ -91,18 +91,18 @@
                     </div>
                 </fieldset>
 
-                <div class="pull-right form-actions" data-ng-show="createRealm">
+                <div class="pull-right form-actions" data-ng-show="createRealm && access.manageRealm">
                     <button kc-cancel data-ng-click="cancel()">Cancel</button>
                     <button kc-save data-ng-show="changed">Save</button>
                 </div>
-                <div class="pull-right form-actions" data-ng-show="!createRealm">
+                <div class="pull-right form-actions" data-ng-show="!createRealm && access.manageRealm">
                     <button kc-reset data-ng-show="changed">Clear changes</button>
                     <button kc-save  data-ng-show="changed">Save</button>
                     <button kc-delete data-ng-click="remove()" data-ng-hide="changed">Delete</button>
                 </div>
             </form>
         </div>
-        <div data-ng-hide="access.manageRealm">
+        <div data-ng-hide="access.viewRealm">
             <h2 ><span>{{realm.realm}}</span></h2>
         </div>
 
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-keys.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-keys.html
index 0f96867..d471df6 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-keys.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-keys.html
@@ -8,7 +8,7 @@
             <li class="active">Keys</li>
         </ol>
         <h2><span>{{realm.realm}}</span> Keys</h2>
-        <form class="form-horizontal" name="realmForm" novalidate>
+        <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm">
             <fieldset class="border-top">
                 <div class="form-group">
                     <label class="col-sm-2 control-label" for="publicKey">Public key</label>
@@ -19,7 +19,7 @@
                     </div>
                 </div>
             </fieldset>
-            <div class="pull-right form-actions">
+            <div class="pull-right form-actions" data-ng-show="access.manageRealm">
                 <button class="btn btn-primary btn-lg" type="submit" data-ng-click="generate()">Generate new keys</button>
             </div>
         </form>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-menu.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-menu.html
index 95c7068..10ac577 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-menu.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-menu.html
@@ -1,9 +1,9 @@
 <ul data-ng-hide="createRealm">
-    <li data-ng-show="access.manageRealm" data-ng-class="((!path[2] || path[1] == 'role' || path[2] == 'roles' || path[2] == 'token-settings' ||
+    <li data-ng-show="access.viewRealm" data-ng-class="((!path[2] || path[1] == 'role' || path[2] == 'roles' || path[2] == 'token-settings' ||
     path[2] == 'social-settings' || path[2] == 'required-credentials' || path[2] == 'default-roles' || path[2] == 'registration-settings' ||
     path[2] == 'keys-settings' || path[2] == 'smtp-settings') && path[3] != 'applications') && 'active'"><a href="#/realms/{{realm.realm}}">Settings</a></li>
-    <li data-ng-show="access.manageUsers" data-ng-class="(path[2] == 'users' || path[1] == 'user') && 'active'"><a href="#/realms/{{realm.realm}}/users">Users</a>
+    <li data-ng-show="access.viewUsers" data-ng-class="(path[2] == 'users' || path[1] == 'user') && 'active'"><a href="#/realms/{{realm.realm}}/users">Users</a>
     </li>
-    <li data-ng-show="access.manageApplications" data-ng-class="(path[2] == 'applications' || path[1] == 'application' || path[3] == 'applications') && 'active'"><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
-    <li data-ng-show="access.manageClients" data-ng-class="(path[2] == 'oauth-clients' || path[1] == 'oauth-client') && 'active'"><a href="#/realms/{{realm.realm}}/oauth-clients">OAuth Clients</a></li>
+    <li data-ng-show="access.viewApplications" data-ng-class="(path[2] == 'applications' || path[1] == 'application' || path[3] == 'applications') && 'active'"><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
+    <li data-ng-show="access.viewClients" data-ng-class="(path[2] == 'oauth-clients' || path[1] == 'oauth-client') && 'active'"><a href="#/realms/{{realm.realm}}/oauth-clients">OAuth Clients</a></li>
 </ul>
\ No newline at end of file
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-smtp.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-smtp.html
index cba699a..e03dc51 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-smtp.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-smtp.html
@@ -8,10 +8,10 @@
             <li class="active">SMTP Configuration</li>
         </ol>
         <h2><span>{{realm.realm}}</span> Email Server Settings</h2>
-        <form class="form-horizontal" name="realmForm" novalidate>
+        <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm">
             <span class="fieldset-notice"><span class="required">*</span> Required fields</span>
             <fieldset>
-                <legend uncollapsed><span class="text">Required Settings</span></legend>
+                <legend><span class="text">Required Settings</span></legend>
                 <div class="form-group clearfix">
                     <label class="col-sm-2 control-label" for="smtpHost">Host <span class="required">*</span></label>
                     <div class="col-sm-4">
@@ -44,7 +44,7 @@
                 </div>
             </fieldset>
             <fieldset>
-                <legend uncollapsed><span class="text">Authentication</span></legend>
+                <legend><span class="text">Authentication</span></legend>
                 <div class="form-group clearfix">
                     <label class="col-sm-2 control-label" for="smtpAuth">Enable Authentication</label>
                     <div class="col-sm-4">
@@ -65,7 +65,7 @@
                 </div>
             </fieldset>
 
-            <div class="pull-right form-actions">
+            <div class="pull-right form-actions" data-ng-show="access.manageRealm">
                 <button data-kc-reset data-ng-show="changed">Clear changes</button>
                 <button data-kc-save data-ng-show="changed">Save</button>
             </div>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-tokens.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-tokens.html
index ac83d09..7dc96e6 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-tokens.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-tokens.html
@@ -8,7 +8,7 @@
             <li class="active">Token</li>
         </ol>
         <h2><span>{{realm.realm}}</span> Token Settings</h2>
-        <form class="form-horizontal" name="realmForm" novalidate>
+        <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm">
             <fieldset class="border-top">
                 <div class="form-group">
                     <label class="col-sm-2 control-label" for="rememberMe">Remember Me</label>
@@ -113,7 +113,7 @@
                     </div>
                 </div>
             </fieldset>
-            <div class="pull-right form-actions">
+            <div class="pull-right form-actions" data-ng-show="access.manageRealm">
                 <button kc-reset data-ng-show="changed">Clear changes</button>
                 <button kc-save data-ng-show="changed">Save</button>
             </div>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-detail.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-detail.html
index cb65d93..fc25f41 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-detail.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-detail.html
@@ -28,7 +28,7 @@
         </ol>
         <h2 data-ng-show="create"><span>{{realm.realm}}</span> Add Role</h2>
         <p class="subtitle" data-ng-show="create"><span class="required">*</span> Required fields</p>
-        <form class="form-horizontal" name="realmForm" novalidate>
+        <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm">
             <fieldset>
                 <div class="form-group">
                     <label class="col-sm-2 control-label" for="name">Role name <span class="required" data-ng-show="create">*</span></label>
@@ -96,7 +96,7 @@
                     <div class="col-sm-4">
                         <div class="input-group">
                             <div class="select-kc">
-                                <select id="applications" name="applications" ng-change="changeApplication()" ng-model="compositeApp" ng-options="a.name for a in applications">
+                                <select id="applications" name="applications" ng-change="changeApplication()" ng-model="compositeApp" ng-options="a.name for a in applications" ng-disabled="false">
                                     <option value="" selected> Select an Application...</option>
                                 </select>
                             </div>
@@ -133,7 +133,7 @@
                 </div>
             </fieldset>
 
-            <div class="pull-right  form-actions" data-ng-show="!create">
+            <div class="pull-right  form-actions" data-ng-show="!create && access.manageRealm">
                 <button kc-reset data-ng-show="changed">Clear changes</button>
                 <button kc-save data-ng-show="changed">Save</button>
                 <button kc-delete data-ng-click="remove()" data-ng-hide="changed">Delete</button>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-list.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-list.html
index e3a6ae3..e0062e0 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-list.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-list.html
@@ -13,7 +13,7 @@
             <table class="table">
                 <thead>
                 <tr>
-                    <th class="kc-table-actions" colspan="3">
+                    <th class="kc-table-actions" colspan="3" data-ng-show="access.manageRealm">
                         <div class="pull-right">
                             <a class="btn btn-primary" href="#/create/role/{{realm.realm}}">Add Role</a>
                             <!-- <button class="remove disabled">Remove</button> -->
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-mappings.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-mappings.html
index 0e61d1a..c290d7a 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-mappings.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-mappings.html
@@ -2,7 +2,7 @@
 <div id="content-area" class="col-md-9" role="main">
     <ul class="nav nav-tabs nav-tabs-pf"  data-ng-show="!create">
         <li><a href="#/realms/{{realm.realm}}/users/{{user.username}}">Attributes</a></li>
-        <li><a href="#/realms/{{realm.realm}}/users/{{user.username}}/user-credentials">Credentials</a></li>
+        <li data-ng-show="access.manageUsers"><a href="#/realms/{{realm.realm}}/users/{{user.username}}/user-credentials">Credentials</a></li>
         <li class="active"><a href="#/realms/{{realm.realm}}/users/{{user.username}}/role-mappings">Role Mappings</a></li>
     </ul>
     <div id="content">
@@ -13,7 +13,7 @@
             <li class="active">Role Mappings</li>
         </ol>
         <h2><span>{{user.username}}'s</span> Role Mappings</h2>
-        <form class="form-horizontal" name="realmForm" novalidate>
+        <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageUsers">
 
             <fieldset>
                 <legend><span class="text">Realm Roles</span> </legend>
@@ -54,7 +54,7 @@
                     <div class="col-sm-4">
                         <div class="input-group">
                             <div class="select-kc">
-                                <select id="applications" name="applications" ng-change="changeApplication()" ng-model="application" ng-options="a.name for a in applications">
+                                <select id="applications" name="applications" ng-change="changeApplication()" ng-model="application" ng-options="a.name for a in applications" ng-disabled="false">
                                     <option value="" selected> Select an Application...</option>
                                 </select>
                             </div>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/user-detail.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/user-detail.html
index c258661..4ce093a 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/user-detail.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/user-detail.html
@@ -3,7 +3,7 @@
 
     <ul class="nav nav-tabs nav-tabs-pf" data-ng-show="!create">
         <li class="active"><a href="#/realms/{{realm.realm}}/users/{{user.username}}">Attributes</a></li>
-        <li><a href="#/realms/{{realm.realm}}/users/{{user.username}}/user-credentials">Credentials</a></li>
+        <li data-ng-show="access.manageUsers"><a href="#/realms/{{realm.realm}}/users/{{user.username}}/user-credentials">Credentials</a></li>
         <li><a href="#/realms/{{realm.realm}}/users/{{user.username}}/role-mappings">Role Mappings</a></li>
     </ul>
 
@@ -22,7 +22,7 @@
         </ol>
         <h2 data-ng-hide="create"><span>{{user.username}}'s</span> Attributes</h2>
 
-        <form class="form-horizontal" name="userForm" novalidate>
+        <form class="form-horizontal" name="userForm" novalidate kc-read-only="!access.manageUsers">
             <span class="fieldset-notice"><span class="required">*</span> Required fields</span>
             <fieldset class="border-top">
                 <div class="form-group">
@@ -79,12 +79,12 @@
                     </div>
                 </div>
             </fieldset>
-            <div class="pull-right form-actions" data-ng-show="create">
+            <div class="pull-right form-actions" data-ng-show="create && access.manageUsers">
                 <button kc-cancel data-ng-click="cancel()">Cancel</button>
                 <button kc-save data-ng-show="changed">Save</button>
             </div>
 
-            <div class="pull-right form-actions" data-ng-show="!create">
+            <div class="pull-right form-actions" data-ng-show="!create && access.manageUsers">
                 <button kc-reset data-ng-show="changed">Clear changes</button>
                 <button kc-save  data-ng-show="changed">Save</button>
                 <button kc-delete data-ng-click="remove()" data-ng-hide="changed">Delete</button>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/templates/kc-navigation.html b/admin-ui/src/main/resources/META-INF/resources/admin/templates/kc-navigation.html
index 715a3a7..307aab6 100644
--- a/admin-ui/src/main/resources/META-INF/resources/admin/templates/kc-navigation.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/templates/kc-navigation.html
@@ -1,10 +1,10 @@
 <ul class="nav nav-tabs nav-tabs-pf">
     <li ng-class="{active: !path[2]}"><a href="#/realms/{{realm.realm}}">General</a></li>
-    <li ng-class="{active: path[2] == 'social'}" data-ng-show="kcSocial && auth.hasAccess(realm.realm, 'manage-realm')"><a href="#/realms/{{realm.realm}}/social-settings">Social</a></li>
-    <li ng-class="{active: path[2] == 'roles'}" data-ng-show="access.manageRealm"><a href="#/realms/{{realm.realm}}/roles">Roles</a></li>
-    <li ng-class="{active: path[2] == 'default-roles'}" data-ng-show="access.manageRealm"><a href="#/realms/{{realm.realm}}/default-roles">Default Roles</a></li>
-    <li ng-class="{active: path[2] == 'required-credentials'}" data-ng-show="access.manageRealm"><a href="#/realms/{{realm.realm}}/required-credentials">Credentials</a></li>
-    <li ng-class="{active: path[2] == 'token-settings'}" data-ng-show="access.manageRealm"><a href="#/realms/{{realm.realm}}/token-settings">Token</a></li>
-    <li ng-class="{active: path[2] == 'keys-settings'}" data-ng-show="access.manageRealm"><a href="#/realms/{{realm.realm}}/keys-settings">Keys</a></li>
-    <li ng-class="{active: path[2] == 'smtp-settings'}" data-ng-show="access.manageRealm"><a href="#/realms/{{realm.realm}}/smtp-settings">Email</a></li>
+    <li ng-class="{active: path[2] == 'social'}" data-ng-show="kcSocial && access.viewRealm"><a href="#/realms/{{realm.realm}}/social-settings">Social</a></li>
+    <li ng-class="{active: path[2] == 'roles'}" data-ng-show="access.viewRealm"><a href="#/realms/{{realm.realm}}/roles">Roles</a></li>
+    <li ng-class="{active: path[2] == 'default-roles'}" data-ng-show="access.viewRealm"><a href="#/realms/{{realm.realm}}/default-roles">Default Roles</a></li>
+    <li ng-class="{active: path[2] == 'required-credentials'}" data-ng-show="access.viewRealm"><a href="#/realms/{{realm.realm}}/required-credentials">Credentials</a></li>
+    <li ng-class="{active: path[2] == 'token-settings'}" data-ng-show="access.viewRealm"><a href="#/realms/{{realm.realm}}/token-settings">Token</a></li>
+    <li ng-class="{active: path[2] == 'keys-settings'}" data-ng-show="access.viewRealm"><a href="#/realms/{{realm.realm}}/keys-settings">Keys</a></li>
+    <li ng-class="{active: path[2] == 'smtp-settings'}" data-ng-show="access.viewRealm"><a href="#/realms/{{realm.realm}}/smtp-settings">Email</a></li>
 </ul>
\ No newline at end of file
diff --git a/model/api/src/main/java/org/keycloak/models/AdminRoles.java b/model/api/src/main/java/org/keycloak/models/AdminRoles.java
index ab414bf..a156be7 100644
--- a/model/api/src/main/java/org/keycloak/models/AdminRoles.java
+++ b/model/api/src/main/java/org/keycloak/models/AdminRoles.java
@@ -9,12 +9,17 @@ public class AdminRoles {
 
     public static String ADMIN = "admin";
 
+    public static String VIEW_REALM = "view-realm";
+    public static String VIEW_USERS = "view-users";
+    public static String VIEW_APPLICATIONS = "view-applications";
+    public static String VIEW_CLIENTS = "view-clients";
+
     public static String MANAGE_REALM = "manage-realm";
     public static String MANAGE_USERS = "manage-users";
     public static String MANAGE_APPLICATIONS = "manage-applications";
     public static String MANAGE_CLIENTS = "manage-clients";
 
-    public static String[] ALL_REALM_ROLES = {MANAGE_REALM, MANAGE_USERS, MANAGE_APPLICATIONS, MANAGE_CLIENTS};
+    public static String[] ALL_REALM_ROLES = {VIEW_REALM, VIEW_USERS, VIEW_APPLICATIONS, VIEW_CLIENTS, MANAGE_REALM, MANAGE_USERS, MANAGE_APPLICATIONS, MANAGE_CLIENTS};
 
     public static String getAdminApp(RealmModel realm) {
         return realm.getName() + APP_SUFFIX;
diff --git a/services/src/main/java/org/keycloak/services/managers/Auth.java b/services/src/main/java/org/keycloak/services/managers/Auth.java
index 3a2b21c..6bc8628 100644
--- a/services/src/main/java/org/keycloak/services/managers/Auth.java
+++ b/services/src/main/java/org/keycloak/services/managers/Auth.java
@@ -1,23 +1,14 @@
 package org.keycloak.services.managers;
 
-import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.Constants;
 import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.representations.AccessToken;
 
-import javax.ws.rs.ForbiddenException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
 /**
 * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
 */
 public class Auth {
+
     private final boolean cookie;
     private final RealmModel realm;
     private final AccessToken token;
@@ -62,77 +53,40 @@ public class Auth {
         return token;
     }
 
-    public void require(String role) {
-        if (!has(role)) {
-            throw new ForbiddenException();
-        }
-    }
-
-    public void require(String app, String role) {
-        if (!has(app, role)) {
-            throw new ForbiddenException();
-        }
-    }
-
-    public void require(ApplicationModel app, String role) {
-        if (!has(app, role)) {
-            throw new ForbiddenException();
-        }
-    }
-
-    public void requireOneOf(String app, String... roles) {
-        if(!hasOneOf(app, roles)) {
-            throw new ForbiddenException();
-        }
-    }
-
-    public void requireOneOf(ApplicationModel app, String... roles) {
-        if(!hasOneOf(app, roles)) {
-            throw new ForbiddenException();
-        }
-    }
-
-    public boolean has(String role) {
-        if (cookie)  {
+    public boolean hasRealmRole(String role) {
+        if (cookie) {
             return realm.hasRole(user, realm.getRole(role));
         } else {
-            return token.getRealmAccess() != null && token.getRealmAccess().isUserInRole(role);
+            AccessToken.Access access = token.getRealmAccess();
+            return access != null && access.isUserInRole(role);
         }
     }
 
-    public boolean has(String app, String role) {
-        if (cookie) {
-            return realm.hasRole(user, realm.getApplicationByName(app).getRole(role));
-        } else {
-            AccessToken.Access access = token.getResourceAccess(app);
-            return access != null && access.isUserInRole(role);
+    public boolean hasOneOfRealmRole(String... roles) {
+        for (String r : roles) {
+            if (hasRealmRole(r)) {
+                return true;
+            }
         }
+        return false;
     }
 
-    public boolean has(ApplicationModel app, String role) {
+    public boolean hasAppRole(String app, String role) {
         if (cookie) {
-            return realm.hasRole(user, app.getRole(role));
+            return realm.hasRole(user, realm.getApplicationByName(app).getRole(role));
         } else {
-            AccessToken.Access access = token.getResourceAccess(app.getName());
+            AccessToken.Access access = token.getResourceAccess(app);
             return access != null && access.isUserInRole(role);
         }
     }
 
-    public boolean hasOneOf(String app, String... roles) {
+    public boolean hasOneOfAppRole(String app, String... roles) {
         for (String r : roles) {
-            if (has(app, r)) {
+            if (hasAppRole(app, r)) {
                 return true;
             }
         }
         return false;
     }
 
-    public boolean hasOneOf(ApplicationModel app, String... roles) {
-        for (String r : roles) {
-            if (has(app, r)) {
-                return true;
-            }
-        }
-        return false;
-    }
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/AccountService.java b/services/src/main/java/org/keycloak/services/resources/AccountService.java
index 407d2c9..a3afea9 100755
--- a/services/src/main/java/org/keycloak/services/resources/AccountService.java
+++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java
@@ -81,7 +81,7 @@ public class AccountService {
         Auth auth = getAuth(false);
         if (auth != null) {
             try {
-                auth.require(application, AccountRoles.MANAGE_ACCOUNT);
+                require(auth, AccountRoles.MANAGE_ACCOUNT);
             } catch (ForbiddenException e) {
                 return Flows.forms(realm, request, uriInfo).setError("No access").createErrorPage();
             }
@@ -113,7 +113,7 @@ public class AccountService {
             return forwardToPage(null, AccountPages.ACCOUNT);
         } else if (types.contains(MediaType.APPLICATION_JSON_TYPE)) {
             Auth auth = getAuth(true);
-            auth.requireOneOf(application, AccountRoles.MANAGE_ACCOUNT, AccountRoles.VIEW_PROFILE);
+            requireOneOf(auth, AccountRoles.MANAGE_ACCOUNT, AccountRoles.VIEW_PROFILE);
 
             return Cors.add(request, Response.ok(ModelToRepresentation.toRepresentation(auth.getUser()))).auth().allowedOrigins(auth.getClient()).build();
         } else {
@@ -138,7 +138,7 @@ public class AccountService {
     @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
     public Response processAccountUpdate(final MultivaluedMap<String, String> formData) {
         Auth auth = getAuth(true);
-        auth.require(application, AccountRoles.MANAGE_ACCOUNT);
+        require(auth, AccountRoles.MANAGE_ACCOUNT);
 
         UserModel user = auth.getUser();
 
@@ -160,7 +160,7 @@ public class AccountService {
     @GET
     public Response processTotpRemove() {
         Auth auth = getAuth(true);
-        auth.require(application, AccountRoles.MANAGE_ACCOUNT);
+        require(auth, AccountRoles.MANAGE_ACCOUNT);
 
         UserModel user = auth.getUser();
         user.setTotp(false);
@@ -174,7 +174,7 @@ public class AccountService {
     @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
     public Response processTotpUpdate(final MultivaluedMap<String, String> formData) {
         Auth auth = getAuth(true);
-        auth.require(application, AccountRoles.MANAGE_ACCOUNT);
+        require(auth, AccountRoles.MANAGE_ACCOUNT);
 
         UserModel user = auth.getUser();
 
@@ -204,7 +204,7 @@ public class AccountService {
     @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
     public Response processPasswordUpdate(final MultivaluedMap<String, String> formData) {
         Auth auth = getAuth(true);
-        auth.require(application, AccountRoles.MANAGE_ACCOUNT);
+        require(auth, AccountRoles.MANAGE_ACCOUNT);
 
         UserModel user = auth.getUser();
 
@@ -345,4 +345,16 @@ public class AccountService {
         return null;
     }
 
+    public void require(Auth auth, String role) {
+        if (!auth.hasAppRole(application.getName(), role)) {
+            throw new ForbiddenException();
+        }
+    }
+
+    public void requireOneOf(Auth auth, String... roles) {
+        if (!auth.hasOneOfAppRole(application.getName(), roles)) {
+            throw new ForbiddenException();
+        }
+    }
+
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AdminService.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminService.java
index 7a5719a..7a3fad1 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/AdminService.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminService.java
@@ -234,6 +234,7 @@ public class AdminService {
         if (auth == null) {
             throw new NotAuthorizedException("Bearer");
         }
+
         RealmsAdminResource adminResource = new RealmsAdminResource(auth, tokenManager);
         resourceContext.initResource(adminResource);
         return adminResource;
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
index 3fa6d1b..92c1845 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
@@ -34,9 +34,10 @@ import java.util.Set;
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
  */
-public class ApplicationResource extends RoleContainerResource {
+public class ApplicationResource {
     protected static final Logger logger = Logger.getLogger(RealmAdminResource.class);
     protected RealmModel realm;
+    private RealmAuth auth;
     protected ApplicationModel application;
     protected KeycloakSession session;
     @Context
@@ -49,16 +50,20 @@ public class ApplicationResource extends RoleContainerResource {
         return (KeycloakApplication)keycloak;
     }
 
-    public ApplicationResource(RealmModel realm, ApplicationModel applicationModel, KeycloakSession session) {
-        super(realm, applicationModel);
+    public ApplicationResource(RealmModel realm, RealmAuth auth, ApplicationModel applicationModel, KeycloakSession session) {
         this.realm = realm;
+        this.auth = auth;
         this.application = applicationModel;
         this.session = session;
+
+        auth.init(RealmAuth.Resource.APPLICATION);
     }
 
     @PUT
     @Consumes(MediaType.APPLICATION_JSON)
     public void update(final ApplicationRepresentation rep) {
+        auth.requireManage();
+
         ApplicationManager applicationManager = new ApplicationManager(new RealmManager(session));
         applicationManager.updateApplication(rep, application);
     }
@@ -68,6 +73,8 @@ public class ApplicationResource extends RoleContainerResource {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public ApplicationRepresentation getApplication() {
+        auth.requireView();
+
         ApplicationManager applicationManager = new ApplicationManager(new RealmManager(session));
         return applicationManager.toRepresentation(application);
     }
@@ -78,6 +85,8 @@ public class ApplicationResource extends RoleContainerResource {
     @Path("installation/json")
     @Produces(MediaType.APPLICATION_JSON)
     public String getInstallation() throws IOException {
+        auth.requireView();
+
         ApplicationManager applicationManager = new ApplicationManager(new RealmManager(session));
         Object rep = applicationManager.toInstallationRepresentation(realm, application, getKeycloakApplication().getBaseUri(uriInfo));
 
@@ -90,6 +99,8 @@ public class ApplicationResource extends RoleContainerResource {
     @Path("installation/jboss")
     @Produces(MediaType.TEXT_PLAIN)
     public String getJBossInstallation() throws IOException {
+        auth.requireView();
+
         ApplicationManager applicationManager = new ApplicationManager(new RealmManager(session));
         return applicationManager.toJBossSubsystemConfig(realm, application, getKeycloakApplication().getBaseUri(uriInfo));
     }
@@ -97,6 +108,8 @@ public class ApplicationResource extends RoleContainerResource {
     @DELETE
     @NoCache
     public void deleteApplication() {
+        auth.requireManage();
+
         realm.removeApplication(application.getId());
     }
 
@@ -105,6 +118,8 @@ public class ApplicationResource extends RoleContainerResource {
     @Produces("application/json")
     @Consumes("application/json")
     public CredentialRepresentation regenerateSecret() {
+        auth.requireManage();
+
         logger.debug("regenerateSecret");
         UserCredentialModel cred = new ApplicationManager().generateSecret(realm, application);
         CredentialRepresentation rep = ModelToRepresentation.toRepresentation(cred);
@@ -115,6 +130,8 @@ public class ApplicationResource extends RoleContainerResource {
     @GET
     @Produces("application/json")
     public CredentialRepresentation getClientSecret() {
+        auth.requireView();
+
         logger.debug("getClientSecret");
         UserCredentialModel model = realm.getSecret(application.getApplicationUser());
         if (model == null) throw new NotFoundException("Application does not have a secret");
@@ -124,7 +141,12 @@ public class ApplicationResource extends RoleContainerResource {
 
     @Path("scope-mappings")
     public ScopeMappedResource getScopeMappedResource() {
-        return new ScopeMappedResource(realm, application.getApplicationUser(), session);
+        return new ScopeMappedResource(realm, auth, application.getApplicationUser(), session);
+    }
+
+    @Path("roles")
+    public RoleContainerResource getRoleContainerResource() {
+        return new RoleContainerResource(realm, auth, application);
     }
 
     @Path("allowed-origins")
@@ -132,6 +154,8 @@ public class ApplicationResource extends RoleContainerResource {
     @Produces("application/json")
     public Set<String> getAllowedOrigins()
     {
+        auth.requireView();
+
         return application.getApplicationUser().getWebOrigins();
     }
 
@@ -140,6 +164,8 @@ public class ApplicationResource extends RoleContainerResource {
     @Consumes("application/json")
     public void updateAllowedOrigins(Set<String> allowedOrigins)
     {
+        auth.requireManage();
+
         application.getApplicationUser().setWebOrigins(allowedOrigins);
     }
 
@@ -148,6 +174,8 @@ public class ApplicationResource extends RoleContainerResource {
     @Consumes("application/json")
     public void deleteAllowedOrigins(Set<String> allowedOrigins)
     {
+        auth.requireManage();
+
         for (String origin : allowedOrigins) {
             application.getApplicationUser().removeWebOrigin(origin);
         }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java
index 4f9d5ca..6387e00 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java
@@ -32,6 +32,7 @@ import java.util.List;
 public class ApplicationsResource {
     protected static final Logger logger = Logger.getLogger(RealmAdminResource.class);
     protected RealmModel realm;
+    private RealmAuth auth;
 
     @Context
     protected ResourceContext resourceContext;
@@ -39,19 +40,32 @@ public class ApplicationsResource {
     @Context
     protected KeycloakSession session;
 
-    public ApplicationsResource(RealmModel realm) {
+    public ApplicationsResource(RealmModel realm, RealmAuth auth) {
         this.realm = realm;
+        this.auth = auth;
+
+        auth.init(RealmAuth.Resource.APPLICATION);
     }
 
     @GET
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
     public List<ApplicationRepresentation> getApplications() {
+        auth.requireAny();
+
         List<ApplicationRepresentation> rep = new ArrayList<ApplicationRepresentation>();
         List<ApplicationModel> applicationModels = realm.getApplications();
         ApplicationManager resourceManager = new ApplicationManager(new RealmManager(session));
+
+        boolean view = auth.hasView();
         for (ApplicationModel applicationModel : applicationModels) {
-            rep.add(resourceManager.toRepresentation(applicationModel));
+            if (view) {
+                rep.add(resourceManager.toRepresentation(applicationModel));
+            } else {
+                ApplicationRepresentation app = new ApplicationRepresentation();
+                app.setName(applicationModel.getName());
+                rep.add(app);
+            }
         }
         return rep;
     }
@@ -59,6 +73,8 @@ public class ApplicationsResource {
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
     public Response createApplication(final @Context UriInfo uriInfo, final ApplicationRepresentation rep) {
+        auth.requireManage();
+
         if (realm.getApplicationNameMap().containsKey(rep.getName())) {
             return Flows.errors().exists("Application " + rep.getName() + " already exists");
         }
@@ -73,7 +89,7 @@ public class ApplicationsResource {
         if (applicationModel == null) {
             throw new NotFoundException("Could not find application: " + name);
         }
-        ApplicationResource applicationResource = new ApplicationResource(realm, applicationModel, session);
+        ApplicationResource applicationResource = new ApplicationResource(realm, auth, applicationModel, session);
         resourceContext.initResource(applicationResource);
         return applicationResource;
     }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java
index 9bdc837..7ae8fe3 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java
@@ -38,6 +38,7 @@ import java.util.List;
 public class OAuthClientResource  {
     protected static final Logger logger = Logger.getLogger(RealmAdminResource.class);
     protected RealmModel realm;
+    private RealmAuth auth;
     protected OAuthClientModel oauthClient;
     protected KeycloakSession session;
     @Context
@@ -50,15 +51,20 @@ public class OAuthClientResource  {
         return (KeycloakApplication)application;
     }
 
-    public OAuthClientResource(RealmModel realm, OAuthClientModel oauthClient, KeycloakSession session) {
+    public OAuthClientResource(RealmModel realm, RealmAuth auth, OAuthClientModel oauthClient, KeycloakSession session) {
         this.realm = realm;
+        this.auth = auth;
         this.oauthClient = oauthClient;
         this.session = session;
+
+        auth.init(RealmAuth.Resource.CLIENT);
     }
 
     @PUT
     @Consumes(MediaType.APPLICATION_JSON)
     public void update(final OAuthClientRepresentation rep) {
+        auth.requireManage();
+
         OAuthClientManager manager = new OAuthClientManager(realm);
         manager.update(rep, oauthClient);
     }
@@ -68,6 +74,8 @@ public class OAuthClientResource  {
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
     public OAuthClientRepresentation getOAuthClient() {
+        auth.requireView();
+
         return OAuthClientManager.toRepresentation(oauthClient);
     }
 
@@ -76,6 +84,8 @@ public class OAuthClientResource  {
     @Path("installation")
     @Produces(MediaType.APPLICATION_JSON)
     public String getInstallation() throws IOException {
+        auth.requireView();
+
         OAuthClientManager manager = new OAuthClientManager(realm);
         Object rep = manager.toInstallationRepresentation(realm, oauthClient, getApplication().getBaseUri(uriInfo));
 
@@ -86,6 +96,8 @@ public class OAuthClientResource  {
     @DELETE
     @NoCache
     public void deleteOAuthClient() {
+        auth.requireManage();
+
         realm.removeOAuthClient(oauthClient.getId());
     }
 
@@ -94,6 +106,8 @@ public class OAuthClientResource  {
     @Produces("application/json")
     @Consumes("application/json")
     public CredentialRepresentation regenerateSecret() {
+        auth.requireManage();
+
         logger.debug("regenerateSecret");
         UserCredentialModel cred = UserCredentialModel.generateSecret();
         realm.updateCredential(oauthClient.getOAuthAgent(), cred);
@@ -105,6 +119,8 @@ public class OAuthClientResource  {
     @GET
     @Produces("application/json")
     public CredentialRepresentation getClientSecret() {
+        auth.requireView();
+
         logger.debug("getClientSecret");
         UserCredentialModel model = realm.getSecret(oauthClient.getOAuthAgent());
         if (model == null) throw new NotFoundException("Application does not have a secret");
@@ -113,7 +129,7 @@ public class OAuthClientResource  {
 
     @Path("scope-mappings")
     public ScopeMappedResource getScopeMappedResource() {
-        return new ScopeMappedResource(realm, oauthClient.getOAuthAgent(), session);
+        return new ScopeMappedResource(realm, auth, oauthClient.getOAuthAgent(), session);
     }
 
 
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java
index eaacae6..4456224 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java
@@ -35,10 +35,14 @@ public class OAuthClientsResource {
 
     @Context
     protected ResourceContext resourceContext;
+    private RealmAuth auth;
 
-    public OAuthClientsResource(RealmModel realm, KeycloakSession session) {
+    public OAuthClientsResource(RealmModel realm, RealmAuth auth, KeycloakSession session) {
+        this.auth = auth;
         this.realm = realm;
         this.session = session;
+
+        auth.init(RealmAuth.Resource.CLIENT);
     }
 
     @GET
@@ -47,8 +51,16 @@ public class OAuthClientsResource {
     public List<OAuthClientRepresentation> getOAuthClients() {
         List<OAuthClientRepresentation> rep = new ArrayList<OAuthClientRepresentation>();
         List<OAuthClientModel> oauthModels = realm.getOAuthClients();
+
+        boolean view = auth.hasView();
         for (OAuthClientModel oauth : oauthModels) {
-            rep.add(OAuthClientManager.toRepresentation(oauth));
+            if (view) {
+                rep.add(OAuthClientManager.toRepresentation(oauth));
+            } else {
+                OAuthClientRepresentation client = new OAuthClientRepresentation();
+                client.setName(oauth.getOAuthAgent().getLoginName());
+                rep.add(client);
+            }
         }
         return rep;
     }
@@ -56,6 +68,8 @@ public class OAuthClientsResource {
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
     public Response createOAuthClient(final @Context UriInfo uriInfo, final OAuthClientRepresentation rep) {
+        auth.requireManage();
+
         OAuthClientManager resourceManager = new OAuthClientManager(realm);
         OAuthClientModel oauth = resourceManager.create(rep);
         return Response.created(uriInfo.getAbsolutePathBuilder().path(oauth.getId()).build()).build();
@@ -63,11 +77,13 @@ public class OAuthClientsResource {
 
     @Path("{id}")
     public OAuthClientResource getOAuthClient(final @PathParam("id") String id) {
+        auth.requireView();
+
         OAuthClientModel oauth = realm.getOAuthClientById(id);
         if (oauth == null) {
             throw new NotFoundException();
         }
-        OAuthClientResource oAuthClientResource = new OAuthClientResource(realm, oauth, session);
+        OAuthClientResource oAuthClientResource = new OAuthClientResource(realm, auth, oauth, session);
         resourceContext.initResource(oAuthClientResource);
         return oAuthClientResource;
     }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
index 5ea0987..7f2f020 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
@@ -19,9 +19,9 @@ import javax.ws.rs.core.Context;
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
  */
-public class RealmAdminResource extends RoleContainerResource {
+public class RealmAdminResource {
     protected static final Logger logger = Logger.getLogger(RealmAdminResource.class);
-    protected Auth auth;
+    protected RealmAuth auth;
     protected RealmModel realm;
     private TokenManager tokenManager;
 
@@ -31,43 +31,43 @@ public class RealmAdminResource extends RoleContainerResource {
     @Context
     protected KeycloakSession session;
 
-    public RealmAdminResource(Auth auth, RealmModel realm, TokenManager tokenManager) {
-        super(realm, realm);
+    public RealmAdminResource(RealmAuth auth, RealmModel realm, TokenManager tokenManager) {
         this.auth = auth;
         this.realm = realm;
         this.tokenManager = tokenManager;
+
+        auth.init(RealmAuth.Resource.REALM);
     }
 
     @Path("applications")
     public ApplicationsResource getApplications() {
-        auth.require(AdminRoles.getAdminApp(realm), AdminRoles.MANAGE_APPLICATIONS);
-
-        ApplicationsResource applicationsResource = new ApplicationsResource(realm);
+        ApplicationsResource applicationsResource = new ApplicationsResource(realm, auth);
         resourceContext.initResource(applicationsResource);
         return applicationsResource;
     }
 
     @Path("oauth-clients")
     public OAuthClientsResource getOAuthClients() {
-        auth.require(AdminRoles.getAdminApp(realm), AdminRoles.MANAGE_CLIENTS);
-
-        OAuthClientsResource oauth = new OAuthClientsResource(realm, session);
+        OAuthClientsResource oauth = new OAuthClientsResource(realm, auth, session);
         resourceContext.initResource(oauth);
         return oauth;
     }
 
+    @Path("roles")
+    public RoleContainerResource getRoleContainerResource() {
+        return new RoleContainerResource(realm, auth, realm);
+    }
+
     @GET
     @NoCache
     @Produces("application/json")
     public RealmRepresentation getRealm() {
-        String realmAdminApp = AdminRoles.getAdminApp(realm);
-        if (auth.has(realmAdminApp, AdminRoles.MANAGE_REALM)) {
+        if (auth.hasView()) {
             return ModelToRepresentation.toRepresentation(realm);
         } else {
-            auth.requireOneOf(AdminRoles.getAdminApp(realm), AdminRoles.ALL_REALM_ROLES);
+            auth.requireAny();
 
             RealmRepresentation rep = new RealmRepresentation();
-            rep.setId(realm.getId());
             rep.setRealm(realm.getName());
 
             return rep;
@@ -77,15 +77,15 @@ public class RealmAdminResource extends RoleContainerResource {
     @PUT
     @Consumes("application/json")
     public void updateRealm(final RealmRepresentation rep) {
-        auth.require(AdminRoles.getAdminApp(realm), AdminRoles.MANAGE_REALM);
+        auth.requireManage();
 
         logger.debug("updating realm: " + realm.getName());
         new RealmManager(session).updateRealm(rep, realm);
     }
 
     @DELETE
-    public void deleteRealms() {
-        auth.require(AdminRoles.getAdminApp(realm), AdminRoles.MANAGE_REALM);
+    public void deleteRealm() {
+        auth.requireManage();
 
         if (!new RealmManager(session).removeRealm(realm)) {
             throw new NotFoundException();
@@ -94,18 +94,14 @@ public class RealmAdminResource extends RoleContainerResource {
 
     @Path("users")
     public UsersResource users() {
-        auth.require(AdminRoles.getAdminApp(realm), AdminRoles.MANAGE_USERS);
-
-        UsersResource users = new UsersResource(realm, tokenManager);
+        UsersResource users = new UsersResource(realm, auth, tokenManager);
         resourceContext.initResource(users);
         return users;
     }
 
     @Path("roles-by-id")
     public RoleByIdResource rolesById() {
-        auth.require(AdminRoles.getAdminApp(realm), AdminRoles.MANAGE_REALM);
-
-        RoleByIdResource resource = new RoleByIdResource(realm);
+        RoleByIdResource resource = new RoleByIdResource(realm, auth);
         resourceContext.initResource(resource);
         return resource;
     }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmAuth.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmAuth.java
new file mode 100644
index 0000000..d059c4c
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAuth.java
@@ -0,0 +1,88 @@
+package org.keycloak.services.resources.admin;
+
+import org.keycloak.models.AdminRoles;
+import org.keycloak.services.managers.Auth;
+
+import javax.ws.rs.ForbiddenException;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class RealmAuth {
+
+    private Resource resource;
+
+    public enum Resource {
+        APPLICATION, CLIENT, USER, REALM
+    }
+
+    private Auth auth;
+    private String realmAdminApp;
+
+    public RealmAuth(Auth auth, String realmAdminApp) {
+        this.auth = auth;
+        this.realmAdminApp = realmAdminApp;
+    }
+
+    public RealmAuth init(Resource resource) {
+        this.resource = resource;
+        return this;
+    }
+
+    public void requireAny() {
+        if (!auth.hasOneOfAppRole(realmAdminApp, AdminRoles.ALL_REALM_ROLES)) {
+            throw new ForbiddenException();
+        }
+    }
+
+    public boolean hasView() {
+        return auth.hasOneOfAppRole(realmAdminApp, getViewRole(resource), getManageRole(resource));
+    }
+
+    public boolean hasManage() {
+        return auth.hasOneOfAppRole(realmAdminApp, getManageRole(resource));
+    }
+
+    public void requireView() {
+        if (!hasView()) {
+            throw new ForbiddenException();
+        }
+    }
+
+    public void requireManage() {
+        if (!hasManage()) {
+            throw new ForbiddenException();
+        }
+    }
+
+    private String getViewRole(Resource resource) {
+        switch (resource) {
+            case APPLICATION:
+                return AdminRoles.VIEW_APPLICATIONS;
+            case CLIENT:
+                return AdminRoles.VIEW_CLIENTS;
+            case USER:
+                return AdminRoles.VIEW_USERS;
+            case REALM:
+                return AdminRoles.VIEW_REALM;
+            default:
+                throw new IllegalStateException();
+        }
+    }
+
+    private String getManageRole(Resource resource) {
+        switch (resource) {
+            case APPLICATION:
+                return AdminRoles.MANAGE_APPLICATIONS;
+            case CLIENT:
+                return AdminRoles.MANAGE_CLIENTS;
+            case USER:
+                return AdminRoles.MANAGE_USERS;
+            case REALM:
+                return AdminRoles.MANAGE_REALM;
+            default:
+                throw new IllegalStateException();
+        }
+    }
+
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java
index f0691d4..c2cbafb 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java
@@ -6,8 +6,6 @@ import org.jboss.resteasy.plugins.providers.multipart.InputPart;
 import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
 import org.jboss.resteasy.util.GenericType;
 import org.keycloak.models.AdminRoles;
-import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.representations.idm.RealmRepresentation;
@@ -67,11 +65,10 @@ public class RealmsAdminResource {
         for (RealmModel realm : realms) {
             String realmAdminApp = AdminRoles.getAdminApp(realm);
 
-            if (auth.has(realmAdminApp, AdminRoles.MANAGE_REALM)) {
+            if (auth.hasAppRole(realmAdminApp, AdminRoles.MANAGE_REALM)) {
                 reps.add(ModelToRepresentation.toRepresentation(realm));
-            } else if (auth.hasOneOf(realmAdminApp, AdminRoles.ALL_REALM_ROLES)) {
+            } else if (auth.hasOneOfAppRole(realmAdminApp, AdminRoles.ALL_REALM_ROLES)) {
                 RealmRepresentation rep = new RealmRepresentation();
-                rep.setId(realm.getId());
                 rep.setRealm(realm.getName());
                 reps.add(rep);
             }
@@ -90,7 +87,9 @@ public class RealmsAdminResource {
     @POST
     @Consumes("application/json")
     public Response importRealm(@Context final UriInfo uriInfo, final RealmRepresentation rep) {
-        auth.require(AdminRoles.ADMIN);
+        if (!auth.hasRealmRole(AdminRoles.ADMIN)) {
+            throw new ForbiddenException();
+        }
 
         logger.debug("importRealm: {0}", rep.getRealm());
         RealmManager realmManager = new RealmManager(session);
@@ -107,7 +106,9 @@ public class RealmsAdminResource {
     @POST
     @Consumes(MediaType.MULTIPART_FORM_DATA)
     public Response uploadRealm(MultipartFormDataInput input) throws IOException  {
-        auth.require(AdminRoles.ADMIN);
+        if (!auth.hasRealmRole(AdminRoles.ADMIN)) {
+            throw new ForbiddenException();
+        }
 
         Map<String, List<InputPart>> uploadForm = input.getFormDataMap();
         List<InputPart> inputParts = uploadForm.get("file");
@@ -128,9 +129,9 @@ public class RealmsAdminResource {
         RealmModel realm = realmManager.getRealmByName(name);
         if (realm == null) throw new NotFoundException("{realm} = " + name);
 
-        auth.requireOneOf(AdminRoles.getAdminApp(realm), AdminRoles.ALL_REALM_ROLES);
+        RealmAuth realmAuth = new RealmAuth(auth, AdminRoles.getAdminApp(realm));
 
-        RealmAdminResource adminResource = new RealmAdminResource(auth, realm, tokenManager);
+        RealmAdminResource adminResource = new RealmAdminResource(realmAuth, realm, tokenManager);
         resourceContext.initResource(adminResource);
         return adminResource;
     }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java
index 98869bf..f5b7cb0 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java
@@ -1,14 +1,13 @@
 package org.keycloak.services.resources.admin;
 
 import org.jboss.resteasy.annotations.cache.NoCache;
+import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.Constants;
+import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleContainerModel;
 import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserModel;
 import org.keycloak.representations.idm.RoleRepresentation;
-import org.keycloak.services.managers.ModelToRepresentation;
-import org.keycloak.services.resources.admin.RoleResource;
-import org.keycloak.services.resources.flows.Flows;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
@@ -19,10 +18,6 @@ import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
 
@@ -33,8 +28,14 @@ import java.util.Set;
  * @version $Revision: 1 $
  */
 public class RoleByIdResource extends RoleResource {
-    public RoleByIdResource(RealmModel realm) {
+    private final RealmModel realm;
+    private final RealmAuth auth;
+
+    public RoleByIdResource(RealmModel realm, RealmAuth auth) {
         super(realm);
+
+        this.realm = realm;
+        this.auth = auth;
     }
 
     @Path("{role-id}")
@@ -43,6 +44,7 @@ public class RoleByIdResource extends RoleResource {
     @Produces("application/json")
     public RoleRepresentation getRole(final @PathParam("role-id") String id) {
         RoleModel roleModel = getRoleModel(id);
+        auth.requireView();
         return getRole(roleModel);
     }
 
@@ -51,6 +53,19 @@ public class RoleByIdResource extends RoleResource {
         if (roleModel == null || roleModel.getName().startsWith(Constants.INTERNAL_ROLE)) {
             throw new NotFoundException("Could not find role with id: " + id);
         }
+
+        RealmAuth.Resource r = null;
+        if (roleModel.getContainer() instanceof RealmModel) {
+            r = RealmAuth.Resource.REALM;
+        } else if (roleModel.getContainer() instanceof ApplicationModel) {
+            r = RealmAuth.Resource.APPLICATION;
+        } else if (roleModel.getContainer() instanceof OAuthClientModel) {
+            r = RealmAuth.Resource.CLIENT;
+        } else if (roleModel.getContainer() instanceof UserModel) {
+            r = RealmAuth.Resource.USER;
+        }
+        auth.init(r);
+
         return roleModel;
     }
 
@@ -59,6 +74,7 @@ public class RoleByIdResource extends RoleResource {
     @NoCache
     public void deleteRole(final @PathParam("role-id") String id) {
         RoleModel role = getRoleModel(id);
+        auth.requireManage();
         deleteRole(role);
     }
 
@@ -67,6 +83,7 @@ public class RoleByIdResource extends RoleResource {
     @Consumes("application/json")
     public void updateRole(final @PathParam("role-id") String id, final RoleRepresentation rep) {
         RoleModel role = getRoleModel(id);
+        auth.requireManage();
         updateRole(rep, role);
     }
 
@@ -75,6 +92,7 @@ public class RoleByIdResource extends RoleResource {
     @Consumes("application/json")
     public void addComposites(final @PathParam("role-id") String id, List<RoleRepresentation> roles) {
         RoleModel role = getRoleModel(id);
+        auth.requireManage();
         addComposites(roles, role);
     }
 
@@ -84,6 +102,7 @@ public class RoleByIdResource extends RoleResource {
     @Produces("application/json")
     public Set<RoleRepresentation> getRoleComposites(final @PathParam("role-id") String id) {
         RoleModel role = getRoleModel(id);
+        auth.requireView();
         return getRoleComposites(role);
     }
 
@@ -93,6 +112,7 @@ public class RoleByIdResource extends RoleResource {
     @Produces("application/json")
     public Set<RoleRepresentation> getRealmRoleComposites(final @PathParam("role-id") String id) {
         RoleModel role = getRoleModel(id);
+        auth.requireView();
         return getRealmRoleComposites(role);
     }
 
@@ -103,6 +123,7 @@ public class RoleByIdResource extends RoleResource {
     public Set<RoleRepresentation> getApplicationRoleComposites(final @PathParam("role-id") String id,
                                                                 final @PathParam("app") String appName) {
         RoleModel role = getRoleModel(id);
+        auth.requireView();
         return getApplicationRoleComposites(appName, role);
     }
 
@@ -112,8 +133,8 @@ public class RoleByIdResource extends RoleResource {
     @Consumes("application/json")
     public void deleteComposites(final @PathParam("role-id") String id, List<RoleRepresentation> roles) {
         RoleModel role = getRoleModel(id);
+        auth.requireManage();
         deleteComposites(roles, role);
     }
 
-
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java
index e1f07fb..5bbd44b 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java
@@ -1,7 +1,6 @@
 package org.keycloak.services.resources.admin;
 
 import org.jboss.resteasy.annotations.cache.NoCache;
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.Constants;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleContainerModel;
@@ -10,13 +9,19 @@ import org.keycloak.representations.idm.RoleRepresentation;
 import org.keycloak.services.managers.ModelToRepresentation;
 import org.keycloak.services.resources.flows.Flows;
 
-import javax.ws.rs.*;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.NotFoundException;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -25,18 +30,24 @@ import java.util.Set;
  * @version $Revision: 1 $
  */
 public class RoleContainerResource extends RoleResource {
+    private final RealmModel realm;
+    private final RealmAuth auth;
     protected RoleContainerModel roleContainer;
 
-    public RoleContainerResource(RealmModel realm, RoleContainerModel roleContainer) {
+    public RoleContainerResource(RealmModel realm, RealmAuth auth, RoleContainerModel roleContainer) {
         super(realm);
+        this.realm = realm;
+        this.auth = auth;
         this.roleContainer = roleContainer;
     }
 
-    @Path("roles")
+    @Path("")
     @GET
     @NoCache
     @Produces("application/json")
     public List<RoleRepresentation> getRoles() {
+        auth.requireAny();
+
         Set<RoleModel> roleModels = roleContainer.getRoles();
         List<RoleRepresentation> roles = new ArrayList<RoleRepresentation>();
         for (RoleModel roleModel : roleModels) {
@@ -47,10 +58,12 @@ public class RoleContainerResource extends RoleResource {
         return roles;
     }
 
-    @Path("roles")
+    @Path("")
     @POST
     @Consumes("application/json")
     public Response createRole(final @Context UriInfo uriInfo, final RoleRepresentation rep) {
+        auth.requireManage();
+
         if (roleContainer.getRole(rep.getName()) != null || rep.getName().startsWith(Constants.INTERNAL_ROLE)) {
             return Flows.errors().exists("Role with name " + rep.getName() + " already exists");
         }
@@ -62,11 +75,13 @@ public class RoleContainerResource extends RoleResource {
         return Response.created(uriInfo.getAbsolutePathBuilder().path(role.getName()).build()).build();
     }
 
-    @Path("roles/{role-name}")
+    @Path("{role-name}")
     @GET
     @NoCache
     @Produces("application/json")
     public RoleRepresentation getRole(final @PathParam("role-name") String roleName) {
+        auth.requireView();
+
         RoleModel roleModel = roleContainer.getRole(roleName);
         if (roleModel == null || roleModel.getName().startsWith(Constants.INTERNAL_ROLE)) {
             throw new NotFoundException("Could not find role: " + roleName);
@@ -74,10 +89,12 @@ public class RoleContainerResource extends RoleResource {
         return getRole(roleModel);
     }
 
-    @Path("roles/{role-name}")
+    @Path("{role-name}")
     @DELETE
     @NoCache
     public void deleteRole(final @PathParam("role-name") String roleName) {
+        auth.requireManage();
+
         RoleModel role = roleContainer.getRole(roleName);
         if (role == null) {
             throw new NotFoundException("Could not find role: " + roleName);
@@ -85,10 +102,12 @@ public class RoleContainerResource extends RoleResource {
         deleteRole(role);
     }
 
-    @Path("roles/{role-name}")
+    @Path("{role-name}")
     @PUT
     @Consumes("application/json")
     public void updateRole(final @PathParam("role-name") String roleName, final RoleRepresentation rep) {
+        auth.requireManage();
+
         RoleModel role = roleContainer.getRole(roleName);
         if (role == null || role.getName().startsWith(Constants.INTERNAL_ROLE)) {
             throw new NotFoundException("Could not find role: " + roleName);
@@ -96,10 +115,12 @@ public class RoleContainerResource extends RoleResource {
         updateRole(rep, role);
     }
 
-    @Path("roles/{role-name}/composites")
+    @Path("{role-name}/composites")
     @POST
     @Consumes("application/json")
     public void addComposites(final @PathParam("role-name") String roleName, List<RoleRepresentation> roles) {
+        auth.requireManage();
+
         RoleModel role = roleContainer.getRole(roleName);
         if (role == null || role.getName().startsWith(Constants.INTERNAL_ROLE)) {
             throw new NotFoundException("Could not find role: " + roleName);
@@ -107,11 +128,13 @@ public class RoleContainerResource extends RoleResource {
         addComposites(roles, role);
     }
 
-    @Path("roles/{role-name}/composites")
+    @Path("{role-name}/composites")
     @GET
     @NoCache
     @Produces("application/json")
     public Set<RoleRepresentation> getRoleComposites(final @PathParam("role-name") String roleName) {
+        auth.requireManage();
+
         RoleModel role = roleContainer.getRole(roleName);
         if (role == null || role.getName().startsWith(Constants.INTERNAL_ROLE)) {
             throw new NotFoundException("Could not find role: " + roleName);
@@ -119,11 +142,13 @@ public class RoleContainerResource extends RoleResource {
         return getRoleComposites(role);
     }
 
-    @Path("roles/{role-name}/composites/realm")
+    @Path("{role-name}/composites/realm")
     @GET
     @NoCache
     @Produces("application/json")
     public Set<RoleRepresentation> getRealmRoleComposites(final @PathParam("role-name") String roleName) {
+        auth.requireManage();
+
         RoleModel role = roleContainer.getRole(roleName);
         if (role == null || role.getName().startsWith(Constants.INTERNAL_ROLE)) {
             throw new NotFoundException("Could not find role: " + roleName);
@@ -131,12 +156,14 @@ public class RoleContainerResource extends RoleResource {
         return getRealmRoleComposites(role);
     }
 
-    @Path("roles/{role-name}/composites/application/{app}")
+    @Path("{role-name}/composites/application/{app}")
     @GET
     @NoCache
     @Produces("application/json")
     public Set<RoleRepresentation> getApplicationRoleComposites(final @PathParam("role-name") String roleName,
                                                                 final @PathParam("app") String appName) {
+        auth.requireManage();
+
         RoleModel role = roleContainer.getRole(roleName);
         if (role == null || role.getName().startsWith(Constants.INTERNAL_ROLE)) {
             throw new NotFoundException("Could not find role: " + roleName);
@@ -145,10 +172,12 @@ public class RoleContainerResource extends RoleResource {
     }
 
 
-    @Path("roles/{role-name}/composites")
+    @Path("{role-name}/composites")
     @DELETE
     @Consumes("application/json")
     public void deleteComposites(final @PathParam("role-name") String roleName, List<RoleRepresentation> roles) {
+        auth.requireManage();
+
         RoleModel role = roleContainer.getRole(roleName);
         if (role == null || role.getName().startsWith(Constants.INTERNAL_ROLE)) {
             throw new NotFoundException("Could not find role: " + roleName);
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java
index 91e42b4..94d95af 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java
@@ -16,7 +16,7 @@ import java.util.Set;
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
  */
-public class RoleResource {
+public abstract class RoleResource {
     protected RealmModel realm;
 
     public RoleResource(RealmModel realm) {
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java
index c630d28..c5e8662 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java
@@ -32,11 +32,13 @@ import java.util.Set;
  */
 public class ScopeMappedResource {
     protected RealmModel realm;
+    private RealmAuth auth;
     protected UserModel agent;
     protected KeycloakSession session;
 
-    public ScopeMappedResource(RealmModel realm, UserModel account, KeycloakSession session) {
+    public ScopeMappedResource(RealmModel realm, RealmAuth auth, UserModel account, KeycloakSession session) {
         this.realm = realm;
+        this.auth = auth;
         this.agent = account;
         this.session = session;
     }
@@ -45,6 +47,8 @@ public class ScopeMappedResource {
     @Produces("application/json")
     @NoCache
     public MappingsRepresentation getScopeMappings() {
+        auth.requireView();
+
         MappingsRepresentation all = new MappingsRepresentation();
         Set<RoleModel> realmMappings = realm.getRealmScopeMappings(agent);
         RealmManager manager = new RealmManager(session);
@@ -83,6 +87,8 @@ public class ScopeMappedResource {
     @Produces("application/json")
     @NoCache
     public List<RoleRepresentation> getRealmScopeMappings() {
+        auth.requireView();
+
         Set<RoleModel> realmMappings = realm.getRealmScopeMappings(agent);
         List<RoleRepresentation> realmMappingsRep = new ArrayList<RoleRepresentation>();
         RealmManager manager = new RealmManager(session);
@@ -96,6 +102,8 @@ public class ScopeMappedResource {
     @POST
     @Consumes("application/json")
     public void addRealmScopeMappings(List<RoleRepresentation> roles) {
+        auth.requireManage();
+
         for (RoleRepresentation role : roles) {
             RoleModel roleModel = realm.getRoleById(role.getId());
             if (roleModel == null) {
@@ -111,6 +119,8 @@ public class ScopeMappedResource {
     @DELETE
     @Consumes("application/json")
     public void deleteRealmScopeMappings(List<RoleRepresentation> roles) {
+        auth.requireManage();
+
         if (roles == null) {
             Set<RoleModel> roleModels = realm.getRealmScopeMappings(agent);
             for (RoleModel roleModel : roleModels) {
@@ -133,6 +143,8 @@ public class ScopeMappedResource {
     @Produces("application/json")
     @NoCache
     public List<RoleRepresentation> getApplicationScopeMappings(@PathParam("app") String appName) {
+        auth.requireView();
+
         ApplicationModel app = realm.getApplicationByName(appName);
 
         if (app == null) {
@@ -151,6 +163,8 @@ public class ScopeMappedResource {
     @POST
     @Consumes("application/json")
     public void addApplicationScopeMapping(@PathParam("app") String appName, List<RoleRepresentation> roles) {
+        auth.requireManage();
+
         ApplicationModel app = realm.getApplicationByName(appName);
 
         if (app == null) {
@@ -171,6 +185,8 @@ public class ScopeMappedResource {
     @DELETE
     @Consumes("application/json")
     public void deleteApplicationScopeMapping(@PathParam("app") String appName, List<RoleRepresentation> roles) {
+        auth.requireManage();
+
         ApplicationModel app = realm.getApplicationByName(appName);
 
         if (app == null) {
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
index 2af61a9..212c6b6 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
@@ -13,6 +13,7 @@ import org.keycloak.representations.idm.*;
 import org.keycloak.services.email.EmailException;
 import org.keycloak.services.email.EmailSender;
 import org.keycloak.services.managers.AccessCodeEntry;
+import org.keycloak.services.managers.Auth;
 import org.keycloak.services.managers.ModelToRepresentation;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.managers.TokenManager;
@@ -50,11 +51,15 @@ public class UsersResource {
 
     protected RealmModel realm;
 
+    private RealmAuth auth;
     private TokenManager tokenManager;
 
-    public UsersResource(RealmModel realm, TokenManager tokenManager) {
+    public UsersResource(RealmModel realm, RealmAuth auth, TokenManager tokenManager) {
+        this.auth = auth;
         this.realm = realm;
         this.tokenManager = tokenManager;
+
+        auth.init(RealmAuth.Resource.USER);
     }
 
     @Context
@@ -71,6 +76,8 @@ public class UsersResource {
     @PUT
     @Consumes("application/json")
     public void updateUser(final @PathParam("username") String username, final UserRepresentation rep) {
+        auth.requireManage();
+
         UserModel user = realm.getUser(username);
         if (user == null) {
             throw new NotFoundException();
@@ -81,6 +88,8 @@ public class UsersResource {
     @POST
     @Consumes("application/json")
     public Response createUser(final @Context UriInfo uriInfo, final UserRepresentation rep) {
+        auth.requireManage();
+
         if (realm.getUser(rep.getUsername()) != null) {
             return Flows.errors().exists("User with username " + rep.getUsername() + " already exists");
         }
@@ -125,6 +134,8 @@ public class UsersResource {
     @NoCache
     @Produces("application/json")
     public UserRepresentation getUser(final @PathParam("username") String username) {
+        auth.requireView();
+
         UserModel user = realm.getUser(username);
         if (user == null || !isUser(user)) {
             throw new NotFoundException();
@@ -136,6 +147,8 @@ public class UsersResource {
     @DELETE
     @NoCache
     public void deleteUser(final @PathParam("username") String username) {
+        auth.requireManage();
+
         realm.removeUser(username);
     }
 
@@ -147,6 +160,8 @@ public class UsersResource {
                                              @QueryParam("firstName") String first,
                                              @QueryParam("email") String email,
                                              @QueryParam("username") String username) {
+        auth.requireView();
+
         RealmManager manager = new RealmManager(session);
         List<UserRepresentation> results = new ArrayList<UserRepresentation>();
         List<UserModel> userModels;
@@ -191,6 +206,8 @@ public class UsersResource {
     @Produces("application/json")
     @NoCache
     public MappingsRepresentation getRoleMappings(@PathParam("username") String username) {
+        auth.requireView();
+
         UserModel user = realm.getUser(username);
         if (user == null) {
             throw new NotFoundException();
@@ -234,6 +251,8 @@ public class UsersResource {
     @Produces("application/json")
     @NoCache
     public List<RoleRepresentation> getRealmRoleMappings(@PathParam("username") String username) {
+        auth.requireView();
+
         UserModel user = realm.getUser(username);
         if (user == null) {
             throw new NotFoundException();
@@ -252,6 +271,8 @@ public class UsersResource {
     @POST
     @Consumes("application/json")
     public void addRealmRoleMappings(@PathParam("username") String username, List<RoleRepresentation> roles) {
+        auth.requireManage();
+
         logger.debug("** addRealmRoleMappings: {0}", roles);
         UserModel user = realm.getUser(username);
         if (user == null) {
@@ -273,6 +294,8 @@ public class UsersResource {
     @DELETE
     @Consumes("application/json")
     public void deleteRealmRoleMappings(@PathParam("username") String username, List<RoleRepresentation> roles) {
+        auth.requireManage();
+
         logger.debug("deleteRealmRoleMappings");
         UserModel user = realm.getUser(username);
         if (user == null) {
@@ -301,6 +324,8 @@ public class UsersResource {
     @Produces("application/json")
     @NoCache
     public List<RoleRepresentation> getApplicationRoleMappings(@PathParam("username") String username, @PathParam("app") String appName) {
+        auth.requireView();
+
         logger.debug("getApplicationRoleMappings");
 
         UserModel user = realm.getUser(username);
@@ -327,6 +352,8 @@ public class UsersResource {
     @POST
     @Consumes("application/json")
     public void addApplicationRoleMapping(@PathParam("username") String username, @PathParam("app") String appName, List<RoleRepresentation> roles) {
+        auth.requireManage();
+
         logger.debug("addApplicationRoleMapping");
         UserModel user = realm.getUser(username);
         if (user == null) {
@@ -353,6 +380,8 @@ public class UsersResource {
     @DELETE
     @Consumes("application/json")
     public void deleteApplicationRoleMapping(@PathParam("username") String username, @PathParam("app") String appName, List<RoleRepresentation> roles) {
+        auth.requireManage();
+
         UserModel user = realm.getUser(username);
         if (user == null) {
             throw new NotFoundException();
@@ -389,6 +418,8 @@ public class UsersResource {
     @PUT
     @Consumes("application/json")
     public void resetPassword(@PathParam("username") String username, CredentialRepresentation pass) {
+        auth.requireManage();
+
         UserModel user = realm.getUser(username);
         if (user == null) {
             throw new NotFoundException();
@@ -406,6 +437,8 @@ public class UsersResource {
     @PUT
     @Consumes("application/json")
     public void removeTotp(@PathParam("username") String username) {
+        auth.requireManage();
+
         UserModel user = realm.getUser(username);
         if (user == null) {
             throw new NotFoundException();
@@ -418,6 +451,8 @@ public class UsersResource {
     @PUT
     @Consumes("application/json")
     public Response resetPasswordEmail(@PathParam("username") String username) {
+        auth.requireManage();
+
         UserModel user = realm.getUser(username);
         if (user == null) {
             throw new NotFoundException();