/** * sets up the outer security handlers. * * <p>the handler that actually performs the access check happens later in the chain, it is not * setup here * * @param initialHandler The handler to wrap with security handlers */ private HttpHandler setupSecurityHandlers(HttpHandler initialHandler) { final DeploymentInfo deploymentInfo = deployment.getDeploymentInfo(); final LoginConfig loginConfig = deploymentInfo.getLoginConfig(); HttpHandler current = initialHandler; final SecurityPathMatches securityPathMatches = buildSecurityConstraints(); current = new AuthenticationCallHandler(current); if (!securityPathMatches.isEmpty()) { current = new ServletAuthenticationConstraintHandler(current); } current = new ServletConfidentialityConstraintHandler( deploymentInfo.getConfidentialPortManager(), current); if (!securityPathMatches.isEmpty()) { current = new ServletSecurityConstraintHandler(securityPathMatches, current); } final String mechName; if (loginConfig != null) { List<AuthenticationMechanism> authenticationMechanisms = new LinkedList<AuthenticationMechanism>(); authenticationMechanisms.add(new CachedAuthenticatedSessionMechanism()); mechName = loginConfig.getAuthMethod(); if (mechName.equalsIgnoreCase(BASIC_AUTH)) { // The mechanism name is passed in from the HttpServletRequest interface as the name // reported needs to be comparable using '==' authenticationMechanisms.add( new BasicAuthenticationMechanism(loginConfig.getRealmName(), BASIC_AUTH)); } else if (mechName.equalsIgnoreCase(FORM_AUTH)) { // The mechanism name is passed in from the HttpServletRequest interface as the name // reported needs to be comparable using '==' authenticationMechanisms.add( new ServletFormAuthenticationMechanism( FORM_AUTH, loginConfig.getLoginPage(), loginConfig.getErrorPage())); } else if (mechName.equalsIgnoreCase(CLIENT_CERT_AUTH)) { authenticationMechanisms.add(new ClientCertAuthenticationMechanism(CLIENT_CERT_AUTH)); } else { // NYI } current = new AuthenticationMechanismsHandler(current, authenticationMechanisms); } else { mechName = null; } current = new CachedAuthenticatedSessionHandler(current, this.deployment.getServletContext()); List<NotificationReceiver> notificationReceivers = deploymentInfo.getNotificationReceivers(); if (notificationReceivers.isEmpty() == false) { current = new NotificationReceiverHandler(current, notificationReceivers); } // TODO - A switch to constraint driven could be configurable, however before we can support // that with servlets we would // need additional tracking within sessions if a servlet has specifically requested that // authentication occurs. current = new SecurityInitialHandler( AuthenticationMode.PRO_ACTIVE, deploymentInfo.getIdentityManager(), mechName, current); return current; }
@Override public void handleDeployment(DeploymentInfo deploymentInfo, ServletContext servletContext) { if (!isAuthenticationMechanismPresent(deploymentInfo, "KEYCLOAK")) { log.info("auth-method is not keycloak!"); return; } log.info("KeycloakServletException initialization"); InputStream is = servletContext.getResourceAsStream("/WEB-INF/keycloak.json"); if (is == null) throw new RuntimeException("Unable to find /WEB-INF/keycloak.json configuration file"); RealmConfigurationLoader loader = new RealmConfigurationLoader(is); loader.init(true); AdapterConfig keycloakConfig = loader.getAdapterConfig(); RealmConfiguration realmConfiguration = loader.getRealmConfiguration(); PreflightCorsHandler.Wrapper preflight = new PreflightCorsHandler.Wrapper(keycloakConfig); UserSessionManagement userSessionManagement = new UserSessionManagement(realmConfiguration); ServletKeycloakAuthenticationMechanism auth = null; if (keycloakConfig.isBearerOnly()) { auth = new ServletKeycloakAuthenticationMechanism( keycloakConfig, loader.getResourceMetadata(), deploymentInfo.getConfidentialPortManager()); } else { auth = new ServletKeycloakAuthenticationMechanism( userSessionManagement, keycloakConfig, realmConfiguration, deploymentInfo.getConfidentialPortManager()); } ServletAuthenticatedActionsHandler.Wrapper actions = new ServletAuthenticatedActionsHandler.Wrapper(keycloakConfig); // setup handlers deploymentInfo.addInitialHandlerChainWrapper(preflight); // cors preflight deploymentInfo.addOuterHandlerChainWrapper( new ServletAdminActionsHandler.Wrapper(realmConfiguration, userSessionManagement)); final ServletKeycloakAuthenticationMechanism theAuth = auth; deploymentInfo.addAuthenticationMechanism( "KEYCLOAK", new AuthenticationMechanismFactory() { @Override public AuthenticationMechanism create( String s, FormParserFactory formParserFactory, Map<String, String> stringStringMap) { return theAuth; } }); // authentication deploymentInfo.addInnerHandlerChainWrapper( ServletPropagateSessionHandler.WRAPPER); // propagates SkeletonKeySession deploymentInfo.addInnerHandlerChainWrapper(actions); // handles authenticated actions and cors. deploymentInfo.setIdentityManager( new IdentityManager() { @Override public Account verify(Account account) { log.info("Verifying account in IdentityManager"); return account; } @Override public Account verify(String id, Credential credential) { log.warn("Shouldn't call verify!!!"); throw new IllegalStateException("Not allowed"); } @Override public Account verify(Credential credential) { log.warn("Shouldn't call verify!!!"); throw new IllegalStateException("Not allowed"); } }); log.info("Setting jsession cookie path to: " + deploymentInfo.getContextPath()); ServletSessionConfig cookieConfig = new ServletSessionConfig(); cookieConfig.setPath(deploymentInfo.getContextPath()); deploymentInfo.setServletSessionConfig(cookieConfig); }
private HttpHandler setupSecurityHandlers(HttpHandler initialHandler) { final DeploymentInfo deploymentInfo = super.getDeployment().getDeploymentInfo(); final LoginConfig loginConfig = deploymentInfo.getLoginConfig(); final Map<String, AuthenticationMechanismFactory> factoryMap = new HashMap<>(deploymentInfo.getAuthenticationMechanisms()); if (!factoryMap.containsKey(BASIC_AUTH)) { factoryMap.put(BASIC_AUTH, BasicAuthenticationMechanism.FACTORY); } if (!factoryMap.containsKey(FORM_AUTH)) { factoryMap.put(FORM_AUTH, ServletFormAuthenticationMechanism.FACTORY); } if (!factoryMap.containsKey(DIGEST_AUTH)) { factoryMap.put(DIGEST_AUTH, DigestAuthenticationMechanism.FACTORY); } if (!factoryMap.containsKey(CLIENT_CERT_AUTH)) { factoryMap.put(CLIENT_CERT_AUTH, ClientCertAuthenticationMechanism.FACTORY); } if (!factoryMap.containsKey(ExternalAuthenticationMechanism.NAME)) { factoryMap.put(ExternalAuthenticationMechanism.NAME, ExternalAuthenticationMechanism.FACTORY); } HttpHandler current = initialHandler; current = new SSLInformationAssociationHandler(current); final SecurityPathMatches securityPathMatches = buildSecurityConstraints(); current = new ServletAuthenticationCallHandler(current); if (deploymentInfo.isDisableCachingForSecuredPages()) { current = Handlers.predicate(Predicates.authRequired(), Handlers.disableCache(current), current); } if (!securityPathMatches.isEmpty()) { current = new ServletAuthenticationConstraintHandler(current); } current = new ServletConfidentialityConstraintHandler( deploymentInfo.getConfidentialPortManager(), current); if (!securityPathMatches.isEmpty()) { current = new ServletSecurityConstraintHandler(securityPathMatches, current); } List<AuthenticationMechanism> authenticationMechanisms = new LinkedList<>(); authenticationMechanisms.add( new CachedAuthenticatedSessionMechanism()); // TODO: does this really need to be hard coded? String mechName = null; if (loginConfig != null || deploymentInfo.getJaspiAuthenticationMechanism() != null) { // we don't allow multipart requests, and always use the default encoding FormParserFactory parser = FormParserFactory.builder(false) .addParser( new FormEncodedDataDefinition() .setDefaultEncoding(deploymentInfo.getDefaultEncoding())) .build(); List<AuthMethodConfig> authMethods = Collections.<AuthMethodConfig>emptyList(); if (loginConfig != null) { authMethods = loginConfig.getAuthMethods(); } for (AuthMethodConfig method : authMethods) { AuthenticationMechanismFactory factory = factoryMap.get(method.getName()); if (factory == null) { throw UndertowServletMessages.MESSAGES.unknownAuthenticationMechanism(method.getName()); } if (mechName == null) { mechName = method.getName(); } final Map<String, String> properties = new HashMap<>(); properties.put( AuthenticationMechanismFactory.CONTEXT_PATH, deploymentInfo.getContextPath()); properties.put(AuthenticationMechanismFactory.REALM, loginConfig.getRealmName()); properties.put(AuthenticationMechanismFactory.ERROR_PAGE, loginConfig.getErrorPage()); properties.put(AuthenticationMechanismFactory.LOGIN_PAGE, loginConfig.getLoginPage()); properties.putAll(method.getProperties()); String name = method.getName().toUpperCase(Locale.US); // The mechanism name is passed in from the HttpServletRequest interface as the name // reported needs to be // comparable using '==' name = name.equals(FORM_AUTH) ? FORM_AUTH : name; name = name.equals(BASIC_AUTH) ? BASIC_AUTH : name; name = name.equals(DIGEST_AUTH) ? DIGEST_AUTH : name; name = name.equals(CLIENT_CERT_AUTH) ? CLIENT_CERT_AUTH : name; authenticationMechanisms.add(factory.create(name, parser, properties)); } } ((DeploymentImpl) super.getDeployment()).setAuthenticationMechanisms(authenticationMechanisms); // if the JASPI auth mechanism is set then it takes over if (deploymentInfo.getJaspiAuthenticationMechanism() == null) { current = new AuthenticationMechanismsHandler(current, authenticationMechanisms); } else { current = new AuthenticationMechanismsHandler( current, Collections.<AuthenticationMechanism>singletonList( deploymentInfo.getJaspiAuthenticationMechanism())); } current = new CachedAuthenticatedSessionHandler(current, super.getDeployment().getServletContext()); List<NotificationReceiver> notificationReceivers = deploymentInfo.getNotificationReceivers(); if (!notificationReceivers.isEmpty()) { current = new NotificationReceiverHandler(current, notificationReceivers); } // TODO - A switch to constraint driven could be configurable, however before we can support // that with servlets we would // need additional tracking within sessions if a servlet has specifically requested that // authentication occurs. SecurityContextFactory contextFactory = deploymentInfo.getSecurityContextFactory(); if (contextFactory == null) { contextFactory = SecurityContextFactoryImpl.INSTANCE; } current = new SecurityInitialHandler( AuthenticationMode.PRO_ACTIVE, deploymentInfo.getIdentityManager(), mechName, contextFactory, current); return current; }