Merge pull request #4 from patriot1burke/master

refactoring
This commit is contained in:
Bill Burke 2013-07-18 07:28:55 -07:00
commit c3681df76c
9 changed files with 75 additions and 67 deletions

View file

@ -2,14 +2,14 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<name>Identity Guardener</name>
<name>Keycloak</name>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-parent</artifactId>
<version>1.0-alpha-1</version>
<packaging>pom</packaging>
<properties>
<resteasy.version>3.0.1.Final</resteasy.version>
<resteasy.version>3.0.2.Final</resteasy.version>
</properties>
<url>http://keycloak.org</url>

View file

@ -21,6 +21,8 @@ import java.util.HashSet;
import java.util.Set;
/**
* Stateless object that manages authentication
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/

View file

@ -13,16 +13,50 @@ 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 <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class TokenManager {
protected Map<String, AccessCodeEntry> accessCodeMap = new ConcurrentHashMap<String, AccessCodeEntry>();
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());

View file

@ -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();
}
}
}

View file

@ -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() {

View file

@ -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);

View file

@ -24,7 +24,7 @@ public class RealmSubResource {
protected UriInfo uriInfo;
@Context
protected IdentitySession IdentitySession;
protected IdentitySession identitySession;
protected RealmModel realm;

View file

@ -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 <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@ -55,23 +54,26 @@ public class RealmsResource {
protected HttpHeaders headers;
@Context
protected
IdentitySession IdentitySession;
protected IdentitySession identitySession;
@Context
ResourceContext resourceContext;
protected Map<String, AccessCodeEntry> accessCodes = new ConcurrentHashMap<String, AccessCodeEntry>();
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);

View file

@ -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<String, AccessCodeEntry> accessCodeMap;
//protected Map<String, AccessCodeEntry> 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<String, AccessCodeEntry> 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<String, String> res = new HashMap<String, String>();
res.put("error", "invalid_grant");