Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package org.keycloak.jaxrs;
  
 
 
 import java.util.List;
 import java.util.Set;

Author(s):
Bill Burke
Version:
$Revision: 1 $
 
 public class JaxrsBearerTokenFilterImpl implements JaxrsBearerTokenFilter {
 
     private final static Logger log = Logger.getLogger("" + JaxrsBearerTokenFilterImpl.class);
 
     private String keycloakConfigFile;
     protected volatile boolean started;
 
 
     // TODO: Should also somehow handle stop lifecycle for de-registration
 
     public void setKeycloakConfigFile(String configFile) {
         this. = configFile;
         attemptStart();
     }
 
     public String getKeycloakConfigFile() {
         return this.;
     }
 
         return ;
     }
 
     public void setKeycloakConfigResolverClass(String keycloakConfigResolverClass) {
         this. = keycloakConfigResolverClass;
         attemptStart();
     }
 
     // INITIALIZATION AND STARTUP
 
     protected void attemptStart() {
         if () {
             throw new IllegalStateException("Filter already started. Make sure to specify just keycloakConfigResolver or keycloakConfigFile but not both");
         }
 
         if (isInitialized()) {
             start();
         } else {
             .fine("Not yet initialized");
         }
     }
 
     protected boolean isInitialized() {
         return this. != null || this. != null;
     }
 
     protected void start() {
         if () {
             throw new IllegalStateException("Filter already started. Make sure to specify just keycloakConfigResolver or keycloakConfigFile but not both");
         }
 
         if ( != null) {
             Class<? extends KeycloakConfigResolverresolverClass = loadResolverClass();
 
            try {
                KeycloakConfigResolver resolver = resolverClass.newInstance();
                .info("Using " + resolver + " to resolve Keycloak configuration on a per-request basis.");
                this. = new AdapterDeploymentContext(resolver);
            } catch (Exception e) {
                throw new RuntimeException("Unable to instantiate resolver " + resolverClass);
            }
        } else {
            if ( == null) {
                throw new IllegalArgumentException("You need to specify either keycloakConfigResolverClass or keycloakConfigFile in configuration");
            }
            InputStream is = loadKeycloakConfigFile();
            KeycloakDeployment kd = KeycloakDeploymentBuilder.build(is);
             = new AdapterDeploymentContext(kd);
            .info("Keycloak is using a per-deployment configuration loaded from: " + );
        }
         = true;
    }
    // TODO: Use 'Reflections.classForName'
    protected Class<? extends KeycloakConfigResolverloadResolverClass() {
        try {
        } catch (ClassNotFoundException cnfe) {
            // Fallback to tccl
            try {
                return (Class<? extends KeycloakConfigResolver>)Thread.currentThread().getContextClassLoader().loadClass();
            } catch (ClassNotFoundException cnfe2) {
                throw new RuntimeException("Unable to find resolver class: " + );
            }
        }
    }
    protected InputStream loadKeycloakConfigFile() {
            String classPathLocation = .replace(."");
            .fine("Loading config from classpath on location: " + classPathLocation);
            // Try current class classloader first
            InputStream is = getClass().getClassLoader().getResourceAsStream(classPathLocation);
            if (is == null) {
                is = Thread.currentThread().getContextClassLoader().getResourceAsStream(classPathLocation);
            }
            if (is != null) {
                return is;
            } else {
                throw new RuntimeException("Unable to find config from classpath: " + );
            }
        } else {
            // Fallback to file
            try {
                .fine("Loading config from file: " + );
                return new FileInputStream();
            } catch (FileNotFoundException fnfe) {
                .severe("Config not found on " + );
                throw new RuntimeException(fnfe);
            }
        }
    }
    // REQUEST HANDLING
    @Override
    public void filter(ContainerRequestContext requestthrows IOException {
        SecurityContext securityContext = getRequestSecurityContext(request);
        JaxrsHttpFacade facade = new JaxrsHttpFacade(requestsecurityContext);
        if (handlePreauth(facade)) {
            return;
        }
        KeycloakDeployment resolvedDeployment = .resolveDeployment(facade);
        .tryRegister(resolvedDeployment);
        bearerAuthentication(facaderequestresolvedDeployment);
    }
    protected boolean handlePreauth(JaxrsHttpFacade facade) {
        if (handler.handleRequest()) {
            // Send response now (if not already sent)
            if (!facade.isResponseFinished()) {
                facade.getResponse().end();
            }
            return true;
        }
        return false;
    }
    protected void bearerAuthentication(JaxrsHttpFacade facadeContainerRequestContext requestKeycloakDeployment resolvedDeployment) {
        BearerTokenRequestAuthenticator authenticator = new BearerTokenRequestAuthenticator(resolvedDeployment);
        AuthOutcome outcome = authenticator.authenticate(facade);
        
        if (outcome == . && resolvedDeployment.isEnableBasicAuth()) {
            authenticator = new BasicAuthRequestAuthenticator(resolvedDeployment);
            outcome = authenticator.authenticate(facade);
        }
        
        if (outcome == . || outcome == .) {
            AuthChallenge challenge = authenticator.getChallenge();
            .fine("Authentication outcome: " + outcome);
            boolean challengeSent = challenge.challenge(facade);
            if (!challengeSent) {
                // Use some default status code
                facade.getResponse().setStatus(...getStatusCode());
            }
            // Send response now (if not already sent)
            if (!facade.isResponseFinished()) {
                facade.getResponse().end();
            }
            return;
        } else {
            if (verifySslFailed(facaderesolvedDeployment)) {
                return;
            }
        }
        propagateSecurityContext(facaderequestresolvedDeploymentauthenticator);
        handleAuthActions(facaderesolvedDeployment);
    }
    protected void propagateSecurityContext(JaxrsHttpFacade facadeContainerRequestContext requestKeycloakDeployment resolvedDeploymentBearerTokenRequestAuthenticator bearer) {
        RefreshableKeycloakSecurityContext skSession = new RefreshableKeycloakSecurityContext(resolvedDeploymentnullbearer.getTokenString(), bearer.getToken(), nullnullnull);
        // Not needed to do resteasy specifics as KeycloakSecurityContext can be always retrieved from SecurityContext by typecast SecurityContext.getUserPrincipal to KeycloakPrincipal
        // ResteasyProviderFactory.pushContext(KeycloakSecurityContext.class, skSession);
        facade.setSecurityContext(skSession);
        String principalName = AdapterUtils.getPrincipalName(resolvedDeploymentbearer.getToken());
        final KeycloakPrincipal<RefreshableKeycloakSecurityContextprincipal = new KeycloakPrincipal<RefreshableKeycloakSecurityContext>(principalNameskSession);
        SecurityContext anonymousSecurityContext = getRequestSecurityContext(request);
        final boolean isSecure = anonymousSecurityContext.isSecure();
        final Set<Stringroles = AdapterUtils.getRolesFromSecurityContext(skSession);
        SecurityContext ctx = new SecurityContext() {
            @Override
            public Principal getUserPrincipal() {
                return principal;
            }
            @Override
            public boolean isUserInRole(String role) {
                return roles.contains(role);
            }
            @Override
            public boolean isSecure() {
                return isSecure;
            }
            @Override
            public String getAuthenticationScheme() {
                return "OAUTH_BEARER";
            }
        };
        request.setSecurityContext(ctx);
    }
    protected boolean verifySslFailed(JaxrsHttpFacade facadeKeycloakDeployment deployment) {
        if (!facade.getRequest().isSecure() && deployment.getSslRequired().isRequired(facade.getRequest().getRemoteAddr())) {
            .warning("SSL is required to authenticate, but request is not secured");
            facade.getResponse().sendError(403, "SSL required!");
            return true;
        }
        return false;
    }
        return request.getSecurityContext();
    }
    protected void handleAuthActions(JaxrsHttpFacade facadeKeycloakDeployment deployment) {
        AuthenticatedActionsHandler authActionsHandler = new AuthenticatedActionsHandler(deploymentfacade);
        if (authActionsHandler.handledRequest()) {
            // Send response now (if not already sent)
            if (!facade.isResponseFinished()) {
                facade.getResponse().end();
            }
        }
    }
    // We don't have any sessions to manage with pure jaxrs filter
    private static class EmptyUserSessionManagement implements UserSessionManagement {
        @Override
        public void logoutAll() {
        }
        @Override
        public void logoutHttpSessions(List<Stringids) {
        }
    }
New to GrepCode? Check out our FAQ X