keycloak-aplcache

app full scope by default

8/4/2014 5:04:10 PM

Changes

Details

diff --git a/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
index 509f00b..3580e39 100755
--- a/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
@@ -21,6 +21,7 @@ public class ApplicationRepresentation {
     protected Integer notBefore;
     protected Boolean bearerOnly;
     protected Boolean publicClient;
+    protected Boolean fullScopeAllowed;
 
 
     public String getId() {
@@ -134,4 +135,12 @@ public class ApplicationRepresentation {
     public void setPublicClient(Boolean publicClient) {
         this.publicClient = publicClient;
     }
+
+    public Boolean isFullScopeAllowed() {
+        return fullScopeAllowed;
+    }
+
+    public void setFullScopeAllowed(Boolean fullScopeAllowed) {
+        this.fullScopeAllowed = fullScopeAllowed;
+    }
 }
diff --git a/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java
index 7511de6..4c2193d 100755
--- a/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java
@@ -17,6 +17,7 @@ public class OAuthClientRepresentation {
     protected Integer notBefore;
     protected Boolean publicClient;
     protected Boolean directGrantsOnly;
+    protected Boolean fullScopeAllowed;
 
 
     public String getId() {
@@ -98,4 +99,13 @@ public class OAuthClientRepresentation {
     public void setDirectGrantsOnly(Boolean directGrantsOnly) {
         this.directGrantsOnly = directGrantsOnly;
     }
+
+    public Boolean isFullScopeAllowed() {
+        return fullScopeAllowed;
+    }
+
+    public void setFullScopeAllowed(Boolean fullScopeAllowed) {
+        this.fullScopeAllowed = fullScopeAllowed;
+    }
+
 }
diff --git a/dependencies/server-all/pom.xml b/dependencies/server-all/pom.xml
index 92f6df0..b385cfc 100755
--- a/dependencies/server-all/pom.xml
+++ b/dependencies/server-all/pom.xml
@@ -88,7 +88,12 @@
             <version>${project.version}</version>
         </dependency>
 
-        <!-- authentication api -->
+        <!-- ldap federation api -->
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-ldap-federation</artifactId>
+            <version>${project.version}</version>
+        </dependency>
         <dependency>
             <groupId>org.picketlink</groupId>
             <artifactId>picketlink-common</artifactId>
diff --git a/examples/demo-template/testrealm.json b/examples/demo-template/testrealm.json
index 816afd2..3f0e20a 100755
--- a/examples/demo-template/testrealm.json
+++ b/examples/demo-template/testrealm.json
@@ -92,28 +92,7 @@
         {
             "client": "third-party",
             "roles": ["user"]
-        },
-        {
-            "client": "customer-portal",
-            "roles": ["user", "admin" ]
-        },
-        {
-            "client": "customer-portal-js",
-            "roles": ["user"]
-        },
-        {
-            "client": "customer-portal-cli",
-            "roles": ["user"]
-        },
-        {
-            "client": "angular-product",
-            "roles": ["user"]
-        },
-        {
-            "client": "product-portal",
-            "roles": ["user", "admin" ]
         }
-
     ],
     "applications": [
         {
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/applications.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/applications.js
index 60560f3..6c77ae7 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/applications.js
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/applications.js
@@ -348,11 +348,12 @@ module.controller('ApplicationDetailCtrl', function($scope, realm, application, 
 });
 
 module.controller('ApplicationScopeMappingCtrl', function($scope, $http, realm, application, applications,
+                                                          Application,
                                                           ApplicationRealmScopeMapping, ApplicationApplicationScopeMapping, ApplicationRole,
                                                           ApplicationAvailableRealmScopeMapping, ApplicationAvailableApplicationScopeMapping,
                                                           ApplicationCompositeRealmScopeMapping, ApplicationCompositeApplicationScopeMapping) {
     $scope.realm = realm;
-    $scope.application = application;
+    $scope.application = angular.copy(application);
     $scope.selectedRealmRoles = [];
     $scope.selectedRealmMappings = [];
     $scope.realmMappings = [];
@@ -364,6 +365,21 @@ module.controller('ApplicationScopeMappingCtrl', function($scope, $http, realm, 
     $scope.applicationMappings = [];
     $scope.dummymodel = [];
 
+
+    $scope.changeFullScopeAllowed = function() {
+        console.log('change full scope');
+        Application.update({
+            realm : realm.realm,
+            application : application.name
+        }, $scope.application, function() {
+            $scope.changed = false;
+            application = angular.copy($scope.application);
+            updateRealmRoles();
+        });
+    }
+
+
+
     function updateRealmRoles() {
         $scope.realmRoles = ApplicationAvailableRealmScopeMapping.query({realm : realm.realm, application : application.name});
         $scope.realmMappings = ApplicationRealmScopeMapping.query({realm : realm.realm, application : application.name});
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/oauth-clients.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/oauth-clients.js
index 511efe6..3f6c154 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/oauth-clients.js
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/oauth-clients.js
@@ -183,11 +183,12 @@ module.controller('OAuthClientDetailCtrl', function($scope, realm, oauth, OAuthC
 });
 
 module.controller('OAuthClientScopeMappingCtrl', function($scope, $http, realm, oauth, applications,
+                                                          OAuthClient,
                                                           OAuthClientRealmScopeMapping, OAuthClientApplicationScopeMapping, ApplicationRole,
                                                           OAuthClientAvailableRealmScopeMapping, OAuthClientAvailableApplicationScopeMapping,
                                                           OAuthClientCompositeRealmScopeMapping, OAuthClientCompositeApplicationScopeMapping) {
     $scope.realm = realm;
-    $scope.oauth = oauth;
+    $scope.oauth = angular.copy(oauth);
     $scope.selectedRealmRoles = [];
     $scope.selectedRealmMappings = [];
     $scope.realmMappings = [];
@@ -199,6 +200,19 @@ module.controller('OAuthClientScopeMappingCtrl', function($scope, $http, realm, 
     $scope.applicationMappings = [];
     $scope.dummymodel = [];
 
+    $scope.changeFullScopeAllowed = function() {
+        console.log('change full scope');
+        OAuthClient.update({
+            realm : realm.realm,
+            oauth : oauth.name
+        }, $scope.oauth, function() {
+            $scope.changed = false;
+            oauth = angular.copy($scope.oauth);
+        });
+
+    }
+
+
     function updateRealmRoles() {
         $scope.realmRoles = OAuthClientAvailableRealmScopeMapping.query({realm : realm.realm, oauth : oauth.name});
         $scope.realmMappings = OAuthClientRealmScopeMapping.query({realm : realm.realm, oauth : oauth.name});
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-scope-mappings.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-scope-mappings.html
index ba1f809..1f26565 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-scope-mappings.html
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-scope-mappings.html
@@ -21,7 +21,18 @@
         </ol>
         <h2><span>{{application.name}}</span> Scope Mappings</h2>
         <p class="subtitle"></p>
-        <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageApplications">
+        <form class="form-horizontal" name="allowScope" novalidate kc-read-only="!access.manageApplications">
+            <fieldset class="border-top">
+                <div class="form-group">
+                    <label class="col-sm-2 control-label" for="fullScopeAllowed">Full Scope Allowed</label>
+                    <div class="col-sm-4">
+                        <input ng-model="application.fullScopeAllowed" ng-click="changeFullScopeAllowed()" name="fullScopeAllowed" id="fullScopeAllowed" onoffswitch />
+                    </div>
+                </div>
+            </fieldset>
+        </form>
+
+        <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageApplications" data-ng-show="!application.fullScopeAllowed">
             <fieldset>
                 <legend><span class="text">Realm Roles</span></legend>
                 <div class="form-group col-sm-10">
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-scope-mappings.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-scope-mappings.html
index f74ca47..a53b632 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-scope-mappings.html
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-scope-mappings.html
@@ -19,7 +19,17 @@
         </ol>
         <h2><span>{{oauth.name}}</span> Scope Mappings</h2>
         <p class="subtitle"></p>
-        <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageClients">
+        <form class="form-horizontal" name="allowScope" novalidate kc-read-only="!access.manageClients">
+            <fieldset class="border-top">
+                <div class="form-group">
+                    <label class="col-sm-2 control-label" for="fullScopeAllowed">Full Scope Allowed</label>
+                    <div class="col-sm-4">
+                        <input ng-model="oauth.fullScopeAllowed" ng-click="changeFullScopeAllowed()" name="fullScopeAllowed" id="fullScopeAllowed" onoffswitch />
+                    </div>
+                </div>
+            </fieldset>
+        </form>
+        <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageClients"  data-ng-show="!oauth.fullScopeAllowed">
             <fieldset>
                 <legend><span class="text">Realm Roles</span></legend>
                 <div class="form-group col-sm-10">
diff --git a/model/api/src/main/java/org/keycloak/models/ClientModel.java b/model/api/src/main/java/org/keycloak/models/ClientModel.java
index 33ee8e2..9ca5a70 100755
--- a/model/api/src/main/java/org/keycloak/models/ClientModel.java
+++ b/model/api/src/main/java/org/keycloak/models/ClientModel.java
@@ -50,6 +50,9 @@ public interface ClientModel {
     String getSecret();
     public void setSecret(String secret);
 
+    boolean isFullScopeAllowed();
+    void setFullScopeAllowed(boolean value);
+
     boolean isPublicClient();
     void setPublicClient(boolean flag);
 
diff --git a/model/api/src/main/java/org/keycloak/models/entities/ClientEntity.java b/model/api/src/main/java/org/keycloak/models/entities/ClientEntity.java
old mode 100644
new mode 100755
index e7439fc..0d23c35
--- a/model/api/src/main/java/org/keycloak/models/entities/ClientEntity.java
+++ b/model/api/src/main/java/org/keycloak/models/entities/ClientEntity.java
@@ -14,6 +14,7 @@ public class ClientEntity extends AbstractIdentifiableEntity {
     private long allowedClaimsMask;
     private int notBefore;
     private boolean publicClient;
+    private boolean fullScopeAllowed;
 
     private String realmId;
 
@@ -100,4 +101,12 @@ public class ClientEntity extends AbstractIdentifiableEntity {
     public void setScopeIds(List<String> scopeIds) {
         this.scopeIds = scopeIds;
     }
+
+    public boolean isFullScopeAllowed() {
+        return fullScopeAllowed;
+    }
+
+    public void setFullScopeAllowed(boolean fullScopeAllowed) {
+        this.fullScopeAllowed = fullScopeAllowed;
+    }
 }
diff --git a/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java b/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
index 4a00ff9..c36dd10 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
@@ -91,6 +91,7 @@ public final class KeycloakModelUtils {
     public static ApplicationModel createApplication(RealmModel realm, String name) {
         ApplicationModel app = realm.addApplication(name);
         generateSecret(app);
+        app.setFullScopeAllowed(true);
 
         return app;
     }
diff --git a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
index c201a77..9e19b75 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
@@ -214,6 +214,7 @@ public class ModelToRepresentation {
         rep.setEnabled(applicationModel.isEnabled());
         rep.setAdminUrl(applicationModel.getManagementUrl());
         rep.setPublicClient(applicationModel.isPublicClient());
+        rep.setFullScopeAllowed(applicationModel.isFullScopeAllowed());
         rep.setBearerOnly(applicationModel.isBearerOnly());
         rep.setSurrogateAuthRequired(applicationModel.isSurrogateAuthRequired());
         rep.setBaseUrl(applicationModel.getBaseUrl());
@@ -242,6 +243,7 @@ public class ModelToRepresentation {
         rep.setName(model.getClientId());
         rep.setEnabled(model.isEnabled());
         rep.setPublicClient(model.isPublicClient());
+        rep.setFullScopeAllowed(model.isFullScopeAllowed());
         rep.setDirectGrantsOnly(model.isDirectGrantsOnly());
         Set<String> redirectUris = model.getRedirectUris();
         if (redirectUris != null) {
diff --git a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
index ca22cf0..35a4acb 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
@@ -353,6 +353,8 @@ public class RepresentationToModel {
         applicationModel.setBaseUrl(resourceRep.getBaseUrl());
         if (resourceRep.isBearerOnly() != null) applicationModel.setBearerOnly(resourceRep.isBearerOnly());
         if (resourceRep.isPublicClient() != null) applicationModel.setPublicClient(resourceRep.isPublicClient());
+        if (resourceRep.isFullScopeAllowed() != null) applicationModel.setFullScopeAllowed(resourceRep.isFullScopeAllowed());
+        else applicationModel.setFullScopeAllowed(true);
         applicationModel.updateApplication();
 
         if (resourceRep.getNotBefore() != null) {
@@ -415,6 +417,7 @@ public class RepresentationToModel {
         if (rep.isEnabled() != null) resource.setEnabled(rep.isEnabled());
         if (rep.isBearerOnly() != null) resource.setBearerOnly(rep.isBearerOnly());
         if (rep.isPublicClient() != null) resource.setPublicClient(rep.isPublicClient());
+        if (rep.isFullScopeAllowed() != null) resource.setFullScopeAllowed(rep.isFullScopeAllowed());
         if (rep.getAdminUrl() != null) resource.setManagementUrl(rep.getAdminUrl());
         if (rep.getBaseUrl() != null) resource.setBaseUrl(rep.getBaseUrl());
         if (rep.isSurrogateAuthRequired() != null) resource.setSurrogateAuthRequired(rep.isSurrogateAuthRequired());
@@ -521,6 +524,7 @@ public class RepresentationToModel {
         if (rep.getName() != null) model.setClientId(rep.getName());
         if (rep.isEnabled() != null) model.setEnabled(rep.isEnabled());
         if (rep.isPublicClient() != null) model.setPublicClient(rep.isPublicClient());
+        if (rep.isFullScopeAllowed() != null) model.setFullScopeAllowed(rep.isFullScopeAllowed());
         if (rep.isDirectGrantsOnly() != null) model.setDirectGrantsOnly(rep.isDirectGrantsOnly());
         if (rep.getClaims() != null) {
             setClaims(model, rep.getClaims());
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java
index ae913a1..1565e43 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java
@@ -123,6 +123,19 @@ public abstract class ClientAdapter implements ClientModel {
         updatedClient.setPublicClient(flag);
     }
 
+    @Override
+    public boolean isFullScopeAllowed() {
+        if (updatedClient != null) return updatedClient.isFullScopeAllowed();
+        return cachedClient.isFullScopeAllowed();
+    }
+
+    @Override
+    public void setFullScopeAllowed(boolean value) {
+        getDelegateForUpdate();
+        updatedClient.setFullScopeAllowed(value);
+
+    }
+
     public boolean isDirectGrantsOnly() {
         if (updatedClient != null) return updatedClient.isDirectGrantsOnly();
         return cachedClient.isDirectGrantsOnly();
@@ -171,7 +184,7 @@ public abstract class ClientAdapter implements ClientModel {
 
     public boolean hasScope(RoleModel role) {
         if (updatedClient != null) return updatedClient.hasScope(role);
-        if (cachedClient.getScope().contains(role.getId())) return true;
+        if (cachedClient.isFullScopeAllowed() || cachedClient.getScope().contains(role.getId())) return true;
 
         Set<RoleModel> roles = getScopeMappings();
 
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java
index 8e4b008..a48b104 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java
@@ -22,6 +22,7 @@ public class CachedClient {
     protected boolean enabled;
     protected String secret;
     protected boolean publicClient;
+    protected boolean fullScopeAllowed;
     protected boolean directGrantsOnly;
     protected int notBefore;
     protected Set<String> scope = new HashSet<String>();
@@ -37,6 +38,7 @@ public class CachedClient {
         directGrantsOnly = model.isDirectGrantsOnly();
         publicClient = model.isPublicClient();
         allowedClaimsMask = model.getAllowedClaimsMask();
+        fullScopeAllowed = model.isFullScopeAllowed();
         redirectUris.addAll(model.getRedirectUris());
         webOrigins.addAll(model.getWebOrigins());
         for (RoleModel role : model.getScopeMappings())  {
@@ -92,4 +94,8 @@ public class CachedClient {
     public Set<String> getWebOrigins() {
         return webOrigins;
     }
+
+    public boolean isFullScopeAllowed() {
+        return fullScopeAllowed;
+    }
 }
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
index 6a07b5e..16a370e 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
@@ -79,6 +79,16 @@ public abstract class ClientAdapter implements ClientModel {
     }
 
     @Override
+    public boolean isFullScopeAllowed() {
+        return entity.isFullScopeAllowed();
+    }
+
+    @Override
+    public void setFullScopeAllowed(boolean value) {
+        entity.setFullScopeAllowed(value);
+    }
+
+    @Override
     public Set<String> getWebOrigins() {
         Set<String> result = new HashSet<String>();
         result.addAll(entity.getWebOrigins());
@@ -214,6 +224,7 @@ public abstract class ClientAdapter implements ClientModel {
 
     @Override
     public boolean hasScope(RoleModel role) {
+        if (isFullScopeAllowed()) return true;
         Set<RoleModel> roles = getScopeMappings();
         if (roles.contains(role)) return true;
 
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java
index 2f8625b..7bc66c3 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java
@@ -38,6 +38,8 @@ public abstract class ClientEntity {
     private int notBefore;
     @Column(name="PUBLIC_CLIENT")
     private boolean publicClient;
+    @Column(name="FULL_SCOPE_ALLOWED")
+    private boolean fullScopeAllowed;
 
     @ManyToOne(fetch = FetchType.LAZY)
     @JoinColumn(name = "REALM_ID")
@@ -132,4 +134,12 @@ public abstract class ClientEntity {
     public void setPublicClient(boolean publicClient) {
         this.publicClient = publicClient;
     }
+
+    public boolean isFullScopeAllowed() {
+        return fullScopeAllowed;
+    }
+
+    public void setFullScopeAllowed(boolean fullScopeAllowed) {
+        this.fullScopeAllowed = fullScopeAllowed;
+    }
 }
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
index 1e468bc..d172ea5 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
@@ -158,6 +158,18 @@ public abstract class ClientAdapter<T extends MongoIdentifiableEntity> extends A
     }
 
     @Override
+    public boolean isFullScopeAllowed() {
+        return getMongoEntityAsClient().isFullScopeAllowed();
+    }
+
+    @Override
+    public void setFullScopeAllowed(boolean value) {
+        getMongoEntityAsClient().setFullScopeAllowed(value);
+        updateMongoEntity();
+
+    }
+
+    @Override
     public RealmModel getRealm() {
         return realm;
     }
@@ -207,6 +219,7 @@ public abstract class ClientAdapter<T extends MongoIdentifiableEntity> extends A
 
     @Override
     public boolean hasScope(RoleModel role) {
+        if (isFullScopeAllowed()) return true;
         Set<RoleModel> roles = getScopeMappings();
         if (roles.contains(role)) return true;
 
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 c82a803..6456d9e 100755
--- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
@@ -95,6 +95,7 @@ public class RealmManager {
         adminConsole.setEnabled(true);
         adminConsole.setPublicClient(true);
         adminConsole.addRedirectUri(baseUrl + "/*");
+        adminConsole.setFullScopeAllowed(false);
 
         RoleModel adminRole;
         if (realm.getName().equals(Config.getAdminRealm())) {
@@ -163,6 +164,7 @@ public class RealmManager {
         }
         RoleModel adminRole = realmAdminApp.addRole(AdminRoles.REALM_ADMIN);
         realmAdminApp.setBearerOnly(true);
+        realmAdminApp.setFullScopeAllowed(false);
 
         for (String r : AdminRoles.ALL_REALM_ROLES) {
             RoleModel role = realmAdminApp.addRole(r);
@@ -176,6 +178,7 @@ public class RealmManager {
         if (application == null) {
             application = new ApplicationManager(this).createApplication(realm, Constants.ACCOUNT_MANAGEMENT_APP);
             application.setEnabled(true);
+            application.setFullScopeAllowed(false);
             String base = contextPath + "/realms/" + realm.getName() + "/account";
             String redirectUri = base + "/*";
             application.addRedirectUri(redirectUri);
diff --git a/services/src/main/java/org/keycloak/services/managers/TokenManager.java b/services/src/main/java/org/keycloak/services/managers/TokenManager.java
index 7fa008e..0971a07 100755
--- a/services/src/main/java/org/keycloak/services/managers/TokenManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/TokenManager.java
@@ -135,6 +135,8 @@ public class TokenManager {
         Set<RoleModel> requestedRoles = new HashSet<RoleModel>();
 
         Set<RoleModel> roleMappings = user.getRoleMappings();
+        if (client.isFullScopeAllowed()) return roleMappings;
+
         Set<RoleModel> scopeMappings = client.getScopeMappings();
         if (client instanceof ApplicationModel) {
             scopeMappings.addAll(((ApplicationModel) client).getRoles());
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java
index d2656b7..e22c9d1 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java
@@ -166,6 +166,7 @@ public class AdminAPITest {
         if (appRep.isEnabled() != null) Assert.assertEquals(appRep.isEnabled(), storedApp.isEnabled());
         if (appRep.isBearerOnly() != null) Assert.assertEquals(appRep.isBearerOnly(), storedApp.isBearerOnly());
         if (appRep.isPublicClient() != null) Assert.assertEquals(appRep.isPublicClient(), storedApp.isPublicClient());
+        if (appRep.isFullScopeAllowed() != null) Assert.assertEquals(appRep.isFullScopeAllowed(), storedApp.isFullScopeAllowed());
         if (appRep.getAdminUrl() != null) Assert.assertEquals(appRep.getAdminUrl(), storedApp.getAdminUrl());
         if (appRep.getBaseUrl() != null) Assert.assertEquals(appRep.getBaseUrl(), storedApp.getBaseUrl());
         if (appRep.isSurrogateAuthRequired() != null) Assert.assertEquals(appRep.isSurrogateAuthRequired(), storedApp.isSurrogateAuthRequired());
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 3a6acd1..6aaf068 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
@@ -86,6 +86,7 @@ public class CompositeRoleTest {
             realmRole1User.grantRole(realmRole1);
 
             final ApplicationModel realmComposite1Application = new ApplicationManager(manager).createApplication(realm, "REALM_COMPOSITE_1_APPLICATION");
+            realmComposite1Application.setFullScopeAllowed(false);
             realmComposite1Application.setEnabled(true);
             realmComposite1Application.addScopeMapping(realmComposite1);
             realmComposite1Application.addRedirectUri("http://localhost:8081/app/*");
@@ -94,6 +95,7 @@ public class CompositeRoleTest {
             realmComposite1Application.setSecret("password");
 
             final ApplicationModel realmRole1Application = new ApplicationManager(manager).createApplication(realm, "REALM_ROLE_1_APPLICATION");
+            realmRole1Application.setFullScopeAllowed(false);
             realmRole1Application.setEnabled(true);
             realmRole1Application.addScopeMapping(realmRole1);
             realmRole1Application.addRedirectUri("http://localhost:8081/app/*");
@@ -103,6 +105,7 @@ public class CompositeRoleTest {
 
 
             final ApplicationModel appRoleApplication = new ApplicationManager(manager).createApplication(realm, "APP_ROLE_APPLICATION");
+            appRoleApplication.setFullScopeAllowed(false);
             appRoleApplication.setEnabled(true);
             appRoleApplication.addRedirectUri("http://localhost:8081/app/*");
             appRoleApplication.setBaseUrl("http://localhost:8081/app");
@@ -125,6 +128,7 @@ public class CompositeRoleTest {
             realmAppRoleUser.grantRole(appRole2);
 
             final ApplicationModel appCompositeApplication = new ApplicationManager(manager).createApplication(realm, "APP_COMPOSITE_APPLICATION");
+            appCompositeApplication.setFullScopeAllowed(false);
             appCompositeApplication.setEnabled(true);
             appCompositeApplication.addRedirectUri("http://localhost:8081/app/*");
             appCompositeApplication.setBaseUrl("http://localhost:8081/app");
diff --git a/testsuite/integration/src/test/resources/model/testcomposites.json b/testsuite/integration/src/test/resources/model/testcomposites.json
index ef4f999..45a2f30 100755
--- a/testsuite/integration/src/test/resources/model/testcomposites.json
+++ b/testsuite/integration/src/test/resources/model/testcomposites.json
@@ -88,6 +88,7 @@
     "applications": [
         {
             "name": "REALM_COMPOSITE_1_APPLICATION",
+            "fullScopeAllowed": false,
             "enabled": true,
             "baseUrl": "http://localhost:8081/app",
             "adminUrl": "http://localhost:8081/app/logout",
@@ -95,6 +96,7 @@
          },
         {
             "name": "REALM_ROLE_1_APPLICATION",
+            "fullScopeAllowed": false,
             "enabled": true,
             "baseUrl": "http://localhost:8081/app",
             "adminUrl": "http://localhost:8081/app/logout",
@@ -102,6 +104,7 @@
         },
         {
             "name": "APP_ROLE_APPLICATION",
+            "fullScopeAllowed": false,
             "enabled": true,
             "baseUrl": "http://localhost:8081/app",
             "adminUrl": "http://localhost:8081/app/logout",
@@ -109,6 +112,7 @@
         },
         {
             "name": "APP_COMPOSITE_APPLICATION",
+            "fullScopeAllowed": false,
             "enabled": true,
             "baseUrl": "http://localhost:8081/app",
             "adminUrl": "http://localhost:8081/app/logout",
diff --git a/testsuite/integration/src/test/resources/testcomposite.json b/testsuite/integration/src/test/resources/testcomposite.json
index 65e615b..8f3f76f 100755
--- a/testsuite/integration/src/test/resources/testcomposite.json
+++ b/testsuite/integration/src/test/resources/testcomposite.json
@@ -89,6 +89,7 @@
         {
             "name": "REALM_COMPOSITE_1_APPLICATION",
             "enabled": true,
+            "fullScopeAllowed": false,
             "baseUrl": "http://localhost:8081/app",
             "adminUrl": "http://localhost:8081/app/logout",
             "redirectUris": [
@@ -98,6 +99,7 @@
          },
         {
             "name": "REALM_ROLE_1_APPLICATION",
+            "fullScopeAllowed": false,
             "enabled": true,
             "baseUrl": "http://localhost:8081/app",
             "adminUrl": "http://localhost:8081/app/logout",
@@ -108,6 +110,7 @@
         },
         {
             "name": "APP_ROLE_APPLICATION",
+            "fullScopeAllowed": false,
             "enabled": true,
             "baseUrl": "http://localhost:8081/app",
             "adminUrl": "http://localhost:8081/app/logout",
@@ -118,6 +121,7 @@
         },
         {
             "name": "APP_COMPOSITE_APPLICATION",
+            "fullScopeAllowed": false,
             "enabled": true,
             "baseUrl": "http://localhost:8081/app",
             "adminUrl": "http://localhost:8081/app/logout",