@Override public HttpHandler createHttpHandler(Predicate predicate, final HttpHandler next) { // this is a bit of a hack at the moment. Basically we only want to create a single mod_cluster // instance // not matter how many filter refs use it, also mod_cluster at this point has no way // to specify the next handler. To get around this we invoke the mod_proxy handler // and then if it has not dispatched or handled the request then we know that we can // just pass it on to the next handler final HttpHandler mcmp = managementAccessPredicate != null ? Handlers.predicate(managementAccessPredicate, config.create(modCluster, next), next) : config.create(modCluster, next); final HttpHandler proxyHandler = modCluster.getProxyHandler(); HttpHandler theHandler = new HttpHandler() { @Override public void handleRequest(HttpServerExchange exchange) throws Exception { proxyHandler.handleRequest(exchange); if (!exchange.isDispatched() && !exchange.isComplete()) { exchange.setResponseCode(200); mcmp.handleRequest(exchange); } } }; UndertowLogger.ROOT_LOGGER.debug("HttpHandler for mod_cluster MCMP created."); if (predicate != null) { return new PredicateHandler(predicate, theHandler, next); } else { return theHandler; } }
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; }