From 4a40ec71c9d2966627e6eb7af503be4034553ff7 Mon Sep 17 00:00:00 2001 From: Bill Burke Date: Sun, 28 Jul 2013 09:47:26 -0400 Subject: [PATCH] role description --- .../idm/RealmRepresentation.java | 6 ++-- .../idm/ResourceRepresentation.java | 12 +++---- .../idm/RoleRepresentation.java | 34 +++++++++++++++++++ .../src/main/webapp/META-INF/testrealm.json | 4 +++ .../services/managers/RealmManager.java | 20 ++++++++--- .../keycloak/services/models/RealmModel.java | 6 +++- .../services/models/ResourceModel.java | 4 ++- .../services/resources/TokenService.java | 11 +++++- .../java/org/keycloak/test/AdapterTest.java | 2 +- services/src/test/resources/testrealm.json | 10 ++++-- 10 files changed, 89 insertions(+), 20 deletions(-) create mode 100755 core/src/main/java/org/keycloak/representations/idm/RoleRepresentation.java diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java index cddd1caf59..080d845bb1 100755 --- a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java @@ -18,7 +18,7 @@ public class RealmRepresentation { protected boolean cookieLoginAllowed; protected String privateKey; protected String publicKey; - protected Set roles; + protected List roles; protected List requiredCredentials; protected List users; protected List roleMappings; @@ -146,11 +146,11 @@ public class RealmRepresentation { this.accessCodeLifespan = accessCodeLifespan; } - public Set getRoles() { + public List getRoles() { return roles; } - public void setRoles(Set roles) { + public void setRoles(List roles) { this.roles = roles; } diff --git a/core/src/main/java/org/keycloak/representations/idm/ResourceRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/ResourceRepresentation.java index 15c49f994e..84d499f050 100755 --- a/core/src/main/java/org/keycloak/representations/idm/ResourceRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/ResourceRepresentation.java @@ -16,7 +16,7 @@ public class ResourceRepresentation { protected boolean surrogateAuthRequired; protected boolean useRealmMappings; protected List credentials; - protected Set roles; + protected List roles; protected List roleMappings; protected List scopeMappings; @@ -44,17 +44,17 @@ public class ResourceRepresentation { this.surrogateAuthRequired = surrogateAuthRequired; } - public Set getRoles() { + public List getRoles() { return roles; } - public void setRoles(Set roles) { + public void setRoles(List roles) { this.roles = roles; } - public ResourceRepresentation role(String role) { - if (this.roles == null) this.roles = new HashSet(); - this.roles.add(role); + public ResourceRepresentation role(String role, String description) { + if (this.roles == null) this.roles = new ArrayList(); + this.roles.add(new RoleRepresentation(role, description)); return this; } diff --git a/core/src/main/java/org/keycloak/representations/idm/RoleRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RoleRepresentation.java new file mode 100755 index 0000000000..60fbc6b3e4 --- /dev/null +++ b/core/src/main/java/org/keycloak/representations/idm/RoleRepresentation.java @@ -0,0 +1,34 @@ +package org.keycloak.representations.idm; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public class RoleRepresentation { + protected String name; + protected String description; + + public RoleRepresentation() { + } + + public RoleRepresentation(String name, String description) { + this.name = name; + this.description = description; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} diff --git a/examples/as7-eap-demo/server/src/main/webapp/META-INF/testrealm.json b/examples/as7-eap-demo/server/src/main/webapp/META-INF/testrealm.json index db107689e9..dc9375a62f 100755 --- a/examples/as7-eap-demo/server/src/main/webapp/META-INF/testrealm.json +++ b/examples/as7-eap-demo/server/src/main/webapp/META-INF/testrealm.json @@ -27,6 +27,10 @@ ] } ], + "roles" : [ + { "name" : "user", "description" : "User privileges" }, + { "name" : "admin", "description" : "Administrator privileges" } + ], "roleMappings" : [ { "username" : "bburke@redhat.com", 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 080e68858e..9f5e8c8ce9 100755 --- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java +++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java @@ -5,6 +5,7 @@ import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RequiredCredentialRepresentation; import org.keycloak.representations.idm.ResourceRepresentation; import org.keycloak.representations.idm.RoleMappingRepresentation; +import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.representations.idm.ScopeMappingRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.services.models.RealmModel; @@ -23,6 +24,7 @@ import org.picketlink.idm.model.User; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; +import java.io.Serializable; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; @@ -38,6 +40,9 @@ import java.util.concurrent.atomic.AtomicLong; */ public class RealmManager { private static AtomicLong counter = new AtomicLong(1); + public static final String RESOURCE_ROLE = "KEYCLOAK_RESOURCE"; + public static final String OAUTH_CLIENT_ROLE = "KEYCLOAK_OAUTH_CLIENT"; + public static final String WILDCARD_ROLE = "*"; public static String generateId() { return counter.getAndIncrement() + "-" + System.currentTimeMillis(); @@ -71,7 +76,8 @@ public class RealmManager { SimpleAgent agent = new SimpleAgent(RealmModel.REALM_AGENT_ID); idm.add(agent); RealmModel realm = new RealmModel(newRealm, identitySession); - idm.add(new SimpleRole("*")); + idm.add(new SimpleRole(WILDCARD_ROLE)); + idm.add(new SimpleRole(RESOURCE_ROLE)); return realm; } @@ -145,8 +151,9 @@ public class RealmManager { } if (rep.getRoles() != null) { - for (String roleString : rep.getRoles()) { - SimpleRole role = new SimpleRole(roleString.trim()); + for (RoleRepresentation roleRep : rep.getRoles()) { + SimpleRole role = new SimpleRole(roleRep.getName()); + if (roleRep.getDescription() != null) role.setAttribute(new Attribute("description", roleRep.getDescription())); newRealm.getIdm().add(role); } } @@ -186,6 +193,7 @@ public class RealmManager { } protected void createResources(RealmRepresentation rep, RealmModel realm, Map userMap) { + Role loginRole = realm.getIdm().getRole(RealmManager.RESOURCE_ROLE); for (ResourceRepresentation resourceRep : rep.getResources()) { ResourceModel resource = realm.addResource(resourceRep.getName()); resource.setManagementUrl(resourceRep.getAdminUrl()); @@ -202,11 +210,13 @@ public class RealmManager { } } userMap.put(resourceUser.getLoginName(), resourceUser); + realm.getIdm().grantRole(resourceUser, loginRole); if (resourceRep.getRoles() != null) { - for (String roleString : resourceRep.getRoles()) { - SimpleRole role = new SimpleRole(roleString.trim()); + for (RoleRepresentation roleRep : resourceRep.getRoles()) { + SimpleRole role = new SimpleRole(roleRep.getName()); + if (roleRep.getDescription() != null) role.setAttribute(new Attribute("description", roleRep.getDescription())); resource.getIdm().add(role); } } diff --git a/services/src/main/java/org/keycloak/services/models/RealmModel.java b/services/src/main/java/org/keycloak/services/models/RealmModel.java index 6ab850ae83..171e57dba3 100755 --- a/services/src/main/java/org/keycloak/services/models/RealmModel.java +++ b/services/src/main/java/org/keycloak/services/models/RealmModel.java @@ -38,6 +38,8 @@ import java.util.Map; import java.util.Set; /** + * Meant to be a per-request object + * * @author Bill Burke * @version $Revision: 1 $ */ @@ -57,6 +59,7 @@ public class RealmModel { protected IdentitySession identitySession; protected volatile transient PublicKey publicKey; protected volatile transient PrivateKey privateKey; + protected IdentityManager idm; public RealmModel(Realm realm, IdentitySession session) { this.realm = realm; @@ -65,7 +68,8 @@ public class RealmModel { } public IdentityManager getIdm() { - return identitySession.createIdentityManager(realm); + if (idm == null) idm = identitySession.createIdentityManager(realm); + return idm; } public void updateRealm() { diff --git a/services/src/main/java/org/keycloak/services/models/ResourceModel.java b/services/src/main/java/org/keycloak/services/models/ResourceModel.java index c47785bbbe..f9b5ca3834 100755 --- a/services/src/main/java/org/keycloak/services/models/ResourceModel.java +++ b/services/src/main/java/org/keycloak/services/models/ResourceModel.java @@ -25,6 +25,7 @@ public class ResourceModel { protected ResourceRelationship agent; protected RealmModel realm; protected IdentitySession identitySession; + protected IdentityManager idm; public ResourceModel(Tier tier, ResourceRelationship agent, RealmModel realm, IdentitySession session) { this.tier = tier; @@ -34,7 +35,8 @@ public class ResourceModel { } public IdentityManager getIdm() { - return identitySession.createIdentityManager(tier); + if (idm == null) idm = identitySession.createIdentityManager(tier); + return idm; } public void updateResource() { diff --git a/services/src/main/java/org/keycloak/services/resources/TokenService.java b/services/src/main/java/org/keycloak/services/resources/TokenService.java index eaaaf74801..eb52cfe39f 100755 --- a/services/src/main/java/org/keycloak/services/resources/TokenService.java +++ b/services/src/main/java/org/keycloak/services/resources/TokenService.java @@ -13,12 +13,14 @@ import org.keycloak.representations.SkeletonKeyToken; import org.keycloak.services.JspRequestParameters; import org.keycloak.services.managers.AccessCodeEntry; import org.keycloak.services.managers.AuthenticationManager; +import org.keycloak.services.managers.RealmManager; import org.keycloak.services.managers.ResourceAdminManager; import org.keycloak.services.managers.TokenManager; import org.keycloak.services.models.RealmModel; import org.keycloak.services.models.RequiredCredentialModel; import org.keycloak.services.models.ResourceModel; import org.picketlink.idm.IdentitySession; +import org.picketlink.idm.model.Role; import org.picketlink.idm.model.User; import javax.ws.rs.Consumes; @@ -389,12 +391,19 @@ public class TokenService { identitySession.close(); return null; } + Role resourceRole = realm.getIdm().getRole(RealmManager.RESOURCE_ROLE); + Role oauthClientRole = realm.getIdm().getRole(RealmManager.OAUTH_CLIENT_ROLE); + if (!realm.getIdm().hasRole(client, resourceRole) && !realm.getIdm().hasRole(client, oauthClientRole)) { + securityFailureForward("Login requester not allowed to request login."); + identitySession.close(); + return null; + + } User user = authManager.authenticateIdentityCookie(realm, uriInfo, headers); if (user != null) { return redirectAccessCode(scopeParam, state, redirect, client, user); } - // todo make sure client is allowed to request a login forwardToLoginForm(redirect, clientId, scopeParam, state); return null; diff --git a/services/src/test/java/org/keycloak/test/AdapterTest.java b/services/src/test/java/org/keycloak/test/AdapterTest.java index f798539547..36b3d6b0ca 100755 --- a/services/src/test/java/org/keycloak/test/AdapterTest.java +++ b/services/src/test/java/org/keycloak/test/AdapterTest.java @@ -166,7 +166,7 @@ public class AdapterTest { idm.add(new SimpleRole("admin")); idm.add(new SimpleRole("user")); List roles = realmModel.getRoles(); - Assert.assertEquals(3, roles.size()); + Assert.assertEquals(4, roles.size()); SimpleUser user = new SimpleUser("bburke"); idm.add(user); Role role = idm.getRole("user"); diff --git a/services/src/test/resources/testrealm.json b/services/src/test/resources/testrealm.json index b58bdd8a7a..a8d0cbf067 100755 --- a/services/src/test/resources/testrealm.json +++ b/services/src/test/resources/testrealm.json @@ -62,7 +62,10 @@ "resources" : [ { "name" : "Application", - "roles" : ["admin", "user"], + "roles" : [ + { "name" : "admin" }, + { "name" : "user" } + ], "roleMappings" : [ { "username" : "wburke", @@ -82,7 +85,10 @@ }, { "name" : "OtherApp", - "roles" : ["admin", "user"], + "roles" : [ + { "name" : "admin" }, + { "name" : "user" } + ], "roleMappings" : [ { "username" : "wburke",