package org.jboss.resteasy.skeleton.key.jaxrs; import org.jboss.resteasy.skeleton.key.RSATokenVerifier; import org.jboss.resteasy.skeleton.key.ResourceMetadata; import org.jboss.resteasy.skeleton.key.SkeletonKeyPrincipal; import org.jboss.resteasy.skeleton.key.SkeletonKeySession; import org.jboss.resteasy.skeleton.key.VerificationException; import org.jboss.resteasy.skeleton.key.i18n.LogMessages; import org.jboss.resteasy.skeleton.key.i18n.Messages; import org.jboss.resteasy.skeleton.key.representations.SkeletonKeyToken; import org.jboss.resteasy.spi.ResteasyProviderFactory; import javax.annotation.Priority; import javax.ws.rs.Priorities; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.core.Context; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.Response; import javax.ws.rs.core.SecurityContext; import java.io.IOException; import java.security.Principal; /** * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @version $Revision: 1 $ */ @Priority(Priorities.AUTHENTICATION) public class JaxrsBearerTokenFilter implements ContainerRequestFilter { protected ResourceMetadata resourceMetadata; public JaxrsBearerTokenFilter(ResourceMetadata resourceMetadata) { this.resourceMetadata = resourceMetadata; } protected void challengeResponse(ContainerRequestContext request, String error, String description) { StringBuilder header = new StringBuilder("Bearer realm=\""); header.append(resourceMetadata.getRealm()).append("\""); if (error != null) { header.append(", error=\"").append(error).append("\""); } if (description != null) { header.append(", error_description=\"").append(description).append("\""); } request.abortWith(Response.status(401).header("WWW-Authenticate", header.toString()).build()); return; } @Context protected SecurityContext securityContext; @Override public void filter(ContainerRequestContext request) throws IOException { String authHeader = request.getHeaderString(HttpHeaders.AUTHORIZATION); if (authHeader == null) { challengeResponse(request, null, null); return; } String[] split = authHeader.trim().split("\\s+"); if (split == null || split.length != 2) challengeResponse(request, null, null); if (!split[0].equalsIgnoreCase("Bearer")) challengeResponse(request, null, null); String tokenString = split[1]; try { SkeletonKeyToken token = RSATokenVerifier.verifyToken(tokenString, resourceMetadata); SkeletonKeySession skSession = new SkeletonKeySession(tokenString, resourceMetadata); ResteasyProviderFactory.pushContext(SkeletonKeySession.class, skSession); String callerPrincipal = securityContext.getUserPrincipal() != null ? securityContext.getUserPrincipal().getName() : null; final SkeletonKeyPrincipal principal = new SkeletonKeyPrincipal(token.getPrincipal(), callerPrincipal); final boolean isSecure = securityContext.isSecure(); final SkeletonKeyToken.Access access; if (resourceMetadata.getResourceName() != null) { access = token.getResourceAccess(resourceMetadata.getResourceName()); } else { access = token.getRealmAccess(); } SecurityContext ctx = new SecurityContext() { @Override public Principal getUserPrincipal() { return principal; } @Override public boolean isUserInRole(String role) { if (access.getRoles() == null) return false; return access.getRoles().contains(role); } @Override public boolean isSecure() { return isSecure; } @Override public String getAuthenticationScheme() { return "OAUTH_BEARER"; } }; request.setSecurityContext(ctx); } catch (VerificationException e) { LogMessages.LOGGER.error(Messages.MESSAGES.failedToVerifyToken(), e); challengeResponse(request, "invalid_token", e.getMessage()); } } }