diff --git a/pom.xml b/pom.xml
index bcb889c1f5..6ba8fd23c4 100755
--- a/pom.xml
+++ b/pom.xml
@@ -2,14 +2,14 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
4.0.0
- Identity Guardener
+ Keycloak
org.keycloak
keycloak-parent
1.0-alpha-1
pom
- 3.0.1.Final
+ 3.0.2.Final
http://keycloak.org
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 7b725da747..e77e1c66a4 100755
--- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
@@ -21,6 +21,8 @@ import java.util.HashSet;
import java.util.Set;
/**
+ * Stateless object that manages authentication
+ *
* @author Bill Burke
* @version $Revision: 1 $
*/
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 6c015048f5..dc54604c59 100755
--- a/services/src/main/java/org/keycloak/services/managers/TokenManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/TokenManager.java
@@ -13,17 +13,51 @@ import org.picketlink.idm.model.User;
import javax.ws.rs.ForbiddenException;
import javax.ws.rs.core.Response;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
/**
+ * Stateful object that creates tokens and manages oauth access codes
+ *
* @author Bill Burke
* @version $Revision: 1 $
*/
public class TokenManager {
- public SkeletonKeyToken createScopedToken(SkeletonKeyScope scope, RealmModel realm, User client, User user) {
+ protected Map accessCodeMap = new ConcurrentHashMap();
+
+ public void clearAccessCodes() {
+ accessCodeMap.clear();
+ }
+
+ public AccessCodeEntry pullAccessCode(String key) {
+ return accessCodeMap.remove(key);
+ }
+
+ public String createAccessCode(String scopeParam, RealmModel realm, User client, User user)
+ {
+ SkeletonKeyToken token = null;
+ if (scopeParam != null) token = createScopedToken(scopeParam, realm, client, user);
+ else token = createLoginToken(realm, client, user);
+
+ AccessCodeEntry code = new AccessCodeEntry();
+ code.setExpiration((System.currentTimeMillis() / 1000) + realm.getAccessCodeLifespan());
+ code.setToken(token);
+ code.setClient(client);
+ accessCodeMap.put(code.getId(), code);
+ String accessCode = null;
+ try {
+ accessCode = new JWSBuilder().content(code.getId().getBytes("UTF-8")).rsa256(realm.getPrivateKey());
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ return accessCode;
+ }
+
+ public SkeletonKeyToken createScopedToken(SkeletonKeyScope scope, RealmModel realm, User client, User user) {
SkeletonKeyToken token = new SkeletonKeyToken();
token.id(RealmManager.generateId());
token.principal(user.getLoginName());
diff --git a/services/src/main/java/org/keycloak/services/models/RealmManager.java b/services/src/main/java/org/keycloak/services/models/RealmManager.java
index 6ee87cea25..77a75b3cc3 100755
--- a/services/src/main/java/org/keycloak/services/models/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/models/RealmManager.java
@@ -1,15 +1,10 @@
package org.keycloak.services.models;
-import org.keycloak.representations.idm.UserRepresentation;
-import org.picketlink.idm.IdentitySession;
import org.picketlink.idm.IdentityManager;
+import org.picketlink.idm.IdentitySession;
import org.picketlink.idm.model.Realm;
-import org.picketlink.idm.model.Role;
import org.picketlink.idm.model.SimpleAgent;
-import org.picketlink.idm.model.SimpleUser;
-import org.picketlink.idm.model.User;
-import javax.ws.rs.core.Response;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
@@ -26,10 +21,10 @@ public class RealmManager {
return counter.getAndIncrement() + "-" + System.currentTimeMillis();
}
- protected IdentitySession IdentitySession;
+ protected IdentitySession identitySession;
public RealmManager(IdentitySession IdentitySession) {
- this.IdentitySession = IdentitySession;
+ this.identitySession = IdentitySession;
}
public RealmModel defaultRealm() {
@@ -37,11 +32,11 @@ public class RealmManager {
}
public RealmModel getRealm(String id) {
- Realm existing = IdentitySession.findRealm(id);
+ Realm existing = identitySession.findRealm(id);
if (existing == null) {
return null;
}
- return new RealmModel(existing, IdentitySession);
+ return new RealmModel(existing, identitySession);
}
public RealmModel createRealm(String name) {
@@ -49,11 +44,11 @@ public class RealmManager {
}
public RealmModel createRealm(String id, String name) {
- Realm newRealm = IdentitySession.createRealm(id);
- IdentityManager idm = IdentitySession.createIdentityManager(newRealm);
+ Realm newRealm = identitySession.createRealm(id);
+ IdentityManager idm = identitySession.createIdentityManager(newRealm);
SimpleAgent agent = new SimpleAgent(RealmModel.REALM_AGENT_ID);
idm.add(agent);
- RealmModel realm = new RealmModel(newRealm, IdentitySession);
+ RealmModel realm = new RealmModel(newRealm, identitySession);
return realm;
}
@@ -68,4 +63,4 @@ public class RealmManager {
realm.setPublicKey(keyPair.getPublic());
realm.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 cb343b0989..bad532c657 100755
--- a/services/src/main/java/org/keycloak/services/models/ResourceModel.java
+++ b/services/src/main/java/org/keycloak/services/models/ResourceModel.java
@@ -5,7 +5,6 @@ import org.keycloak.services.models.relationships.ScopeRelationship;
import org.picketlink.idm.IdentitySession;
import org.picketlink.idm.IdentityManager;
import org.picketlink.idm.model.Agent;
-import org.picketlink.idm.model.Attribute;
import org.picketlink.idm.model.Grant;
import org.picketlink.idm.model.Role;
import org.picketlink.idm.model.Tier;
@@ -22,24 +21,20 @@ import java.util.Set;
* @version $Revision: 1 $
*/
public class ResourceModel {
- public static final String RESOURCE_AGENT_ID = "_resource_";
- public static final String RESOURCE_NAME = "name";
- public static final String RESOURCE_SURROGATE_AUTH = "surrogate_auth";
-
protected Tier tier;
protected ResourceRelationship agent;
protected RealmModel realm;
- protected IdentitySession IdentitySession;
+ protected IdentitySession identitySession;
- public ResourceModel(Tier tier, ResourceRelationship agent, RealmModel realm, IdentitySession factory) {
+ public ResourceModel(Tier tier, ResourceRelationship agent, RealmModel realm, IdentitySession session) {
this.tier = tier;
this.agent = agent;
this.realm = realm;
- this.IdentitySession = factory;
+ this.identitySession = session;
}
public IdentityManager getIdm() {
- return IdentitySession.createIdentityManager(tier);
+ return identitySession.createIdentityManager(tier);
}
public void updateResource() {
diff --git a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
index 3af3e9c1f8..79b9f47470 100755
--- a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
+++ b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
@@ -2,6 +2,7 @@ package org.keycloak.services.resources;
import org.keycloak.SkeletonKeyContextResolver;
import org.keycloak.services.filters.IdentitySessionFilter;
+import org.keycloak.services.managers.TokenManager;
import org.keycloak.services.models.relationships.RealmAdminRelationship;
import org.keycloak.services.models.relationships.ResourceRelationship;
import org.keycloak.services.models.relationships.RequiredCredentialRelationship;
@@ -38,7 +39,7 @@ public class KeycloakApplication extends Application {
public KeycloakApplication() {
this.factory = createFactory();
IdentitySessionFilter filter = new IdentitySessionFilter(factory);
- singletons.add(new RealmsResource());
+ singletons.add(new RealmsResource(new TokenManager()));
singletons.add(filter);
classes.add(SkeletonKeyContextResolver.class);
classes.add(RegistrationService.class);
diff --git a/services/src/main/java/org/keycloak/services/resources/RealmSubResource.java b/services/src/main/java/org/keycloak/services/resources/RealmSubResource.java
index 9d76a21a60..8e33a5ad13 100755
--- a/services/src/main/java/org/keycloak/services/resources/RealmSubResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/RealmSubResource.java
@@ -24,7 +24,7 @@ public class RealmSubResource {
protected UriInfo uriInfo;
@Context
- protected IdentitySession IdentitySession;
+ protected IdentitySession identitySession;
protected RealmModel realm;
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 b749569102..cf7576d431 100755
--- a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
@@ -7,8 +7,8 @@ import org.keycloak.representations.idm.ResourceRepresentation;
import org.keycloak.representations.idm.RoleMappingRepresentation;
import org.keycloak.representations.idm.ScopeMappingRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
-import org.keycloak.services.managers.AccessCodeEntry;
import org.keycloak.services.managers.AuthenticationManager;
+import org.keycloak.services.managers.TokenManager;
import org.keycloak.services.models.RealmManager;
import org.keycloak.services.models.RealmModel;
import org.keycloak.services.models.RequiredCredentialModel;
@@ -38,7 +38,6 @@ import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import java.util.HashMap;
import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
/**
* @author Bill Burke
@@ -55,23 +54,26 @@ public class RealmsResource {
protected HttpHeaders headers;
@Context
- protected
- IdentitySession IdentitySession;
+ protected IdentitySession identitySession;
@Context
ResourceContext resourceContext;
- protected Map accessCodes = new ConcurrentHashMap();
+ protected TokenManager tokenManager;
+
+ public RealmsResource(TokenManager tokenManager) {
+ this.tokenManager = tokenManager;
+ }
@Path("{realm}/tokens")
public TokenService getTokenService(@PathParam("realm") String id) {
- RealmManager realmManager = new RealmManager(IdentitySession);
+ RealmManager realmManager = new RealmManager(identitySession);
RealmModel realm = realmManager.getRealm(id);
if (realm == null) {
logger.debug("realm not found");
throw new NotFoundException();
}
- TokenService tokenService = new TokenService(realm, accessCodes);
+ TokenService tokenService = new TokenService(realm, tokenManager);
resourceContext.initResource(tokenService);
return tokenService;
@@ -80,7 +82,7 @@ public class RealmsResource {
@Path("{realm}")
public RealmSubResource getRealmResource(@PathParam("realm") String id) {
- RealmManager realmManager = new RealmManager(IdentitySession);
+ RealmManager realmManager = new RealmManager(identitySession);
RealmModel realm = realmManager.getRealm(id);
if (realm == null) {
logger.debug("realm not found");
@@ -96,13 +98,13 @@ public class RealmsResource {
@POST
@Consumes("application/json")
public Response importRealm(RealmRepresentation rep) {
- IdentitySession.getTransaction().begin();
+ identitySession.getTransaction().begin();
RealmModel realm;
try {
realm = createRealm(rep);
- IdentitySession.getTransaction().commit();
+ identitySession.getTransaction().commit();
} catch (RuntimeException re) {
- IdentitySession.getTransaction().rollback();
+ identitySession.getTransaction().rollback();
throw re;
}
UriBuilder builder = uriInfo.getRequestUriBuilder().path(realm.getId());
@@ -112,7 +114,7 @@ public class RealmsResource {
}
protected RealmModel createRealm(RealmRepresentation rep) {
- RealmManager realmManager = new RealmManager(IdentitySession);
+ RealmManager realmManager = new RealmManager(identitySession);
RealmModel defaultRealm = realmManager.getRealm(Realm.DEFAULT_REALM);
User realmCreator = new AuthenticationManager().authenticateToken(defaultRealm, headers);
Role creatorRole = defaultRealm.getIdm().getRole(RegistrationService.REALM_CREATOR_ROLE);
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 d77339daef..b9831ce500 100755
--- a/services/src/main/java/org/keycloak/services/resources/TokenService.java
+++ b/services/src/main/java/org/keycloak/services/resources/TokenService.java
@@ -12,7 +12,6 @@ import org.keycloak.representations.SkeletonKeyToken;
import org.keycloak.services.managers.AccessCodeEntry;
import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.managers.TokenManager;
-import org.keycloak.services.models.RealmManager;
import org.keycloak.services.models.RealmModel;
import org.keycloak.services.models.RequiredCredentialModel;
import org.keycloak.services.models.ResourceModel;
@@ -35,7 +34,6 @@ import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.ext.Providers;
-import java.io.UnsupportedEncodingException;
import java.security.PrivateKey;
import java.util.HashMap;
import java.util.List;
@@ -50,7 +48,7 @@ public class TokenService {
protected static final Logger logger = Logger.getLogger(TokenService.class);
- protected Map accessCodeMap;
+ //protected Map accessCodeMap;
@Context
protected UriInfo uriInfo;
@@ -65,12 +63,12 @@ public class TokenService {
IdentitySession IdentitySession;
protected RealmModel realm;
- protected TokenManager tokenManager = new TokenManager();
+ protected TokenManager tokenManager;
protected AuthenticationManager authManager = new AuthenticationManager();
- public TokenService(RealmModel realm, Map accessCodeMap) {
+ public TokenService(RealmModel realm, TokenManager tokenManager) {
this.realm = realm;
- this.accessCodeMap = accessCodeMap;
+ this.tokenManager = tokenManager;
}
@Path("grants/identity-token")
@@ -163,23 +161,7 @@ public class TokenService {
if (!authenticated)
return loginForm("Unable to authenticate, try again", redirect, clientId, scopeParam, state, realm, client);
- SkeletonKeyToken token = null;
- if (scopeParam != null) token = tokenManager.createScopedToken(scopeParam, realm, client, user);
- else token = tokenManager.createLoginToken(realm, client, user);
-
- AccessCodeEntry code = new AccessCodeEntry();
- code.setExpiration((System.currentTimeMillis() / 1000) + realm.getAccessCodeLifespan());
- code.setToken(token);
- code.setClient(client);
- synchronized (accessCodeMap) {
- accessCodeMap.put(code.getId(), code);
- }
- String accessCode = null;
- try {
- accessCode = new JWSBuilder().content(code.getId().getBytes("UTF-8")).rsa256(realm.getPrivateKey());
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException(e);
- }
+ String accessCode = tokenManager.createAccessCode(scopeParam, realm, client, user);
UriBuilder redirectUri = UriBuilder.fromUri(redirect).queryParam("code", accessCode);
if (state != null) redirectUri.queryParam("state", state);
return Response.status(302).location(redirectUri.build()).build();
@@ -249,10 +231,7 @@ public class TokenService {
return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res).build();
}
String key = input.readContent(String.class);
- AccessCodeEntry accessCode = null;
- synchronized (accessCodeMap) {
- accessCode = accessCodeMap.remove(key);
- }
+ AccessCodeEntry accessCode = tokenManager.pullAccessCode(key);
if (accessCode == null) {
Map res = new HashMap();
res.put("error", "invalid_grant");