package org.jboss.resteasy.keystone.core; import org.jboss.resteasy.keystone.core.i18n.LogMessages; import org.jboss.resteasy.keystone.core.i18n.Messages; import org.jboss.resteasy.keystone.model.Access; import org.jboss.resteasy.keystone.model.Role; import org.jboss.resteasy.security.smime.PKCS7SignatureInput; import javax.ws.rs.WebApplicationException; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.SecurityContext; import javax.ws.rs.ext.Providers; import java.io.IOException; import java.security.Principal; import java.security.cert.X509Certificate; import java.util.HashSet; import java.util.Set; /** * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @version $Revision: 1 $ */ public abstract class AbstractTokenAuthFilter implements ContainerRequestFilter { protected X509Certificate certificate; protected AbstractTokenAuthFilter(X509Certificate certificate) { this.certificate = certificate; } @Context SecurityContext securityContext; @Context Providers providers; @SuppressWarnings(value = "unchecked") protected Access signed(String header) { PKCS7SignatureInput input = null; boolean verify = false; try { input = new PKCS7SignatureInput(header); input.setProviders(providers); verify = input.verify(certificate); } catch (Exception e) { throw new WebApplicationException(403); } if (!verify) throw new WebApplicationException(403); try { return (Access)input.getEntity(Access.class, MediaType.APPLICATION_JSON_TYPE); } catch (Exception e) { LogMessages.LOGGER.error(Messages.MESSAGES.failedToUnmarshall(), e); throw new WebApplicationException(403); } } protected abstract Access getTokenFromServer(String header); @Override public void filter(ContainerRequestContext requestContext) throws IOException { String xAuthToken = requestContext.getHeaderString("X-Auth-Token"); String xAuthSignedToken = requestContext.getHeaderString("X-Auth-Signed-Token"); Access token = null; if (xAuthToken == null && xAuthSignedToken == null) return; else if (xAuthSignedToken != null && certificate != null) { token = signed(xAuthSignedToken); } else if (xAuthToken != null) { token = getTokenFromServer(xAuthToken); } if (token == null) return; // do nothing if (token.getToken().expired()) return; // todo maybe throw 401 with an error stating token is expired? final UserPrincipal principal = new UserPrincipal(token.getUser()); final Set<String> roleSet = new HashSet<String>(); for (Role role : token.getUser().getRoles()) { roleSet.add(role.getName()); } SecurityContext ctx = new SecurityContext() { @Override public Principal getUserPrincipal() { return principal; } @Override public boolean isUserInRole(String role) { return roleSet.contains(role); } @Override public boolean isSecure() { return securityContext.isSecure(); } @Override public String getAuthenticationScheme() { return securityContext.getAuthenticationScheme(); } }; requestContext.setSecurityContext(ctx); } }