keycloak-aplcache
Changes
dependencies/server-all/pom.xml 7(+6 -1)
examples/demo-template/testrealm.json 21(+0 -21)
forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/applications.js 18(+17 -1)
forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/oauth-clients.js 16(+15 -1)
forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-scope-mappings.html 13(+12 -1)
forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-scope-mappings.html 12(+11 -1)
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java 15(+14 -1)
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java 6(+6 -0)
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;
+ }
+
}
dependencies/server-all/pom.xml 7(+6 -1)
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>
examples/demo-template/testrealm.json 21(+0 -21)
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",