package org.jboss.resteasy.keystone.as7;
import org.apache.catalina.connector.Request;
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.jboss.resteasy.keystone.client.SkeletonKeyAdminClient;
import org.jboss.resteasy.keystone.client.SkeletonKeyClientBuilder;
import org.jboss.resteasy.keystone.core.UserPrincipal;
import org.jboss.resteasy.keystone.model.Access;
import org.jboss.resteasy.keystone.model.Role;
import org.jboss.resteasy.logging.Logger;
import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.jboss.security.SimpleGroup;
import org.jboss.security.SimplePrincipal;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.client.WebTarget;
import java.security.Principal;
import java.security.acl.Group;
import java.util.Map;
/**
* Keystone Access token protocol
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class SkeletonKeyStoneLoginModule extends JBossWebAuthLoginModule
{
static ResteasyClient client;
static volatile SkeletonKeyAdminClient admin;
private static final Logger log = Logger.getLogger(SkeletonKeyStoneLoginModule.class);
static
{
ResteasyProviderFactory providerFactory = new ResteasyProviderFactory();
ClassLoader old = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(SkeletonKeyStoneLoginModule.class.getClassLoader());
try
{
RegisterBuiltin.register(providerFactory);
}
finally
{
Thread.currentThread().setContextClassLoader(old);
}
client = new ResteasyClientBuilder().providerFactory(providerFactory)
.connectionPoolSize(100)
.maxPooledPerRoute(100).build();
}
static void initAdmin(Map<String, ?> options)
{
SkeletonKeyAdminClient tmp = admin;
if (tmp == null)
{
synchronized (client)
{
tmp = admin;
if (tmp == null)
{
String adminUrl = (String) options.get("skeleton.key.url");
String username = (String) options.get("admin.username");
String password = (String) options.get("admin.password");
WebTarget adminTarget = client.target(adminUrl);
tmp = admin = new SkeletonKeyClientBuilder().username(username).password(password).idp(adminTarget).admin();
}
}
}
}
protected String projectId;
protected Access access;
@Override
public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options)
{
super.initialize(subject, callbackHandler, sharedState, options);
initAdmin(options);
projectId = (String) options.get("projectId");
}
@Override
protected boolean login(Request request, HttpServletResponse response) throws LoginException
{
String tokenHeader = request.getHeader("X-Auth-Token");
if (tokenHeader == null) return false; //throw new LoginException("No X-Auth-Token");
access = admin.tokens().get(tokenHeader);
if (access.getToken().expired())
{
throw new LoginException("Token expired");
}
if (!projectId.equals(access.getToken().getProject().getId()))
{
throw new LoginException("Token project id doesn't match");
}
this.loginOk = true;
return true;
}
@Override
protected Principal getIdentity()
{
Principal principal = new UserPrincipal(access.getUser());
return principal;
}
@Override
protected Group[] getRoleSets() throws LoginException
{
SimpleGroup roles = new SimpleGroup("Roles");
Group[] roleSets = {roles};
for (Role role : access.getUser().getRoles())
{
roles.addMember(new SimplePrincipal(role.getName()));
}
return roleSets;
}
}