keycloak-aplcache

Merge pull request #240 from stianst/admin-access KEYCLOAK-292

2/25/2014 9:59:31 AM

Changes

Details

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 f1a4f49..782069a 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
@@ -7,6 +7,17 @@ module.controller('GlobalCtrl', function($scope, $http, Auth, Current, $location
     $http.get('/auth/rest/admin/whoami').success(function(data, status) {
         Auth.user = data;
         Auth.loggedIn = true;
+
+        Auth.hasAccess = function(realm, role) {
+            var realmAccess = Auth.user['realm_access'];
+            if (realmAccess) {
+                realmAccess = realmAccess[realm];
+                if (realmAccess) {
+                    return realmAccess.indexOf(role) >= 0;
+                }
+            }
+            return false;
+        }
     })
         .error(function(data, status) {
             Auth.loggedIn = false;
@@ -62,7 +73,7 @@ module.controller('RealmDropdownCtrl', function($scope, Realm, Current, Auth, $l
     }
 });
 
-module.controller('RealmCreateCtrl', function($scope, Current, Realm, $upload, $http, $location, Dialog, Notifications) {
+module.controller('RealmCreateCtrl', function($scope, Current, Realm, $upload, $http, $location, Dialog, Notifications, Auth) {
     console.log('RealmCreateCtrl');
 
     Current.realm = null;
@@ -131,8 +142,14 @@ module.controller('RealmCreateCtrl', function($scope, Current, Realm, $upload, $
                         Current.realm = Current.realms[i];
                     }
                 }
-                $location.url("/realms/" + realmCopy.realm);
-                Notifications.success("The realm has been created.");
+
+                $http.get('/auth/rest/admin/whoami').success(function(data, status) {
+                    Auth.user = data;
+                    console.log("reloaded auth");
+
+                    $location.url("/realms/" + realmCopy.realm);
+                    Notifications.success("The realm has been created.");
+                });
             });
         });
     };
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/menu.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/menu.html
index 2aeab7c..275cdae 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/menu.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/menu.html
@@ -33,7 +33,7 @@
                     </li>
                 </ul>
             </li>
-            <li class="active pull-right" data-ng-show="auth.loggedIn">
+            <li class="active pull-right" data-ng-show="auth.loggedIn && auth.user.admin">
                 <a class="button primary" href="#/create/realm" data-ng-class="path[0] == 'create' && path[1] == 'realm' && 'active'"
                    data-ng-show="auth.loggedIn">Add Realm</a>
             </li>
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 da8375a..d51f280 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,98 +7,104 @@
             <li><a href="#/realms/{{realm.realm}}">Settings</a></li>
             <li class="active">General</li>
         </ol>
-        <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>
-            <fieldset>
-                <legend class="aj-collapse open"><span class="text">Required Settings</span></legend>
-                <div class="form-group">
-                    <label class="col-sm-2 control-label" for="name">Name <span class="required" data-ng-show="createRealm">*</span></label>
+        <div data-ng-show="auth.hasAccess(realm.realm, 'manage-realm')">
+            <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>
+                <fieldset>
+                    <legend class="aj-collapse open"><span class="text">Required Settings</span></legend>
+                    <div class="form-group">
+                        <label class="col-sm-2 control-label" for="name">Name <span class="required" data-ng-show="createRealm">*</span></label>
 
-                    <div class="col-sm-4">
-                        <input class="form-control" type="text" id="name" name="name" data-ng-model="realm.realm" autofocus required>
+                        <div class="col-sm-4">
+                            <input class="form-control" type="text" id="name" name="name" data-ng-model="realm.realm" autofocus required>
+                        </div>
                     </div>
-                </div>
-                <div class="form-group">
-                    <label class="col-sm-2 control-label" for="enabled">Enabled</label>
-                    <div class="col-sm-4">
-                        <input ng-model="realm.enabled" name="enabled" id="enabled" onoffswitch />
+                    <div class="form-group">
+                        <label class="col-sm-2 control-label" for="enabled">Enabled</label>
+                        <div class="col-sm-4">
+                            <input ng-model="realm.enabled" name="enabled" id="enabled" onoffswitch />
+                        </div>
                     </div>
-                </div>
-            </fieldset>
-            <fieldset>
-                <legend><span class="text">Login Options</span></legend>
-                <div class="form-group">
-                    <label class="col-sm-2 control-label" for="social">Social login</label>
-                    <div class="col-sm-4">
-                        <input ng-model="realm.social" name="social" id="social" onoffswitch />
+                </fieldset>
+                <fieldset>
+                    <legend><span class="text">Login Options</span></legend>
+                    <div class="form-group">
+                        <label class="col-sm-2 control-label" for="social">Social login</label>
+                        <div class="col-sm-4">
+                            <input ng-model="realm.social" name="social" id="social" onoffswitch />
+                        </div>
                     </div>
-                </div>
-                <div class="form-group" data-ng-show="realm.social">
-                    <label class="col-sm-2 control-label" for="updateProfileOnInitialSocialLogin">Update profile on first social login</label>
-                    <div class="col-sm-4">
-                        <input ng-model="realm.updateProfileOnInitialSocialLogin" name="updateProfileOnInitialSocialLogin" id="updateProfileOnInitialSocialLogin" onoffswitch />
+                    <div class="form-group" data-ng-show="realm.social">
+                        <label class="col-sm-2 control-label" for="updateProfileOnInitialSocialLogin">Update profile on first social login</label>
+                        <div class="col-sm-4">
+                            <input ng-model="realm.updateProfileOnInitialSocialLogin" name="updateProfileOnInitialSocialLogin" id="updateProfileOnInitialSocialLogin" onoffswitch />
+                        </div>
                     </div>
-                </div>
-                <div class="form-group">
-                    <label for="registrationAllowed" class="col-sm-2 control-label">User registration</label>
-                    <div class="col-sm-4">
-                        <input ng-model="realm.registrationAllowed" name="registrationAllowed" id="registrationAllowed" onoffswitch />
+                    <div class="form-group">
+                        <label for="registrationAllowed" class="col-sm-2 control-label">User registration</label>
+                        <div class="col-sm-4">
+                            <input ng-model="realm.registrationAllowed" name="registrationAllowed" id="registrationAllowed" onoffswitch />
+                        </div>
                     </div>
-                </div>
-                <div class="form-group">
-                    <label for="resetPasswordAllowed" class="col-sm-2 control-label">Reset password</label>
-                    <div class="col-sm-4">
-                        <input ng-model="realm.resetPasswordAllowed" name="resetPasswordAllowed" id="resetPasswordAllowed" onoffswitch />
+                    <div class="form-group">
+                        <label for="resetPasswordAllowed" class="col-sm-2 control-label">Reset password</label>
+                        <div class="col-sm-4">
+                            <input ng-model="realm.resetPasswordAllowed" name="resetPasswordAllowed" id="resetPasswordAllowed" onoffswitch />
+                        </div>
                     </div>
-                </div>
-                <div class="form-group">
-                    <label for="verifyEmail" class="col-sm-2 control-label">Verify email</label>
-                    <div class="col-sm-4">
-                        <input ng-model="realm.verifyEmail" name="verifyEmail" id="verifyEmail" onoffswitch />
+                    <div class="form-group">
+                        <label for="verifyEmail" class="col-sm-2 control-label">Verify email</label>
+                        <div class="col-sm-4">
+                            <input ng-model="realm.verifyEmail" name="verifyEmail" id="verifyEmail" onoffswitch />
+                        </div>
                     </div>
-                </div>
-                <div class="form-group">
-                    <label for="requireSsl" class="col-sm-2 control-label">Require SSL</label>
-                    <div class="col-sm-4">
-                        <input ng-model="realm.requireSsl" name="requireSsl" id="requireSsl" onoffswitch />
+                    <div class="form-group">
+                        <label for="requireSsl" class="col-sm-2 control-label">Require SSL</label>
+                        <div class="col-sm-4">
+                            <input ng-model="realm.requireSsl" name="requireSsl" id="requireSsl" onoffswitch />
+                        </div>
                     </div>
-                </div>
-            </fieldset>
-            <fieldset>
-                <legend><span class="text">Optional Settings</span></legend>
-                <div class="form-group">
-                    <label class="col-sm-2 control-label" for="loginTheme">Login Theme</label>
-                    <div class="col-sm-4">
-                        <select kc-select id="loginTheme"
-                                data-kc-placeholder="Select one..."
-                                data-kc-model="realm.loginTheme"
-                                data-kc-options="serverInfo.themes.login">
-                        </select>
+                </fieldset>
+                <fieldset>
+                    <legend><span class="text">Optional Settings</span></legend>
+                    <div class="form-group">
+                        <label class="col-sm-2 control-label" for="loginTheme">Login Theme</label>
+                        <div class="col-sm-4">
+                            <select kc-select id="loginTheme"
+                                    data-kc-placeholder="Select one..."
+                                    data-kc-model="realm.loginTheme"
+                                    data-kc-options="serverInfo.themes.login">
+                            </select>
+                        </div>
                     </div>
-                </div>
-                <div class="form-group">
-                    <label class="col-sm-2 control-label" for="accountTheme">Account Theme</label>
-                    <div class="col-sm-4">
-                        <select kc-select id="accountTheme"
-                                data-kc-placeholder="Select one..."
-                                data-kc-model="realm.accountTheme"
-                                data-kc-options="serverInfo.themes.account">
-                        </select>
+                    <div class="form-group">
+                        <label class="col-sm-2 control-label" for="accountTheme">Account Theme</label>
+                        <div class="col-sm-4">
+                            <select kc-select id="accountTheme"
+                                    data-kc-placeholder="Select one..."
+                                    data-kc-model="realm.accountTheme"
+                                    data-kc-options="serverInfo.themes.account">
+                            </select>
+                        </div>
                     </div>
+                </fieldset>
+
+                <div class="pull-right form-actions" data-ng-show="createRealm">
+                    <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">
+                    <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>
-            </fieldset>
+            </form>
+        </div>
+        <div data-ng-hide="auth.hasAccess(realm.realm, 'manage-realm')">
+            <h2 ><span>{{realm.realm}}</span></h2>
+        </div>
 
-            <div class="pull-right form-actions" data-ng-show="createRealm">
-                <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">
-                <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>
+</div>
\ No newline at end of file
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 81c9fae..6bd704c 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,10 +1,9 @@
 <ul data-ng-hide="createRealm">
-    <li data-ng-class="((!path[2] || path[1] == 'role' || path[2] == 'roles' || path[2] == 'token-settings' ||
+    <li data-ng-show="auth.hasAccess(realm.realm, 'manage-realm')" 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-class="(path[2] == 'users' || path[1] == 'user') && 'active'"><a href="#/realms/{{realm.realm}}/users">Users</a>
+    <li data-ng-show="auth.hasAccess(realm.realm, 'manage-users')" data-ng-class="(path[2] == 'users' || path[1] == 'user') && 'active'"><a href="#/realms/{{realm.realm}}/users">Users</a>
     </li>
-    <li 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-class="(path[2] == 'oauth-clients' || path[1] == 'oauth-client') && 'active'"><a href="#/realms/{{realm.realm}}/oauth-clients">OAuth Clients</a></li>
-</ul>
-
+    <li data-ng-show="auth.hasAccess(realm.realm, 'manage-applications')" 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="auth.hasAccess(realm.realm, 'manage-clients')" 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/templates/kc-navigation.html b/admin-ui/src/main/resources/META-INF/resources/admin/templates/kc-navigation.html
index cfb83b2..aed507b 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: kcCurrent == 'general'}"><a href="#/realms/{{kcRealm}}">General</a></li>
-    <li ng-class="{active: kcCurrent == 'social'}" data-ng-show="kcSocial"><a href="#/realms/{{kcRealm}}/social-settings">Social</a></li>
-    <li ng-class="{active: kcCurrent == 'roles'}"><a href="#/realms/{{kcRealm}}/roles">Roles</a></li>
-    <li ng-class="{active: kcCurrent == 'defRoles'}"><a href="#/realms/{{kcRealm}}/default-roles">Default Roles</a></li>
-    <li ng-class="{active: kcCurrent == 'credentials'}"><a href="#/realms/{{kcRealm}}/required-credentials">Credentials</a></li>
-    <li ng-class="{active: kcCurrent == 'token'}"><a href="#/realms/{{kcRealm}}/token-settings">Token</a></li>
-    <li ng-class="{active: kcCurrent == 'keys'}"><a href="#/realms/{{kcRealm}}/keys-settings">Keys</a></li>
-    <li ng-class="{active: kcCurrent == 'email'}"><a href="#/realms/{{kcRealm}}/smtp-settings">Email</a></li>
-</ul>
+    <li ng-class="{active: kcCurrent == 'social'}" data-ng-show="kcSocial && auth.hasAccess(realm.realm, 'manage-realm')"><a href="#/realms/{{kcRealm}}/social-settings">Social</a></li>
+    <li ng-class="{active: kcCurrent == 'roles'}" data-ng-show="auth.hasAccess(realm.realm, 'manage-realm')"><a href="#/realms/{{kcRealm}}/roles">Roles</a></li>
+    <li ng-class="{active: kcCurrent == 'defRoles'}" data-ng-show="auth.hasAccess(realm.realm, 'manage-realm')"><a href="#/realms/{{kcRealm}}/default-roles">Default Roles</a></li>
+    <li ng-class="{active: kcCurrent == 'credentials'}" data-ng-show="auth.hasAccess(realm.realm, 'manage-realm')"><a href="#/realms/{{kcRealm}}/required-credentials">Credentials</a></li>
+    <li ng-class="{active: kcCurrent == 'token'}" data-ng-show="auth.hasAccess(realm.realm, 'manage-realm')"><a href="#/realms/{{kcRealm}}/token-settings">Token</a></li>
+    <li ng-class="{active: kcCurrent == 'keys'}" data-ng-show="auth.hasAccess(realm.realm, 'manage-realm')"><a href="#/realms/{{kcRealm}}/keys-settings">Keys</a></li>
+    <li ng-class="{active: kcCurrent == 'email'}" data-ng-show="auth.hasAccess(realm.realm, 'manage-realm')"><a href="#/realms/{{kcRealm}}/smtp-settings">Email</a></li>
+</ul>
\ No newline at end of file
diff --git a/model/api/src/main/java/org/keycloak/models/AccountRoles.java b/model/api/src/main/java/org/keycloak/models/AccountRoles.java
new file mode 100644
index 0000000..824d00a
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/models/AccountRoles.java
@@ -0,0 +1,13 @@
+package org.keycloak.models;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public interface AccountRoles {
+
+    String VIEW_PROFILE = "view-profile";
+    String MANAGE_ACCOUNT = "manage-account";
+
+    String[] ALL = {VIEW_PROFILE, MANAGE_ACCOUNT};
+
+}
diff --git a/model/api/src/main/java/org/keycloak/models/AdminRoles.java b/model/api/src/main/java/org/keycloak/models/AdminRoles.java
new file mode 100644
index 0000000..ab414bf
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/models/AdminRoles.java
@@ -0,0 +1,23 @@
+package org.keycloak.models;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class AdminRoles {
+
+    public static String APP_SUFFIX = "-realm";
+
+    public static String ADMIN = "admin";
+
+    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 getAdminApp(RealmModel realm) {
+        return realm.getName() + APP_SUFFIX;
+    }
+
+}
diff --git a/model/api/src/main/java/org/keycloak/models/Constants.java b/model/api/src/main/java/org/keycloak/models/Constants.java
index c2051df..9dfe1e4 100755
--- a/model/api/src/main/java/org/keycloak/models/Constants.java
+++ b/model/api/src/main/java/org/keycloak/models/Constants.java
@@ -5,14 +5,12 @@ package org.keycloak.models;
  * @version $Revision: 1 $
  */
 public interface Constants {
-    String INTERNAL_ROLE = "KEYCLOAK_";
     String ADMIN_REALM = "keycloak-admin";
     String ADMIN_CONSOLE_APPLICATION = "admin-console";
-    String ADMIN_CONSOLE_ADMIN_ROLE = "admin";
+
+    String INTERNAL_ROLE = "KEYCLOAK_";
     String APPLICATION_ROLE = INTERNAL_ROLE + "_APPLICATION";
     String IDENTITY_REQUESTER_ROLE = INTERNAL_ROLE + "_IDENTITY_REQUESTER";
 
-    String ACCOUNT_APPLICATION = "account";
-    String ACCOUNT_PROFILE_ROLE = "view-profile";
-    String ACCOUNT_MANAGE_ROLE = "manage-account";
+    String ACCOUNT_MANAGEMENT_APP = "account";
 }
diff --git a/model/api/src/main/java/org/keycloak/models/KeycloakSession.java b/model/api/src/main/java/org/keycloak/models/KeycloakSession.java
index f9ed6a2..00b4db9 100755
--- a/model/api/src/main/java/org/keycloak/models/KeycloakSession.java
+++ b/model/api/src/main/java/org/keycloak/models/KeycloakSession.java
@@ -13,7 +13,7 @@ public interface KeycloakSession {
     RealmModel createRealm(String id, String name);
     RealmModel getRealm(String id);
     RealmModel getRealmByName(String name);
-    List<RealmModel> getRealms(UserModel admin);
+    List<RealmModel> getRealms();
     boolean removeRealm(String id);
 
     void close();
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakSession.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakSession.java
index 1a24530..7812315 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakSession.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakSession.java
@@ -49,7 +49,7 @@ public class JpaKeycloakSession implements KeycloakSession {
     }
 
     @Override
-    public List<RealmModel> getRealms(UserModel admin) {
+    public List<RealmModel> getRealms() {
         TypedQuery<RealmEntity> query = em.createNamedQuery("getAllRealms", RealmEntity.class);
         List<RealmEntity> entities = query.getResultList();
         List<RealmModel> realms = new ArrayList<RealmModel>();
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoKeycloakSession.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoKeycloakSession.java
index a57916b..1420a09 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoKeycloakSession.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoKeycloakSession.java
@@ -67,7 +67,7 @@ public class MongoKeycloakSession implements KeycloakSession {
     }
 
     @Override
-    public List<RealmModel> getRealms(UserModel admin) {
+    public List<RealmModel> getRealms() {
         DBObject query = new BasicDBObject();
         List<RealmEntity> realms = getMongoStore().loadEntities(RealmEntity.class, query, invocationContext);
 
diff --git a/model/tests/src/test/java/org/keycloak/model/test/AbstractModelTest.java b/model/tests/src/test/java/org/keycloak/model/test/AbstractModelTest.java
index c7c9671..4846b57 100644
--- a/model/tests/src/test/java/org/keycloak/model/test/AbstractModelTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/AbstractModelTest.java
@@ -13,6 +13,7 @@ import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.KeycloakSessionFactory;
 import org.keycloak.models.RoleModel;
 import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.services.managers.ApplianceBootstrap;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.resources.KeycloakApplication;
 import org.keycloak.util.JsonSerialization;
@@ -34,6 +35,8 @@ public class AbstractModelTest {
         identitySession = factory.createSession();
         identitySession.getTransaction().begin();
         realmManager = new RealmManager(identitySession);
+
+        new ApplianceBootstrap().bootstrap(identitySession);
     }
 
     @After
diff --git a/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java b/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java
index 6e71d6e..8aa12f9 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java
@@ -1,6 +1,7 @@
 package org.keycloak.model.test;
 
 import org.junit.Assert;
+import org.junit.Before;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
@@ -33,12 +34,6 @@ public class AdapterTest extends AbstractModelTest {
     private RealmModel realmModel;
 
     @Test
-    public void installTest() throws Exception {
-        new ApplianceBootstrap().bootstrap(identitySession);
-
-    }
-
-    @Test
     public void test1CreateRealm() throws Exception {
         realmModel = realmManager.createRealm("JUGGLER");
         realmModel.setAccessCodeLifespan(100);
@@ -79,7 +74,6 @@ public class AdapterTest extends AbstractModelTest {
         realmModel.setUpdateProfileOnInitialSocialLogin(true);
         realmModel.addDefaultRole("foo");
 
-        System.out.println(realmModel.getId());
         realmModel = realmManager.getRealm(realmModel.getId());
         Assert.assertNotNull(realmModel);
         Assert.assertEquals(realmModel.getAccessCodeLifespan(), 100);
@@ -93,13 +87,11 @@ public class AdapterTest extends AbstractModelTest {
         Assert.assertEquals(1, realmModel.getDefaultRoles().size());
         Assert.assertEquals("foo", realmModel.getDefaultRoles().get(0));
 
-        String id = realmModel.getId();
-        System.out.println("id: " + id);
+        realmModel.getId();
 
         commit();
-        List<RealmModel> realms = identitySession.getRealms(null);
-        System.out.println("num realms: " + realms.size());
-        Assert.assertEquals(realms.size(), 1);
+        List<RealmModel> realms = identitySession.getRealms();
+        Assert.assertEquals(realms.size(), 2);
     }
 
 
diff --git a/model/tests/src/test/java/org/keycloak/model/test/ImportTest.java b/model/tests/src/test/java/org/keycloak/model/test/ImportTest.java
index b44b32f..ba30206 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/ImportTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/ImportTest.java
@@ -4,6 +4,7 @@ import org.junit.Assert;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
+import org.keycloak.models.AccountRoles;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.Constants;
 import org.keycloak.models.RealmModel;
@@ -56,7 +57,7 @@ public class ImportTest extends AbstractModelTest {
         // Test applications imported
         ApplicationModel application = realm.getApplicationByName("Application");
         ApplicationModel otherApp = realm.getApplicationByName("OtherApp");
-        ApplicationModel accountApp = realm.getApplicationByName(Constants.ACCOUNT_APPLICATION);
+        ApplicationModel accountApp = realm.getApplicationByName(Constants.ACCOUNT_MANAGEMENT_APP);
         ApplicationModel nonExisting = realm.getApplicationByName("NonExisting");
         Assert.assertNotNull(application);
         Assert.assertNotNull(otherApp);
@@ -80,8 +81,8 @@ public class ImportTest extends AbstractModelTest {
         Assert.assertTrue(allRoles.contains(realm.getRole("admin")));
         Assert.assertTrue(allRoles.contains(application.getRole("app-admin")));
         Assert.assertTrue(allRoles.contains(otherApp.getRole("otherapp-admin")));
-        Assert.assertTrue(allRoles.contains(accountApp.getRole(Constants.ACCOUNT_PROFILE_ROLE)));
-        Assert.assertTrue(allRoles.contains(accountApp.getRole(Constants.ACCOUNT_MANAGE_ROLE)));
+        Assert.assertTrue(allRoles.contains(accountApp.getRole(AccountRoles.VIEW_PROFILE)));
+        Assert.assertTrue(allRoles.contains(accountApp.getRole(AccountRoles.MANAGE_ACCOUNT)));
 
         UserModel wburke = realm.getUser("wburke");
         allRoles = realm.getRoleMappings(wburke);
diff --git a/services/src/main/java/org/keycloak/services/managers/AppAuthManager.java b/services/src/main/java/org/keycloak/services/managers/AppAuthManager.java
new file mode 100644
index 0000000..9aea2f3
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/managers/AppAuthManager.java
@@ -0,0 +1,176 @@
+package org.keycloak.services.managers;
+
+import org.jboss.resteasy.logging.Logger;
+import org.jboss.resteasy.spi.HttpResponse;
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
+import org.keycloak.RSATokenVerifier;
+import org.keycloak.VerificationException;
+import org.keycloak.jose.jws.JWSBuilder;
+import org.keycloak.jose.jws.JWSInput;
+import org.keycloak.jose.jws.crypto.RSAProvider;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.representations.AccessToken;
+
+import javax.ws.rs.BadRequestException;
+import javax.ws.rs.NotAuthorizedException;
+import javax.ws.rs.core.Cookie;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.NewCookie;
+import java.net.URI;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class AppAuthManager extends AuthenticationManager {
+    protected static Logger logger = Logger.getLogger(AuthenticationManager.class);
+
+    private String cookieName;
+    private TokenManager tokenManager;
+
+    public AppAuthManager(String cookieName, TokenManager tokenManager) {
+        this.cookieName = cookieName;
+        this.tokenManager = tokenManager;
+    }
+
+    public NewCookie createCookie(RealmModel realm, UserModel client, String code, URI uri) {
+        JWSInput input = new JWSInput(code);
+        boolean verifiedCode = false;
+        try {
+            verifiedCode = RSAProvider.verify(input, realm.getPublicKey());
+        } catch (Exception ignored) {
+            logger.debug("Failed to verify signature", ignored);
+        }
+        if (!verifiedCode) {
+            logger.debug("unverified access code");
+            throw new BadRequestException();
+        }
+        String key = input.readContentAsString();
+        AccessCodeEntry accessCode = tokenManager.pullAccessCode(key);
+        if (accessCode == null) {
+            logger.debug("bad access code");
+            throw new BadRequestException();
+        }
+        if (accessCode.isExpired()) {
+            logger.debug("access code expired");
+            throw new BadRequestException();
+        }
+        if (!accessCode.getToken().isActive()) {
+            logger.debug("access token expired");
+            throw new BadRequestException();
+        }
+        if (!accessCode.getRealm().getId().equals(realm.getId())) {
+            logger.debug("bad realm");
+            throw new BadRequestException();
+
+        }
+        if (!client.getLoginName().equals(accessCode.getClient().getLoginName())) {
+            logger.debug("bad client");
+            throw new BadRequestException();
+        }
+
+        return createLoginCookie(realm, accessCode.getUser(), accessCode.getClient(), cookieName, uri.getRawPath(), false);
+    }
+
+    public NewCookie createRefreshCookie(RealmModel realm, UserModel user, UserModel client, URI uri) {
+        return createLoginCookie(realm, user, client, cookieName, uri.getRawPath(), false);
+    }
+
+    public void expireCookie(URI uri) {
+        expireCookie(cookieName, uri.getRawPath());
+    }
+
+    public Auth authenticateCookie(RealmModel realm, HttpHeaders headers) {
+        return authenticateCookie(realm, headers, cookieName, true);
+    }
+
+    public Auth authenticate(RealmModel realm, HttpHeaders headers) {
+        Auth auth = authenticateCookie(realm, headers);
+        if (auth != null) return auth;
+        return authenticateBearerToken(realm, headers);
+    }
+
+    private Auth authenticateCookie(RealmModel realm, HttpHeaders headers, String cookieName, boolean checkActive) {
+        logger.info("authenticateCookie");
+        Cookie cookie = headers.getCookies().get(cookieName);
+        if (cookie == null) {
+            logger.info("authenticateCookie could not find cookie: {0}", cookieName);
+            return null;
+        }
+
+        String tokenString = cookie.getValue();
+        try {
+            AccessToken token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), realm.getName(), checkActive);
+            logger.info("token verified");
+            if (checkActive && !token.isActive()) {
+                logger.info("cookie expired");
+                expireCookie(cookie.getName(), cookie.getPath());
+                return null;
+            }
+
+            UserModel user = realm.getUserById(token.getSubject());
+            if (user == null || !user.isEnabled()) {
+                logger.info("Unknown user in cookie");
+                expireCookie(cookie.getName(), cookie.getPath());
+                return null;
+            }
+
+            UserModel client = null;
+            if (token.getIssuedFor() != null) {
+                client = realm.getUser(token.getIssuedFor());
+                if (client == null || !client.isEnabled()) {
+                    logger.info("Unknown client in cookie");
+                    expireCookie(cookie.getName(), cookie.getPath());
+                    return null;
+                }
+            }
+
+            return new Auth(realm, user, client);
+        } catch (VerificationException e) {
+            logger.info("Failed to verify cookie", e);
+            expireCookie(cookie.getName(), cookie.getPath());
+        }
+        return null;
+    }
+
+    private Auth authenticateBearerToken(RealmModel realm, HttpHeaders headers) {
+        String tokenString;
+        String authHeader = headers.getHeaderString(HttpHeaders.AUTHORIZATION);
+        if (authHeader == null) {
+            return null;
+        } else {
+            String[] split = authHeader.trim().split("\\s+");
+            if (split == null || split.length != 2) throw new NotAuthorizedException("Bearer");
+            if (!split[0].equalsIgnoreCase("Bearer")) throw new NotAuthorizedException("Bearer");
+            tokenString = split[1];
+        }
+
+        try {
+            AccessToken token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), realm.getName());
+            if (!token.isActive()) {
+                throw new NotAuthorizedException("token_expired");
+            }
+
+            UserModel user = realm.getUserById(token.getSubject());
+            if (user == null || !user.isEnabled()) {
+                throw new NotAuthorizedException("invalid_user");
+            }
+
+            UserModel client = null;
+            if (token.getIssuedFor() != null) {
+                client = realm.getUser(token.getIssuedFor());
+                if (client == null || !client.isEnabled()) {
+                    throw new NotAuthorizedException("invalid_user");
+                }
+            }
+
+            return new Auth(token, user, client);
+        } catch (VerificationException e) {
+            logger.error("Failed to verify token", e);
+            throw new NotAuthorizedException("invalid_token");
+        }
+    }
+
+}
diff --git a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
index 49ea96a..337dcf0 100755
--- a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
+++ b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
@@ -1,6 +1,7 @@
 package org.keycloak.services.managers;
 
 import org.jboss.resteasy.logging.Logger;
+import org.keycloak.models.AdminRoles;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
@@ -62,7 +63,9 @@ public class ApplianceBootstrap {
         adminConsole.setBaseUrl("/auth/admin/index.html");
         adminConsole.setEnabled(true);
 
-        RoleModel adminRole = adminConsole.addRole(Constants.ADMIN_CONSOLE_ADMIN_ROLE);
+        RoleModel adminRole = realm.getRole(AdminRoles.ADMIN);
+
+        adminConsole.addScope(adminRole);
 
         UserModel adminUser = realm.addUser("admin");
         adminUser.setEnabled(true);
@@ -74,7 +77,7 @@ public class ApplianceBootstrap {
 
         realm.grantRole(adminUser, adminRole);
 
-        ApplicationModel accountApp = realm.getApplicationNameMap().get(Constants.ACCOUNT_APPLICATION);
+        ApplicationModel accountApp = realm.getApplicationNameMap().get(Constants.ACCOUNT_MANAGEMENT_APP);
         for (String r : accountApp.getDefaultRoles()) {
             realm.grantRole(adminUser, accountApp.getRole(r));
         }
diff --git a/services/src/main/java/org/keycloak/services/managers/Auth.java b/services/src/main/java/org/keycloak/services/managers/Auth.java
new file mode 100644
index 0000000..3a2b21c
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/managers/Auth.java
@@ -0,0 +1,138 @@
+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;
+    private final UserModel user;
+    private final UserModel client;
+
+    public Auth(RealmModel realm, UserModel user, UserModel client) {
+        this.cookie = true;
+        this.realm = realm;
+        this.token = null;
+
+        this.user = user;
+        this.client = client;
+    }
+
+    public Auth(AccessToken token, UserModel user, UserModel client) {
+        this.cookie = false;
+        this.token = token;
+        this.realm = null;
+
+        this.user = user;
+        this.client = client;
+    }
+
+    public boolean isCookie() {
+        return cookie;
+    }
+
+    public RealmModel getRealm() {
+        return realm;
+    }
+
+    public UserModel getUser() {
+        return user;
+    }
+
+    public UserModel getClient() {
+        return client;
+    }
+
+    public AccessToken getToken() {
+        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)  {
+            return realm.hasRole(user, realm.getRole(role));
+        } else {
+            return token.getRealmAccess() != null && token.getRealmAccess().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 has(ApplicationModel app, String role) {
+        if (cookie) {
+            return realm.hasRole(user, app.getRole(role));
+        } else {
+            AccessToken.Access access = token.getResourceAccess(app.getName());
+            return access != null && access.isUserInRole(role);
+        }
+    }
+
+    public boolean hasOneOf(String app, String... roles) {
+        for (String r : roles) {
+            if (has(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/managers/AuthenticationManager.java b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
index b82f585..90ab901 100755
--- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
@@ -14,11 +14,8 @@ import org.keycloak.models.UserModel;
 import org.keycloak.models.utils.KeycloakModelUtils;
 import org.keycloak.representations.AccessToken;
 import org.keycloak.representations.idm.CredentialRepresentation;
-import org.keycloak.services.resources.AccountService;
-import org.keycloak.services.resources.admin.AdminService;
 import org.keycloak.services.resources.RealmsResource;
 
-import javax.ws.rs.NotAuthorizedException;
 import javax.ws.rs.core.Cookie;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MultivaluedMap;
@@ -59,19 +56,6 @@ public class AuthenticationManager {
         return createLoginCookie(realm, user, null, cookieName, cookiePath, rememberMe);
     }
 
-    public NewCookie createSaasIdentityCookie(RealmModel realm, UserModel user, UriInfo uriInfo) {
-        String cookieName = AdminService.SAAS_IDENTITY_COOKIE;
-        URI uri = AdminService.saasCookiePath(uriInfo).build();
-        String cookiePath = uri.getRawPath();
-        return createLoginCookie(realm, user, null, cookieName, cookiePath, false);
-    }
-
-    public NewCookie createAccountIdentityCookie(RealmModel realm, UserModel user, UserModel client, URI uri) {
-        String cookieName = AccountService.ACCOUNT_IDENTITY_COOKIE;
-        String cookiePath = uri.getRawPath();
-        return createLoginCookie(realm, user, client, cookieName, cookiePath, false);
-    }
-
     protected NewCookie createLoginCookie(RealmModel realm, UserModel user, UserModel client, String cookieName, String cookiePath, boolean rememberMe) {
         AccessToken identityToken = createIdentityToken(realm, user);
         if (client != null) {
@@ -104,7 +88,6 @@ public class AuthenticationManager {
         return encodedToken;
     }
 
-
     public void expireIdentityCookie(RealmModel realm, UriInfo uriInfo) {
         logger.debug("Expiring identity cookie");
         String path = getIdentityCookiePath(realm, uriInfo);
@@ -123,17 +106,6 @@ public class AuthenticationManager {
         return uri.getRawPath();
     }
 
-    public void expireSaasIdentityCookie(UriInfo uriInfo) {
-        URI uri = AdminService.saasCookiePath(uriInfo).build();
-        String cookiePath = uri.getRawPath();
-        expireCookie(AdminService.SAAS_IDENTITY_COOKIE, cookiePath);
-    }
-
-    public void expireAccountIdentityCookie(URI uri) {
-        String cookiePath = uri.getRawPath();
-        expireCookie(AccountService.ACCOUNT_IDENTITY_COOKIE, cookiePath);
-    }
-
     public void expireCookie(String cookieName, String path) {
         HttpResponse response = ResteasyProviderFactory.getContextData(HttpResponse.class);
         if (response == null) {
@@ -149,42 +121,13 @@ public class AuthenticationManager {
         return authenticateIdentityCookie(realm, uriInfo, headers, true);
     }
 
-
     public UserModel authenticateIdentityCookie(RealmModel realm, UriInfo uriInfo, HttpHeaders headers, boolean checkActive) {
         logger.info("authenticateIdentityCookie");
         String cookieName = KEYCLOAK_IDENTITY_COOKIE;
-        Auth auth = authenticateIdentityCookie(realm, uriInfo, headers, cookieName, checkActive);
-        return auth != null ? auth.getUser() : null;
-    }
-
-    public UserModel authenticateSaasIdentityCookie(RealmModel realm, UriInfo uriInfo, HttpHeaders headers) {
-        String cookieName = AdminService.SAAS_IDENTITY_COOKIE;
-        Auth auth = authenticateIdentityCookie(realm, uriInfo, headers, cookieName, true);
-        return auth != null ? auth.getUser() : null;
+        return authenticateIdentityCookie(realm, uriInfo, headers, cookieName, checkActive);
     }
 
-    public Auth authenticateAccountIdentityCookie(RealmModel realm, UriInfo uriInfo, HttpHeaders headers) {
-        String cookieName = AccountService.ACCOUNT_IDENTITY_COOKIE;
-        return authenticateIdentityCookie(realm, uriInfo, headers, cookieName, true);
-    }
-
-    public UserModel authenticateSaasIdentity(RealmModel realm, UriInfo uriInfo, HttpHeaders headers) {
-        UserModel user = authenticateSaasIdentityCookie(realm, uriInfo, headers);
-        if (user != null) return user;
-
-        Auth auth = authenticateBearerToken(realm, headers);
-        return auth != null ? auth.getUser() : null;
-    }
-
-    public Auth authenticateAccountIdentity(RealmModel realm, UriInfo uriInfo, HttpHeaders headers) {
-        Auth auth = authenticateAccountIdentityCookie(realm, uriInfo, headers);
-        if (auth != null) return auth;
-
-        return authenticateBearerToken(realm, headers);
-    }
-
-
-    protected Auth authenticateIdentityCookie(RealmModel realm, UriInfo uriInfo, HttpHeaders headers, String cookieName, boolean checkActive) {
+    protected UserModel authenticateIdentityCookie(RealmModel realm, UriInfo uriInfo, HttpHeaders headers, String cookieName, boolean checkActive) {
         logger.info("authenticateIdentityCookie");
         Cookie cookie = headers.getCookies().get(cookieName);
         if (cookie == null) {
@@ -202,27 +145,14 @@ public class AuthenticationManager {
                 return null;
             }
 
-            Auth auth = new Auth(token);
-
             UserModel user = realm.getUserById(token.getSubject());
             if (user == null || !user.isEnabled()) {
                 logger.info("Unknown user in identity cookie");
                 expireIdentityCookie(realm, uriInfo);
                 return null;
             }
-            auth.setUser(user);
 
-            if (token.getIssuedFor() != null) {
-                UserModel client = realm.getUser(token.getIssuedFor());
-                if (client == null || !client.isEnabled()) {
-                    logger.info("Unknown client in identity cookie");
-                    expireIdentityCookie(realm, uriInfo);
-                    return null;
-                }
-                auth.setClient(client);
-            }
-
-            return auth;
+            return user;
         } catch (VerificationException e) {
             logger.info("Failed to verify identity cookie", e);
             expireCookie(cookie.getName(), cookie.getPath());
@@ -230,49 +160,6 @@ public class AuthenticationManager {
         return null;
     }
 
-    public Auth authenticateBearerToken(RealmModel realm, HttpHeaders headers) {
-        String tokenString = null;
-        String authHeader = headers.getHeaderString(HttpHeaders.AUTHORIZATION);
-        if (authHeader == null) {
-            return null;
-        } else {
-            String[] split = authHeader.trim().split("\\s+");
-            if (split == null || split.length != 2) throw new NotAuthorizedException("Bearer");
-            if (!split[0].equalsIgnoreCase("Bearer")) throw new NotAuthorizedException("Bearer");
-            tokenString = split[1];
-        }
-
-
-        try {
-            AccessToken token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), realm.getName());
-            if (!token.isActive()) {
-                throw new NotAuthorizedException("token_expired");
-            }
-
-            Auth auth = new Auth(token);
-
-            UserModel user = realm.getUserById(token.getSubject());
-            if (user == null || !user.isEnabled()) {
-                throw new NotAuthorizedException("invalid_user");
-            }
-            auth.setUser(user);
-
-            if (token.getIssuedFor() != null) {
-                UserModel client = realm.getUser(token.getIssuedFor());
-                if (client == null || !client.isEnabled()) {
-                    throw new NotAuthorizedException("invalid_user");
-                }
-                auth.setClient(client);
-            }
-
-            return auth;
-        } catch (VerificationException e) {
-            logger.error("Failed to verify token", e);
-            throw new NotAuthorizedException("invalid_token");
-        }
-    }
-
-
     public AuthenticationStatus authenticateForm(RealmModel realm, UserModel user, MultivaluedMap<String, String> formData) {
         if (user == null) {
             logger.debug("Not Authenticated! Incorrect user name");
@@ -356,34 +243,4 @@ public class AuthenticationManager {
         SUCCESS, ACCOUNT_DISABLED, ACTIONS_REQUIRED, INVALID_USER, INVALID_CREDENTIALS, MISSING_PASSWORD, MISSING_TOTP, FAILED
     }
 
-    public static class Auth {
-        private AccessToken token;
-        private UserModel user;
-        private UserModel client;
-
-        public Auth(AccessToken token) {
-            this.token = token;
-        }
-
-        public AccessToken getToken() {
-            return token;
-        }
-
-        public UserModel getUser() {
-            return user;
-        }
-
-        public UserModel getClient() {
-            return client;
-        }
-
-        void setUser(UserModel user) {
-            this.user = user;
-        }
-
-        void setClient(UserModel client) {
-            this.client = client;
-        }
-    }
-
 }
diff --git a/services/src/main/java/org/keycloak/services/managers/ModelToRepresentation.java b/services/src/main/java/org/keycloak/services/managers/ModelToRepresentation.java
index 9bf9142..303cd94 100755
--- a/services/src/main/java/org/keycloak/services/managers/ModelToRepresentation.java
+++ b/services/src/main/java/org/keycloak/services/managers/ModelToRepresentation.java
@@ -85,7 +85,7 @@ public class ModelToRepresentation {
             rep.setPasswordPolicy(realm.getPasswordPolicy().toString());
         }
 
-        ApplicationModel accountManagementApplication = realm.getApplicationNameMap().get(Constants.ACCOUNT_APPLICATION);
+        ApplicationModel accountManagementApplication = realm.getApplicationNameMap().get(Constants.ACCOUNT_MANAGEMENT_APP);
 
         List<String> defaultRoles = realm.getDefaultRoles();
         if (!defaultRoles.isEmpty()) {
diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
index 4828002..ca71051 100755
--- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
@@ -1,6 +1,8 @@
 package org.keycloak.services.managers;
 
 import org.jboss.resteasy.logging.Logger;
+import org.keycloak.models.AccountRoles;
+import org.keycloak.models.AdminRoles;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
@@ -59,7 +61,6 @@ public class RealmManager {
         return identitySession.getRealmByName(name);
     }
 
-
     public RealmModel createRealm(String name) {
         return createRealm(name, name);
     }
@@ -71,13 +72,31 @@ public class RealmManager {
         realm.addRole(Constants.APPLICATION_ROLE);
         realm.addRole(Constants.IDENTITY_REQUESTER_ROLE);
 
+        setupAdminManagement(realm);
         setupAccountManagement(realm);
+
         realm.addRequiredOAuthClientCredential(UserCredentialModel.SECRET);
         realm.addRequiredResourceCredential(UserCredentialModel.SECRET);
 
         return realm;
     }
 
+    public boolean removeRealm(RealmModel realm) {
+        boolean removed = identitySession.removeRealm(realm.getId());
+
+        RealmModel adminRealm = getKeycloakAdminstrationRealm();
+        RoleModel adminRole = adminRealm.getRole(AdminRoles.ADMIN);
+
+        ApplicationModel realmAdminApp = adminRealm.getApplicationByName(AdminRoles.getAdminApp(realm));
+        for (RoleModel r : realmAdminApp.getRoles()) {
+            adminRole.removeCompositeRole(r);
+        }
+
+        adminRealm.removeApplication(realmAdminApp.getId());
+
+        return removed;
+    }
+
     public void generateRealmKeys(RealmModel realm) {
         KeyPair keyPair = null;
         try {
@@ -134,19 +153,41 @@ public class RealmManager {
         }
     }
 
+    private void setupAdminManagement(RealmModel realm) {
+        RealmModel adminRealm;
+        RoleModel adminRole;
+
+        if (realm.getName().equals(Constants.ADMIN_REALM)) {
+            adminRealm = realm;
+
+            adminRole = realm.addRole(AdminRoles.ADMIN);
+        } else {
+            adminRealm = identitySession.getRealmByName(Constants.ADMIN_REALM);
+            adminRole = adminRealm.getRole(AdminRoles.ADMIN);
+        }
+
+        ApplicationManager applicationManager = new ApplicationManager(new RealmManager(identitySession));
+        ApplicationModel realmAdminApp = applicationManager.createApplication(adminRealm, AdminRoles.getAdminApp(realm));
+
+        for (String r : AdminRoles.ALL_REALM_ROLES) {
+            RoleModel role = realmAdminApp.addRole(r);
+            adminRole.addCompositeRole(role);
+        }
+    }
+
     private void setupAccountManagement(RealmModel realm) {
-        ApplicationModel application = realm.getApplicationNameMap().get(Constants.ACCOUNT_APPLICATION);
+        ApplicationModel application = realm.getApplicationNameMap().get(Constants.ACCOUNT_MANAGEMENT_APP);
         if (application == null) {
-            application = new ApplicationManager(this).createApplication(realm, Constants.ACCOUNT_APPLICATION);
+            application = new ApplicationManager(this).createApplication(realm, Constants.ACCOUNT_MANAGEMENT_APP);
             application.setEnabled(true);
 
-            application.addDefaultRole(Constants.ACCOUNT_PROFILE_ROLE);
-            application.addDefaultRole(Constants.ACCOUNT_MANAGE_ROLE);
-
+            for (String role : AccountRoles.ALL) {
+                application.addDefaultRole(role);
+            }
         }
     }
 
-    public RealmModel importRealm(RealmRepresentation rep, UserModel realmCreator) {
+    public RealmModel importRealm(RealmRepresentation rep) {
         String id = rep.getId();
         if (id == null) {
             id = KeycloakModelUtils.generateId();
@@ -299,7 +340,6 @@ public class RealmManager {
         }
 
 
-
         if (rep.getRoleMappings() != null) {
             for (UserRoleMappingRepresentation mapping : rep.getRoleMappings()) {
                 UserModel user = userMap.get(mapping.getUsername());
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 12c167a..407d2c9 100755
--- a/services/src/main/java/org/keycloak/services/resources/AccountService.java
+++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java
@@ -23,7 +23,6 @@ package org.keycloak.services.resources;
 
 import org.jboss.resteasy.logging.Logger;
 import org.jboss.resteasy.spi.HttpRequest;
-import org.keycloak.AbstractOAuthClient;
 import org.keycloak.account.Account;
 import org.keycloak.account.AccountLoader;
 import org.keycloak.account.AccountPages;
@@ -32,10 +31,10 @@ import org.keycloak.jose.jws.JWSInput;
 import org.keycloak.jose.jws.crypto.RSAProvider;
 import org.keycloak.models.*;
 import org.keycloak.models.utils.TimeBasedOTP;
-import org.keycloak.representations.AccessToken;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.services.managers.AccessCodeEntry;
-import org.keycloak.services.managers.AuthenticationManager;
+import org.keycloak.services.managers.AppAuthManager;
+import org.keycloak.services.managers.Auth;
 import org.keycloak.services.managers.ModelToRepresentation;
 import org.keycloak.services.managers.TokenManager;
 import org.keycloak.services.messages.Messages;
@@ -68,23 +67,23 @@ public class AccountService {
     @Context
     private UriInfo uriInfo;
 
-    private AuthenticationManager authManager = new AuthenticationManager();
+    private AppAuthManager authManager;
 
     private ApplicationModel application;
 
-    private TokenManager tokenManager;
-
     public AccountService(RealmModel realm, ApplicationModel application, TokenManager tokenManager) {
         this.realm = realm;
         this.application = application;
-        this.tokenManager = tokenManager;
+        this.authManager =  new AppAuthManager("KEYCLOAK_ACCOUNT_IDENTITY", tokenManager);
     }
 
     private Response forwardToPage(String path, AccountPages page) {
-        AuthenticationManager.Auth auth = getAuth(false);
+        Auth auth = getAuth(false);
         if (auth != null) {
-            if (!hasAccess(auth)) {
-                return noAccess();
+            try {
+                auth.require(application, AccountRoles.MANAGE_ACCOUNT);
+            } catch (ForbiddenException e) {
+                return Flows.forms(realm, request, uriInfo).setError("No access").createErrorPage();
             }
 
             Account account = AccountLoader.load().createAccount(uriInfo).setRealm(realm).setUser(auth.getUser());
@@ -100,10 +99,6 @@ public class AccountService {
         }
     }
 
-    private Response noAccess() {
-        return Flows.forms(realm, request, uriInfo).setError("No access").createErrorPage();
-    }
-
     @Path("/")
     @OPTIONS
     public Response accountPreflight() {
@@ -117,10 +112,9 @@ public class AccountService {
         if (types.contains(MediaType.WILDCARD_TYPE) || (types.contains(MediaType.TEXT_HTML_TYPE))) {
             return forwardToPage(null, AccountPages.ACCOUNT);
         } else if (types.contains(MediaType.APPLICATION_JSON_TYPE)) {
-            AuthenticationManager.Auth auth = getAuth(true);
-            if (!hasAccess(auth, Constants.ACCOUNT_PROFILE_ROLE)) {
-                return Response.status(Response.Status.FORBIDDEN).build();
-            }
+            Auth auth = getAuth(true);
+            auth.requireOneOf(application, AccountRoles.MANAGE_ACCOUNT, AccountRoles.VIEW_PROFILE);
+
             return Cors.add(request, Response.ok(ModelToRepresentation.toRepresentation(auth.getUser()))).auth().allowedOrigins(auth.getClient()).build();
         } else {
             return Response.notAcceptable(Variant.VariantListBuilder.newInstance().mediaTypes(MediaType.TEXT_HTML_TYPE, MediaType.APPLICATION_JSON_TYPE).build()).build();
@@ -143,10 +137,8 @@ public class AccountService {
     @POST
     @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
     public Response processAccountUpdate(final MultivaluedMap<String, String> formData) {
-        AuthenticationManager.Auth auth = getAuth(true);
-        if (!hasAccess(auth)) {
-            return noAccess();
-        }
+        Auth auth = getAuth(true);
+        auth.require(application, AccountRoles.MANAGE_ACCOUNT);
 
         UserModel user = auth.getUser();
 
@@ -167,10 +159,8 @@ public class AccountService {
     @Path("totp-remove")
     @GET
     public Response processTotpRemove() {
-        AuthenticationManager.Auth auth = getAuth(true);
-        if (!hasAccess(auth)) {
-            return noAccess();
-        }
+        Auth auth = getAuth(true);
+        auth.require(application, AccountRoles.MANAGE_ACCOUNT);
 
         UserModel user = auth.getUser();
         user.setTotp(false);
@@ -183,10 +173,8 @@ public class AccountService {
     @POST
     @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
     public Response processTotpUpdate(final MultivaluedMap<String, String> formData) {
-        AuthenticationManager.Auth auth = getAuth(true);
-        if (!hasAccess(auth)) {
-            return noAccess();
-        }
+        Auth auth = getAuth(true);
+        auth.require(application, AccountRoles.MANAGE_ACCOUNT);
 
         UserModel user = auth.getUser();
 
@@ -215,10 +203,8 @@ public class AccountService {
     @POST
     @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
     public Response processPasswordUpdate(final MultivaluedMap<String, String> formData) {
-        AuthenticationManager.Auth auth = getAuth(true);
-        if (!hasAccess(auth)) {
-            return noAccess();
-        }
+        Auth auth = getAuth(true);
+        auth.require(application, AccountRoles.MANAGE_ACCOUNT);
 
         UserModel user = auth.getUser();
 
@@ -285,61 +271,25 @@ public class AccountService {
                 throw new BadRequestException();
             }
 
-            JWSInput input = new JWSInput(code);
-            boolean verifiedCode = false;
-            try {
-                verifiedCode = RSAProvider.verify(input, realm.getPublicKey());
-            } catch (Exception ignored) {
-                logger.debug("Failed to verify signature", ignored);
-            }
-            if (!verifiedCode) {
-                logger.debug("unverified access code");
-                throw new BadRequestException();
-            }
-            String key = input.readContentAsString();
-            AccessCodeEntry accessCode = tokenManager.pullAccessCode(key);
-            if (accessCode == null) {
-                logger.debug("bad access code");
-                throw new BadRequestException();
-            }
-            if (accessCode.isExpired()) {
-                logger.debug("access code expired");
-                throw new BadRequestException();
-            }
-            if (!accessCode.getToken().isActive()) {
-                logger.debug("access token expired");
-                throw new BadRequestException();
-            }
-            if (!accessCode.getRealm().getId().equals(realm.getId())) {
-                logger.debug("bad realm");
-                throw new BadRequestException();
-
-            }
-            if (!client.getLoginName().equals(accessCode.getClient().getLoginName())) {
-                logger.debug("bad client");
-                throw new BadRequestException();
-            }
-
             URI accountUri = Urls.accountBase(uriInfo.getBaseUri()).path("/").build(realm.getName());
             URI redirectUri = path != null ? accountUri.resolve(path) : accountUri;
             if (referrer != null) {
                 redirectUri = redirectUri.resolve("?referrer=" + referrer);
             }
 
-            NewCookie cookie = authManager.createAccountIdentityCookie(realm, accessCode.getUser(), client, Urls.accountBase(uriInfo.getBaseUri()).build(realm.getName()));
+            NewCookie cookie = authManager.createCookie(realm, client, code, Urls.accountBase(uriInfo.getBaseUri()).build(realm.getName()));
             return Response.status(302).cookie(cookie).location(redirectUri).build();
         } finally {
-            authManager.expireCookie(AbstractOAuthClient.OAUTH_TOKEN_REQUEST_STATE, uriInfo.getAbsolutePath().getRawPath());
+            authManager.expireCookie(Urls.accountBase(uriInfo.getBaseUri()).build(realm.getName()));
         }
     }
 
     @Path("logout")
     @GET
     public Response logout() {
-        // TODO Should use single-sign out via TokenService
         URI baseUri = Urls.accountBase(uriInfo.getBaseUri()).build(realm.getName());
         authManager.expireIdentityCookie(realm, uriInfo);
-        authManager.expireAccountIdentityCookie(baseUri);
+        authManager.expireCookie(baseUri);
         return Response.status(302).location(baseUri).build();
     }
 
@@ -348,7 +298,7 @@ public class AccountService {
         String authUrl = Urls.realmLoginPage(uriInfo.getBaseUri(), realm.getName()).toString();
         oauth.setAuthUrl(authUrl);
 
-        oauth.setClientId(Constants.ACCOUNT_APPLICATION);
+        oauth.setClientId(Constants.ACCOUNT_MANAGEMENT_APP);
 
         UriBuilder uriBuilder = Urls.accountPageBuilder(uriInfo.getBaseUri()).path(AccountService.class, "loginRedirect");
 
@@ -368,42 +318,14 @@ public class AccountService {
         return oauth.redirect(uriInfo, accountUri.toString());
     }
 
-    private AuthenticationManager.Auth getAuth(boolean error) {
-        AuthenticationManager.Auth auth = authManager.authenticateAccountIdentity(realm, uriInfo, headers);
+    private Auth getAuth(boolean error) {
+        Auth auth = authManager.authenticate(realm, headers);
         if (auth == null && error) {
             throw new ForbiddenException();
         }
         return auth;
     }
 
-    private boolean hasAccess(AuthenticationManager.Auth auth) {
-        return hasAccess(auth, null);
-    }
-
-    private boolean hasAccess(AuthenticationManager.Auth auth, String role) {
-        UserModel client = auth.getClient();
-        if (realm.hasRole(client, realm.getRole(Constants.APPLICATION_ROLE))) {
-            // Tokens from cookies don't have roles
-            UserModel user = auth.getUser();
-            if (hasRole(user, Constants.ACCOUNT_MANAGE_ROLE) || (role != null && hasRole(user, role))) {
-                return true;
-            }
-        }
-
-        AccessToken.Access access = auth.getToken().getResourceAccess(application.getName());
-        if (access != null) {
-            if (access.isUserInRole(Constants.ACCOUNT_MANAGE_ROLE) || (role != null && access.isUserInRole(role))) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    private boolean hasRole(UserModel user, String role) {
-        return realm.hasRole(user, application.getRole(role));
-    }
-
     private String getReferrer() {
         String referrer = uriInfo.getQueryParameters().getFirst("referrer");
         if (referrer != null) {
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 8665803..7a5719a 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
@@ -1,49 +1,44 @@
 package org.keycloak.services.resources.admin;
 
+import org.codehaus.jackson.annotate.JsonProperty;
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.logging.Logger;
 import org.jboss.resteasy.spi.HttpRequest;
 import org.jboss.resteasy.spi.HttpResponse;
-import org.jboss.resteasy.spi.NotImplementedYetException;
-import org.keycloak.AbstractOAuthClient;
 import org.keycloak.jaxrs.JaxrsOAuthClient;
-import org.keycloak.jose.jws.JWSInput;
-import org.keycloak.jose.jws.crypto.RSAProvider;
+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.models.RoleModel;
 import org.keycloak.models.UserModel;
-import org.keycloak.services.managers.AccessCodeEntry;
-import org.keycloak.services.managers.AuthenticationManager;
-import org.keycloak.services.managers.AuthenticationManager.AuthenticationStatus;
+import org.keycloak.services.managers.AppAuthManager;
+import org.keycloak.services.managers.Auth;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.managers.TokenManager;
-import org.keycloak.services.messages.Messages;
 import org.keycloak.services.resources.TokenService;
 import org.keycloak.services.resources.flows.Flows;
-import org.keycloak.services.resources.flows.OAuthFlows;
 
-import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
 import javax.ws.rs.NotAuthorizedException;
 import javax.ws.rs.NotFoundException;
-import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.container.ResourceContext;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.NewCookie;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriBuilder;
 import javax.ws.rs.core.UriInfo;
 import javax.ws.rs.ext.Providers;
 import java.net.URI;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@@ -52,8 +47,6 @@ import java.net.URI;
 @Path("/admin")
 public class AdminService {
     protected static final Logger logger = Logger.getLogger(AdminService.class);
-    public static final String REALM_CREATOR_ROLE = "realm-creator";
-    public static final String SAAS_IDENTITY_COOKIE = "KEYCLOAK_SAAS_IDENTITY";
 
     @Context
     protected UriInfo uriInfo;
@@ -73,25 +66,32 @@ public class AdminService {
     @Context
     protected Providers providers;
 
-
     protected String adminPath = "/admin/index.html";
-    protected AuthenticationManager authManager = new AuthenticationManager();
+    protected AppAuthManager authManager;
     protected TokenManager tokenManager;
 
     public AdminService(TokenManager tokenManager) {
         this.tokenManager = tokenManager;
+        this.authManager = new AppAuthManager("KEYCLOAK_ADMIN_CONSOLE_IDENTITY", tokenManager);
     }
 
     public static class WhoAmI {
         protected String userId;
         protected String displayName;
 
+        @JsonProperty("admin")
+        protected boolean admin;
+        @JsonProperty("realm_access")
+        protected Map<String, Set<String>> realmAccess = new HashMap<String, Set<String>>();
+
         public WhoAmI() {
         }
 
-        public WhoAmI(String userId, String displayName) {
+        public WhoAmI(String userId, String displayName, boolean admin, Map<String, Set<String>> realmAccess) {
             this.userId = userId;
             this.displayName = displayName;
+            this.admin = admin;
+            this.realmAccess = realmAccess;
         }
 
         public String getUserId() {
@@ -109,6 +109,22 @@ public class AdminService {
         public void setDisplayName(String displayName) {
             this.displayName = displayName;
         }
+
+        public boolean isAdmin() {
+            return admin;
+        }
+
+        public void setAdmin(boolean admin) {
+            this.admin = admin;
+        }
+
+        public Map<String, Set<String>> getRealmAccess() {
+            return realmAccess;
+        }
+
+        public void setRealmAccess(Map<String, Set<String>> realmAccess) {
+            this.realmAccess = realmAccess;
+        }
     }
 
     @Path("keepalive")
@@ -120,11 +136,11 @@ public class AdminService {
         RealmModel realm = getAdminstrationRealm(realmManager);
         if (realm == null)
             throw new NotFoundException();
-        UserModel user = authManager.authenticateSaasIdentityCookie(realm, uriInfo, headers);
-        if (user == null) {
+        Auth auth = authManager.authenticateCookie(realm, headers);
+        if (auth == null) {
             return Response.status(401).build();
         }
-        NewCookie refreshCookie = authManager.createSaasIdentityCookie(realm, user, uriInfo);
+        NewCookie refreshCookie = authManager.createRefreshCookie(realm, auth.getUser(), auth.getClient(), AdminService.saasCookiePath(uriInfo).build());
         return Response.noContent().cookie(refreshCookie).build();
     }
 
@@ -137,15 +153,50 @@ public class AdminService {
         RealmModel realm = getAdminstrationRealm(realmManager);
         if (realm == null)
             throw new NotFoundException();
-        UserModel user = authManager.authenticateSaasIdentityCookie(realm, uriInfo, headers);
+        Auth auth = authManager.authenticateCookie(realm, headers);
+        UserModel user = auth.getUser();
         if (user == null) {
             return Response.status(401).build();
         }
-        // keycloak is bootstrapped with an admin user with no first/last name, so use login name as display name
-        return Response.ok(new WhoAmI(user.getLoginName(), user.getLoginName())).build();
+
+        String displayName;
+        if (user.getFirstName() != null || user.getLastName() != null) {
+            displayName = user.getFirstName();
+            if (user.getLastName() != null) {
+                displayName = displayName != null ? displayName + " " + user.getLastName() : user.getLastName();
+            }
+        } else {
+            displayName = user.getLoginName();
+        }
+
+        boolean admin = realm.hasRole(user, realm.getRole("admin"));
+
+        Map<String, Set<String>> realmAccess = new HashMap<String, Set<String>>();
+        addRealmAdminAccess(realmAccess, auth.getRealm().getRoleMappings(auth.getUser()));
+
+        return Response.ok(new WhoAmI(user.getId(), displayName, admin, realmAccess)).build();
+    }
+
+    private void addRealmAdminAccess(Map<String, Set<String>> realmAdminAccess, Set<RoleModel> roles) {
+        for (RoleModel r : roles) {
+            if (r.getContainer() instanceof ApplicationModel) {
+                ApplicationModel app = (ApplicationModel) r.getContainer();
+                if (app.getName().endsWith(AdminRoles.APP_SUFFIX)) {
+                    String realm = app.getName().substring(0, app.getName().length() - AdminRoles.APP_SUFFIX.length());
+                    if (!realmAdminAccess.containsKey(realm)) {
+                        realmAdminAccess.put(realm, new HashSet<String>());
+                    }
+                    realmAdminAccess.get(realm).add(r.getName());
+                }
+            }
+
+            if (r.isComposite()) {
+                addRealmAdminAccess(realmAdminAccess, r.getComposites());
+            }
+        }
     }
 
-    @Path("isLoggedIn.js")
+        @Path("isLoggedIn.js")
     @GET
     @Produces("application/javascript")
     @NoCache
@@ -157,7 +208,7 @@ public class AdminService {
             return "var keycloakCookieLoggedIn = false;";
 
         }
-        UserModel user = authManager.authenticateSaasIdentityCookie(realm, uriInfo, headers);
+        UserModel user = authManager.authenticateCookie(realm, headers).getUser();
         if (user == null) {
             return "var keycloakCookieLoggedIn = false;";
         }
@@ -176,23 +227,14 @@ public class AdminService {
     @Path("realms")
     public RealmsAdminResource getRealmsAdmin(@Context final HttpHeaders headers) {
         RealmManager realmManager = new RealmManager(session);
-        RealmModel saasRealm = getAdminstrationRealm(realmManager);
-        if (saasRealm == null)
+        RealmModel adminRealm = getAdminstrationRealm(realmManager);
+        if (adminRealm == null)
             throw new NotFoundException();
-        UserModel admin = authManager.authenticateSaasIdentity(saasRealm, uriInfo, headers);
-        if (admin == null) {
+        Auth auth = authManager.authenticate(adminRealm, headers);
+        if (auth == null) {
             throw new NotAuthorizedException("Bearer");
         }
-        ApplicationModel adminConsole = saasRealm.getApplicationNameMap().get(Constants.ADMIN_CONSOLE_APPLICATION);
-        if (adminConsole == null) {
-            throw new NotFoundException();
-        }
-        RoleModel adminRole = adminConsole.getRole(Constants.ADMIN_CONSOLE_ADMIN_ROLE);
-        if (!saasRealm.hasRole(admin, adminRole)) {
-            logger.warn("not a Realm admin");
-            throw new NotAuthorizedException("Bearer");
-        }
-        RealmsAdminResource adminResource = new RealmsAdminResource(admin, tokenManager);
+        RealmsAdminResource adminResource = new RealmsAdminResource(auth, tokenManager);
         resourceContext.initResource(adminResource);
         return adminResource;
     }
@@ -200,35 +242,33 @@ public class AdminService {
     @Path("serverinfo")
     public ServerInfoAdminResource getServerInfo(@Context final HttpHeaders headers) {
         RealmManager realmManager = new RealmManager(session);
-        RealmModel saasRealm = getAdminstrationRealm(realmManager);
-        if (saasRealm == null)
+        RealmModel adminRealm = getAdminstrationRealm(realmManager);
+        if (adminRealm == null)
             throw new NotFoundException();
-        UserModel admin = authManager.authenticateSaasIdentity(saasRealm, uriInfo, headers);
+        Auth auth = authManager.authenticate(adminRealm, headers);
+        UserModel admin = auth.getUser();
         if (admin == null) {
             throw new NotAuthorizedException("Bearer");
         }
-        ApplicationModel adminConsole = saasRealm.getApplicationNameMap().get(Constants.ADMIN_CONSOLE_APPLICATION);
+        ApplicationModel adminConsole = adminRealm.getApplicationNameMap().get(Constants.ADMIN_CONSOLE_APPLICATION);
         if (adminConsole == null) {
             throw new NotFoundException();
         }
-        RoleModel adminRole = adminConsole.getRole(Constants.ADMIN_CONSOLE_ADMIN_ROLE);
-        if (!saasRealm.hasRole(admin, adminRole)) {
-            logger.warn("not a Realm admin");
-            throw new NotAuthorizedException("Bearer");
-        }
         ServerInfoAdminResource adminResource = new ServerInfoAdminResource();
         resourceContext.initResource(adminResource);
         return adminResource;
     }
 
+    private void expireCookie() {
+        authManager.expireCookie(AdminService.saasCookiePath(uriInfo).build());
+    }
+
     @Path("login")
     @GET
     @NoCache
     public Response loginPage(@QueryParam("path") String path) {
         logger.debug("loginPage ********************** <---");
-        RealmManager realmManager = new RealmManager(session);
-        RealmModel realm = getAdminstrationRealm(realmManager);
-        authManager.expireSaasIdentityCookie(uriInfo);
+        expireCookie();
 
         JaxrsOAuthClient oauth = new JaxrsOAuthClient();
         String authUrl = TokenService.loginPageUrl(uriInfo).build(Constants.ADMIN_REALM).toString();
@@ -259,7 +299,6 @@ public class AdminService {
         URI uri = uriInfo.getBaseUriBuilder().path(AdminService.class).path(AdminService.class, "errorOnLoginRedirect").queryParam("error", message).build();
         URI logout = TokenService.logoutUrl(uriInfo).queryParam("redirect_uri", uri.toString()).build(Constants.ADMIN_REALM);
         return Response.status(302).location(logout).build();
-
     }
 
     @Path("login-redirect")
@@ -279,12 +318,12 @@ public class AdminService {
                 return redirectOnLoginError(error);
             }
             RealmManager realmManager = new RealmManager(session);
-            RealmModel realm = getAdminstrationRealm(realmManager);
-            if (!realm.isEnabled()) {
+            RealmModel adminRealm = getAdminstrationRealm(realmManager);
+            if (!adminRealm.isEnabled()) {
                 logger.debug("realm not enabled");
                 return redirectOnLoginError("realm not enabled");
             }
-            ApplicationModel adminConsole = realm.getApplicationNameMap().get(Constants.ADMIN_CONSOLE_APPLICATION);
+            ApplicationModel adminConsole = adminRealm.getApplicationNameMap().get(Constants.ADMIN_CONSOLE_APPLICATION);
             UserModel adminConsoleUser = adminConsole.getApplicationUser();
             if (!adminConsole.isEnabled() || !adminConsoleUser.isEnabled()) {
                 logger.debug("admin app not enabled");
@@ -301,47 +340,8 @@ public class AdminService {
             }
             new JaxrsOAuthClient().checkStateCookie(uriInfo, headers);
 
-            JWSInput input = new JWSInput(code);
-            boolean verifiedCode = false;
-            try {
-                verifiedCode = RSAProvider.verify(input, realm.getPublicKey());
-            } catch (Exception ignored) {
-                logger.debug("Failed to verify signature", ignored);
-            }
-            if (!verifiedCode) {
-                logger.debug("unverified access code");
-                return redirectOnLoginError("invalid login data");
-            }
-            String key = input.readContentAsString();
-            AccessCodeEntry accessCode = tokenManager.pullAccessCode(key);
-            if (accessCode == null) {
-                logger.debug("bad access code");
-                return redirectOnLoginError("invalid login data");
-            }
-            if (accessCode.isExpired()) {
-                logger.debug("access code expired");
-                return redirectOnLoginError("invalid login data");
-            }
-            if (!accessCode.getToken().isActive()) {
-                logger.debug("access token expired");
-                return redirectOnLoginError("invalid login data");
-            }
-            if (!accessCode.getRealm().getId().equals(realm.getId())) {
-                logger.debug("bad realm");
-                return redirectOnLoginError("invalid login data");
-
-            }
-            if (!adminConsoleUser.getLoginName().equals(accessCode.getClient().getLoginName())) {
-                logger.debug("bad client");
-                return redirectOnLoginError("invalid login data");
-            }
-            RoleModel adminConsoleAdminRole = adminConsole.getRole(Constants.ADMIN_CONSOLE_ADMIN_ROLE);
-            if (!realm.hasRole(accessCode.getUser(), adminConsoleAdminRole)) {
-                logger.debug("not allowed");
-                return redirectOnLoginError("No permission to access console");
-            }
             logger.debug("loginRedirect SUCCESS");
-            NewCookie cookie = authManager.createSaasIdentityCookie(realm, accessCode.getUser(), uriInfo);
+            NewCookie cookie = authManager.createCookie(adminRealm, adminConsoleUser, code, AdminService.saasCookiePath(uriInfo).build());
 
             URI redirectUri = contextRoot(uriInfo).path(adminPath).build();
             if (path != null) {
@@ -349,7 +349,7 @@ public class AdminService {
             }
             return Response.status(302).cookie(cookie).location(redirectUri).build();
         } finally {
-            authManager.expireCookie(AbstractOAuthClient.OAUTH_TOKEN_REQUEST_STATE, uriInfo.getAbsolutePath().getPath());
+            expireCookie();
         }
     }
 
@@ -359,7 +359,7 @@ public class AdminService {
     public Response logout() {
         RealmManager realmManager = new RealmManager(session);
         RealmModel realm = getAdminstrationRealm(realmManager);
-        authManager.expireSaasIdentityCookie(uriInfo);
+        expireCookie();
         authManager.expireIdentityCookie(realm, uriInfo);
 
         return Response.status(302).location(uriInfo.getBaseUriBuilder().path(AdminService.class).path(AdminService.class, "loginPage").build()).build();
@@ -370,42 +370,7 @@ public class AdminService {
     @NoCache
     public void logoutCookie() {
         logger.debug("*** logoutCookie");
-        authManager.expireSaasIdentityCookie(uriInfo);
-    }
-
-    @Path("login")
-    @POST
-    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
-    public Response processLogin(final MultivaluedMap<String, String> formData) {
-        logger.debug("processLogin start");
-        RealmManager realmManager = new RealmManager(session);
-        RealmModel realm = getAdminstrationRealm(realmManager);
-        if (realm == null)
-            throw new NotFoundException();
-        ApplicationModel adminConsole = realm.getApplicationNameMap().get(Constants.ADMIN_CONSOLE_APPLICATION);
-        UserModel adminConsoleUser = adminConsole.getApplicationUser();
-
-        if (!realm.isEnabled()) {
-            throw new NotImplementedYetException();
-        }
-        String username = formData.getFirst("username");
-        UserModel user = realm.getUser(username);
-
-        AuthenticationStatus status = authManager.authenticateForm(realm, user, formData);
-
-        OAuthFlows oauth = Flows.oauth(realm, request, uriInfo, authManager, tokenManager);
-
-        switch (status) {
-            case SUCCESS:
-                NewCookie cookie = authManager.createSaasIdentityCookie(realm, user, uriInfo);
-                return Response.status(302).cookie(cookie).location(contextRoot(uriInfo).path(adminPath).build()).build();
-            case ACCOUNT_DISABLED:
-                return Flows.forms(realm, request, uriInfo).setError(Messages.ACCOUNT_DISABLED).setFormData(formData).createLogin();
-            case ACTIONS_REQUIRED:
-                return oauth.processAccessCode(null, "n", contextRoot(uriInfo).path(adminPath).build().toString(), adminConsoleUser, user);
-            default:
-                return Flows.forms(realm, request, uriInfo).setError(Messages.INVALID_USER).setFormData(formData).createLogin();
-        }
+        expireCookie();
     }
 
     protected RealmModel getAdminstrationRealm(RealmManager realmManager) {
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 2b5e420..5ea0987 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
@@ -2,10 +2,11 @@ package org.keycloak.services.resources.admin;
 
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.logging.Logger;
+import org.keycloak.models.AdminRoles;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserModel;
 import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.services.managers.Auth;
 import org.keycloak.services.managers.ModelToRepresentation;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.managers.TokenManager;
@@ -20,7 +21,7 @@ import javax.ws.rs.core.Context;
  */
 public class RealmAdminResource extends RoleContainerResource {
     protected static final Logger logger = Logger.getLogger(RealmAdminResource.class);
-    protected UserModel admin;
+    protected Auth auth;
     protected RealmModel realm;
     private TokenManager tokenManager;
 
@@ -30,15 +31,17 @@ public class RealmAdminResource extends RoleContainerResource {
     @Context
     protected KeycloakSession session;
 
-    public RealmAdminResource(UserModel admin, RealmModel realm, TokenManager tokenManager) {
+    public RealmAdminResource(Auth auth, RealmModel realm, TokenManager tokenManager) {
         super(realm, realm);
-        this.admin = admin;
+        this.auth = auth;
         this.realm = realm;
         this.tokenManager = tokenManager;
     }
 
     @Path("applications")
     public ApplicationsResource getApplications() {
+        auth.require(AdminRoles.getAdminApp(realm), AdminRoles.MANAGE_APPLICATIONS);
+
         ApplicationsResource applicationsResource = new ApplicationsResource(realm);
         resourceContext.initResource(applicationsResource);
         return applicationsResource;
@@ -46,6 +49,8 @@ public class RealmAdminResource extends RoleContainerResource {
 
     @Path("oauth-clients")
     public OAuthClientsResource getOAuthClients() {
+        auth.require(AdminRoles.getAdminApp(realm), AdminRoles.MANAGE_CLIENTS);
+
         OAuthClientsResource oauth = new OAuthClientsResource(realm, session);
         resourceContext.initResource(oauth);
         return oauth;
@@ -55,26 +60,42 @@ public class RealmAdminResource extends RoleContainerResource {
     @NoCache
     @Produces("application/json")
     public RealmRepresentation getRealm() {
-        return ModelToRepresentation.toRepresentation(realm);
-    }
+        String realmAdminApp = AdminRoles.getAdminApp(realm);
+        if (auth.has(realmAdminApp, AdminRoles.MANAGE_REALM)) {
+            return ModelToRepresentation.toRepresentation(realm);
+        } else {
+            auth.requireOneOf(AdminRoles.getAdminApp(realm), AdminRoles.ALL_REALM_ROLES);
 
+            RealmRepresentation rep = new RealmRepresentation();
+            rep.setId(realm.getId());
+            rep.setRealm(realm.getName());
+
+            return rep;
+        }
+    }
 
     @PUT
     @Consumes("application/json")
     public void updateRealm(final RealmRepresentation rep) {
+        auth.require(AdminRoles.getAdminApp(realm), AdminRoles.MANAGE_REALM);
+
         logger.debug("updating realm: " + realm.getName());
         new RealmManager(session).updateRealm(rep, realm);
     }
 
     @DELETE
     public void deleteRealms() {
-        if (!session.removeRealm(realm.getId())) {
+        auth.require(AdminRoles.getAdminApp(realm), AdminRoles.MANAGE_REALM);
+
+        if (!new RealmManager(session).removeRealm(realm)) {
             throw new NotFoundException();
         }
     }
 
     @Path("users")
     public UsersResource users() {
+        auth.require(AdminRoles.getAdminApp(realm), AdminRoles.MANAGE_USERS);
+
         UsersResource users = new UsersResource(realm, tokenManager);
         resourceContext.initResource(users);
         return users;
@@ -82,12 +103,11 @@ public class RealmAdminResource extends RoleContainerResource {
 
     @Path("roles-by-id")
     public RoleByIdResource rolesById() {
+        auth.require(AdminRoles.getAdminApp(realm), AdminRoles.MANAGE_REALM);
+
         RoleByIdResource resource = new RoleByIdResource(realm);
         resourceContext.initResource(resource);
         return resource;
-
     }
 
-
-
 }
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 48e91f8..f0691d4 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
@@ -5,10 +5,13 @@ import org.jboss.resteasy.logging.Logger;
 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.models.UserModel;
 import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.services.managers.Auth;
 import org.keycloak.services.managers.ModelToRepresentation;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.managers.TokenManager;
@@ -35,11 +38,11 @@ import java.util.Map;
  */
 public class RealmsAdminResource {
     protected static final Logger logger = Logger.getLogger(RealmsAdminResource.class);
-    protected UserModel admin;
+    protected Auth auth;
     protected TokenManager tokenManager;
 
-    public RealmsAdminResource(UserModel admin, TokenManager tokenManager) {
-        this.admin = admin;
+    public RealmsAdminResource(Auth auth, TokenManager tokenManager) {
+        this.auth = auth;
         this.tokenManager = tokenManager;
     }
 
@@ -59,11 +62,19 @@ public class RealmsAdminResource {
     @Produces("application/json")
     public List<RealmRepresentation> getRealms() {
         logger.debug(("getRealms()"));
-        RealmManager realmManager = new RealmManager(session);
-        List<RealmModel> realms = session.getRealms(admin);
+        List<RealmModel> realms = session.getRealms();
         List<RealmRepresentation> reps = new ArrayList<RealmRepresentation>();
         for (RealmModel realm : realms) {
-            reps.add(ModelToRepresentation.toRepresentation(realm));
+            String realmAdminApp = AdminRoles.getAdminApp(realm);
+
+            if (auth.has(realmAdminApp, AdminRoles.MANAGE_REALM)) {
+                reps.add(ModelToRepresentation.toRepresentation(realm));
+            } else if (auth.hasOneOf(realmAdminApp, AdminRoles.ALL_REALM_ROLES)) {
+                RealmRepresentation rep = new RealmRepresentation();
+                rep.setId(realm.getId());
+                rep.setRealm(realm.getName());
+                reps.add(rep);
+            }
         }
         return reps;
     }
@@ -79,13 +90,15 @@ public class RealmsAdminResource {
     @POST
     @Consumes("application/json")
     public Response importRealm(@Context final UriInfo uriInfo, final RealmRepresentation rep) {
+        auth.require(AdminRoles.ADMIN);
+
         logger.debug("importRealm: {0}", rep.getRealm());
         RealmManager realmManager = new RealmManager(session);
         if (realmManager.getRealmByName(rep.getRealm()) != null) {
             return Flows.errors().exists("Realm " + rep.getRealm() + " already exists");
         }
 
-        RealmModel realm = realmManager.importRealm(rep, admin);
+        RealmModel realm = realmManager.importRealm(rep);
         URI location = realmUrl(uriInfo).build(realm.getName());
         logger.debug("imported realm success, sending back: {0}", location.toString());
         return Response.created(location).build();
@@ -94,6 +107,8 @@ public class RealmsAdminResource {
     @POST
     @Consumes(MediaType.MULTIPART_FORM_DATA)
     public Response uploadRealm(MultipartFormDataInput input) throws IOException  {
+        auth.require(AdminRoles.ADMIN);
+
         Map<String, List<InputPart>> uploadForm = input.getFormDataMap();
         List<InputPart> inputParts = uploadForm.get("file");
 
@@ -101,7 +116,7 @@ public class RealmsAdminResource {
         for (InputPart inputPart : inputParts) {
             inputPart.setMediaType(MediaType.APPLICATION_JSON_TYPE);
             RealmRepresentation rep = inputPart.getBody(new GenericType<RealmRepresentation>(){});
-            realmManager.importRealm(rep, admin);
+            realmManager.importRealm(rep);
         }
         return Response.noContent().build();
     }
@@ -113,8 +128,11 @@ public class RealmsAdminResource {
         RealmModel realm = realmManager.getRealmByName(name);
         if (realm == null) throw new NotFoundException("{realm} = " + name);
 
-        RealmAdminResource adminResource = new RealmAdminResource(admin, realm, tokenManager);
+        auth.requireOneOf(AdminRoles.getAdminApp(realm), AdminRoles.ALL_REALM_ROLES);
+
+        RealmAdminResource adminResource = new RealmAdminResource(auth, realm, tokenManager);
         resourceContext.initResource(adminResource);
         return adminResource;
     }
+
 }
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 24cfdc6..2af61a9 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
@@ -23,7 +23,6 @@ import javax.ws.rs.BadRequestException;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
-import javax.ws.rs.InternalServerErrorException;
 import javax.ws.rs.NotFoundException;
 import javax.ws.rs.POST;
 import javax.ws.rs.PUT;
@@ -31,12 +30,10 @@ import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
-import javax.ws.rs.ServerErrorException;
 import javax.ws.rs.container.ResourceContext;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
-import java.net.URI;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -431,7 +428,7 @@ public class UsersResource {
         }
 
         String redirect = Urls.accountBase(uriInfo.getBaseUri()).path("/").build(realm.getName()).toString();
-        String clientId = Constants.ACCOUNT_APPLICATION;
+        String clientId = Constants.ACCOUNT_MANAGEMENT_APP;
         String state = null;
         String scope = null;
 
diff --git a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
index 2338387..3a2ea92 100755
--- a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
@@ -69,7 +69,7 @@ public class RealmsResource {
         RealmManager realmManager = new RealmManager(session);
         RealmModel realm = locateRealm(name, realmManager);
 
-        ApplicationModel application = realm.getApplicationNameMap().get(Constants.ACCOUNT_APPLICATION);
+        ApplicationModel application = realm.getApplicationNameMap().get(Constants.ACCOUNT_MANAGEMENT_APP);
         if (application == null || !application.isEnabled()) {
             logger.debug("account management not enabled");
             throw new NotFoundException();
diff --git a/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java b/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java
index 6fbb6fd..cfcd1f3 100755
--- a/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java
+++ b/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java
@@ -228,7 +228,7 @@ public class KeycloakServer {
         try {
             RealmManager manager = new RealmManager(session);
 
-            RealmModel adminRealm = manager.getRealm(Constants.ADMIN_REALM);
+            RealmModel adminRealm = manager.getKeycloakAdminstrationRealm();
             UserModel admin = adminRealm.getUser("admin");
             admin.removeRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
 
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java
index f520c70..3c96873 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java
@@ -10,6 +10,7 @@ import org.json.JSONObject;
 import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
+import org.keycloak.models.AccountRoles;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserCredentialModel;
@@ -31,8 +32,6 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.UriBuilder;
 import java.io.IOException;
 import java.net.URI;
-import java.util.Collections;
-import java.util.List;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
@@ -53,7 +52,7 @@ public class ProfileTest {
             user.setAttribute("key1", "value1");
             user.setAttribute("key2", "value2");
 
-            ApplicationModel accountApp = appRealm.getApplicationNameMap().get(org.keycloak.models.Constants.ACCOUNT_APPLICATION);
+            ApplicationModel accountApp = appRealm.getApplicationNameMap().get(org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_APP);
 
             UserModel user2 = appRealm.addUser("test-user-no-access@localhost");
             user2.setEnabled(true);
@@ -66,12 +65,12 @@ public class ProfileTest {
             appRealm.updateCredential(user2, creds);
 
             ApplicationModel app = appRealm.getApplicationNameMap().get("test-app");
-            appRealm.addScopeMapping(app.getApplicationUser(), accountApp.getRole(org.keycloak.models.Constants.ACCOUNT_PROFILE_ROLE));
+            appRealm.addScopeMapping(app.getApplicationUser(), accountApp.getRole(AccountRoles.VIEW_PROFILE));
 
             app.getApplicationUser().addWebOrigin("http://localtest.me:8081");
 
             UserModel thirdParty = appRealm.getUser("third-party");
-            appRealm.addScopeMapping(thirdParty, accountApp.getRole(org.keycloak.models.Constants.ACCOUNT_PROFILE_ROLE));
+            appRealm.addScopeMapping(thirdParty, accountApp.getRole(AccountRoles.VIEW_PROFILE));
         }
     });
 
@@ -175,7 +174,7 @@ public class ProfileTest {
 
     @Test
     public void getProfileOAuthClient() throws Exception {
-        oauth.addScope(org.keycloak.models.Constants.ACCOUNT_APPLICATION, org.keycloak.models.Constants.ACCOUNT_PROFILE_ROLE);
+        oauth.addScope(org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_APP, AccountRoles.VIEW_PROFILE);
         oauth.clientId("third-party");
         oauth.doLoginGrant("test-user@localhost", "password");
 
@@ -192,7 +191,7 @@ public class ProfileTest {
 
     @Test
     public void getProfileOAuthClientNoScope() throws Exception {
-        oauth.addScope(org.keycloak.models.Constants.ACCOUNT_APPLICATION);
+        oauth.addScope(org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_APP);
         oauth.clientId("third-party");
         oauth.doLoginGrant("test-user@localhost", "password");
 
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeImportRoleTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeImportRoleTest.java
index 59a4c5e..7a53ae0 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeImportRoleTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeImportRoleTest.java
@@ -90,7 +90,7 @@ public class CompositeImportRoleTest {
 
         AccessToken token = oauth.verifyToken(response.getAccessToken());
 
-        Assert.assertEquals("APP_COMPOSITE_USER", oauth.getProfile(response.getAccessToken()).getUsername());
+        Assert.assertEquals(keycloakRule.getUser("Test", "APP_COMPOSITE_USER").getId(), token.getSubject());
 
         Assert.assertEquals(1, token.getResourceAccess("APP_ROLE_APPLICATION").getRoles().size());
         Assert.assertEquals(1, token.getRealmAccess().getRoles().size());
@@ -115,7 +115,7 @@ public class CompositeImportRoleTest {
 
         AccessToken token = oauth.verifyToken(response.getAccessToken());
 
-        Assert.assertEquals("REALM_APP_COMPOSITE_USER", oauth.getProfile(response.getAccessToken()).getUsername());
+        Assert.assertEquals(keycloakRule.getUser("Test", "REALM_APP_COMPOSITE_USER").getId(), token.getSubject());
 
         Assert.assertEquals(1, token.getResourceAccess("APP_ROLE_APPLICATION").getRoles().size());
         Assert.assertTrue(token.getResourceAccess("APP_ROLE_APPLICATION").isUserInRole("APP_ROLE_1"));
@@ -139,7 +139,7 @@ public class CompositeImportRoleTest {
 
         AccessToken token = oauth.verifyToken(response.getAccessToken());
 
-        Assert.assertEquals("REALM_COMPOSITE_1_USER", oauth.getProfile(response.getAccessToken()).getUsername());
+        Assert.assertEquals(keycloakRule.getUser("Test", "REALM_COMPOSITE_1_USER").getId(), token.getSubject());
 
         Assert.assertEquals(2, token.getRealmAccess().getRoles().size());
         Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_COMPOSITE_1"));
@@ -162,7 +162,7 @@ public class CompositeImportRoleTest {
 
         AccessToken token = oauth.verifyToken(response.getAccessToken());
 
-        Assert.assertEquals("REALM_COMPOSITE_1_USER", oauth.getProfile(response.getAccessToken()).getUsername());
+        Assert.assertEquals(keycloakRule.getUser("Test", "REALM_COMPOSITE_1_USER").getId(), token.getSubject());
 
         Assert.assertEquals(1, token.getRealmAccess().getRoles().size());
         Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1"));
@@ -184,7 +184,7 @@ public class CompositeImportRoleTest {
 
         AccessToken token = oauth.verifyToken(response.getAccessToken());
 
-        Assert.assertEquals("REALM_ROLE_1_USER", oauth.getProfile(response.getAccessToken()).getUsername());
+        Assert.assertEquals(keycloakRule.getUser("Test", "REALM_ROLE_1_USER").getId(), token.getSubject());
 
         Assert.assertEquals(1, token.getRealmAccess().getRoles().size());
         Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1"));
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java
index 6483823..7d6c128 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java
@@ -168,7 +168,7 @@ public class CompositeRoleTest {
 
         AccessToken token = oauth.verifyToken(response.getAccessToken());
 
-        Assert.assertEquals("APP_COMPOSITE_USER", oauth.getProfile(response.getAccessToken()).getUsername());
+        Assert.assertEquals(keycloakRule.getUser("Test", "APP_COMPOSITE_USER").getId(), token.getSubject());
 
         Assert.assertEquals(1, token.getResourceAccess("APP_ROLE_APPLICATION").getRoles().size());
         Assert.assertEquals(1, token.getRealmAccess().getRoles().size());
@@ -193,7 +193,7 @@ public class CompositeRoleTest {
 
         AccessToken token = oauth.verifyToken(response.getAccessToken());
 
-        Assert.assertEquals("REALM_APP_COMPOSITE_USER", oauth.getProfile(response.getAccessToken()).getUsername());
+        Assert.assertEquals(keycloakRule.getUser("Test", "REALM_APP_COMPOSITE_USER").getId(), token.getSubject());
 
         Assert.assertEquals(1, token.getResourceAccess("APP_ROLE_APPLICATION").getRoles().size());
         Assert.assertTrue(token.getResourceAccess("APP_ROLE_APPLICATION").isUserInRole("APP_ROLE_1"));
@@ -217,7 +217,7 @@ public class CompositeRoleTest {
 
         AccessToken token = oauth.verifyToken(response.getAccessToken());
 
-        Assert.assertEquals("REALM_COMPOSITE_1_USER", oauth.getProfile(response.getAccessToken()).getUsername());
+        Assert.assertEquals(keycloakRule.getUser("Test", "REALM_COMPOSITE_1_USER").getId(), token.getSubject());
 
         Assert.assertEquals(2, token.getRealmAccess().getRoles().size());
         Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_COMPOSITE_1"));
@@ -240,7 +240,7 @@ public class CompositeRoleTest {
 
         AccessToken token = oauth.verifyToken(response.getAccessToken());
 
-        Assert.assertEquals("REALM_COMPOSITE_1_USER", oauth.getProfile(response.getAccessToken()).getUsername());
+        Assert.assertEquals(keycloakRule.getUser("Test", "REALM_COMPOSITE_1_USER").getId(), token.getSubject());
 
         Assert.assertEquals(1, token.getRealmAccess().getRoles().size());
         Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1"));
@@ -262,7 +262,7 @@ public class CompositeRoleTest {
 
         AccessToken token = oauth.verifyToken(response.getAccessToken());
 
-        Assert.assertEquals("REALM_ROLE_1_USER", oauth.getProfile(response.getAccessToken()).getUsername());
+        Assert.assertEquals(keycloakRule.getUser("Test", "REALM_ROLE_1_USER").getId(), token.getSubject());
 
         Assert.assertEquals(1, token.getRealmAccess().getRoles().size());
         Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1"));
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AccountTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AccountTest.java
index 4168e9f..0aa9075 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AccountTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AccountTest.java
@@ -21,7 +21,6 @@
  */
 package org.keycloak.testsuite.forms;
 
-import org.apache.http.HttpResponse;
 import org.junit.*;
 import org.keycloak.models.*;
 import org.keycloak.models.utils.TimeBasedOTP;
@@ -35,10 +34,6 @@ import org.keycloak.testsuite.rule.KeycloakRule.KeycloakSetup;
 import org.keycloak.testsuite.rule.WebResource;
 import org.keycloak.testsuite.rule.WebRule;
 import org.openqa.selenium.WebDriver;
-import org.openqa.selenium.WebElement;
-import org.openqa.selenium.support.FindBy;
-
-import java.util.List;
 
 import static org.junit.Assert.assertEquals;
 
@@ -53,7 +48,7 @@ public class AccountTest {
         public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
             UserModel user = appRealm.getUser("test-user@localhost");
 
-            ApplicationModel accountApp = appRealm.getApplicationNameMap().get(org.keycloak.models.Constants.ACCOUNT_APPLICATION);
+            ApplicationModel accountApp = appRealm.getApplicationNameMap().get(org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_APP);
 
             UserModel user2 = appRealm.addUser("test-user-no-access@localhost");
             user2.setEnabled(true);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
index 964a7d3..b894e2c 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
@@ -25,8 +25,10 @@ import org.junit.Assert;
 import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
+import org.keycloak.models.RealmModel;
 import org.keycloak.representations.AccessToken;
 import org.keycloak.representations.idm.UserRepresentation;
+import org.keycloak.services.managers.RealmManager;
 import org.keycloak.testsuite.OAuthClient;
 import org.keycloak.testsuite.OAuthClient.AccessTokenResponse;
 import org.keycloak.testsuite.pages.LoginPage;
@@ -70,11 +72,8 @@ public class AccessTokenTest {
 
         AccessToken token = oauth.verifyToken(response.getAccessToken());
 
-        UserRepresentation user = oauth.getProfile(response.getAccessToken());
-
-        Assert.assertEquals(user.getId(), token.getSubject());
+        Assert.assertEquals(keycloakRule.getUser("test", "test-user@localhost").getId(), token.getSubject());
         Assert.assertNotEquals("test-user@localhost", token.getSubject());
-        Assert.assertEquals("test-user@localhost", user.getUsername());
 
         Assert.assertEquals(1, token.getRealmAccess().getRoles().size());
         Assert.assertTrue(token.getRealmAccess().isUserInRole("user"));
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
index a213b72..8d9b742 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
@@ -148,20 +148,6 @@ public class OAuthClient {
         }
     }
 
-    public UserRepresentation getProfile(String token) {
-        HttpClient client = new DefaultHttpClient();
-        HttpGet get = new HttpGet(baseUrl + "/realms/" + realm + "/account");
-        get.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + token);
-        get.setHeader(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON.getMimeType());
-
-        try {
-            HttpResponse response = client.execute(get);
-            return JsonSerialization.readValue(response.getEntity().getContent(), UserRepresentation.class);
-        } catch (Exception e) {
-            throw new RuntimeException("Failed to retrieve profile", e);
-        }
-    }
-
     public AccessToken verifyToken(String token) {
         try {
             return RSATokenVerifier.verifyToken(token, realmPublicKey, realm);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java
index caf6c58..a595694 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java
@@ -7,6 +7,8 @@ import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.representations.idm.UserRepresentation;
+import org.keycloak.services.managers.ModelToRepresentation;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.testutils.KeycloakServer;
 import org.keycloak.util.JsonSerialization;
@@ -31,6 +33,24 @@ public abstract class AbstractKeycloakRule extends ExternalResource {
         setupKeycloak();
     }
 
+    public UserRepresentation getUser(String realm, String name) {
+        KeycloakSession session = server.getKeycloakSessionFactory().createSession();
+        try {
+            return ModelToRepresentation.toRepresentation(session.getRealmByName(realm).getUser(name));
+        } finally {
+            session.close();
+        }
+    }
+
+    public UserRepresentation getUserById(String realm, String id) {
+        KeycloakSession session = server.getKeycloakSessionFactory().createSession();
+        try {
+            return ModelToRepresentation.toRepresentation(session.getRealmByName(realm).getUserById(id));
+        } finally {
+            session.close();
+        }
+    }
+
     protected void setupKeycloak() {
         KeycloakSession session = server.getKeycloakSessionFactory().createSession();
         session.getTransaction().begin();
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java
index 7f4e17a..27e7a87 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java
@@ -26,6 +26,9 @@ import org.junit.BeforeClass;
 import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
+import org.keycloak.models.AccountRoles;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.Constants;
 import org.keycloak.models.RealmModel;
 import org.keycloak.representations.AccessToken;
 import org.keycloak.representations.idm.UserRepresentation;
@@ -107,7 +110,7 @@ public class SocialLoginTest {
         AccessToken token = oauth.verifyToken(response.getAccessToken());
         Assert.assertEquals(36, token.getSubject().length());
 
-        UserRepresentation profile = oauth.getProfile(response.getAccessToken());
+        UserRepresentation profile = keycloakRule.getUserById("test", token.getSubject());
         Assert.assertEquals(36, profile.getUsername().length());
 
         Assert.assertEquals("Bob", profile.getFirstName());
@@ -146,7 +149,9 @@ public class SocialLoginTest {
             Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
 
             AccessTokenResponse response = oauth.doAccessTokenRequest(oauth.getCurrentQuery().get("code"), "password");
-            UserRepresentation profile = oauth.getProfile(response.getAccessToken());
+            AccessToken token = oauth.verifyToken(response.getAccessToken());
+
+            UserRepresentation profile = keycloakRule.getUserById("test", token.getSubject());
 
             Assert.assertEquals("Dummy", profile.getFirstName());
             Assert.assertEquals("User", profile.getLastName());