* 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;
current = new SSLInformationAssociationHandler(current);
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);
}
String mechName = null;
if (loginConfig != null || !deploymentInfo.getAdditionalAuthenticationMechanisms().isEmpty()) {
List<AuthenticationMechanism> authenticationMechanisms = new LinkedList<AuthenticationMechanism>();
authenticationMechanisms.add(new CachedAuthenticatedSessionMechanism());
authenticationMechanisms.addAll(deploymentInfo.getAdditionalAuthenticationMechanisms());
if (loginConfig != null) {
mechName = loginConfig.getAuthMethod();
if (!deploymentInfo.isIgnoreStandardAuthenticationMechanism()) {
if (mechName != null) {
String[] mechanisms = mechName.split(",");
for (String mechanism : mechanisms) {
if (mechanism.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 (mechanism.equalsIgnoreCase("BASIC-SILENT")) {
//slient basic auth with use the basic headers if available, but will never challenge
//this allows programtic clients to use basic auth, and browsers to use other mechanisms
authenticationMechanisms.add(new BasicAuthenticationMechanism(loginConfig.getRealmName(), "BASIC-SILENT", true));
} else if (mechanism.equalsIgnoreCase(FORM_AUTH)) {
// The mechanism name is passed in from the HttpServletRequest interface as the name reported needs to be
// comparable using '=='
//we don't allow multipart requests, and always use the default encoding
FormParserFactory parser = FormParserFactory.builder(false)
.addParser(new FormEncodedDataDefinition().setDefaultEncoding(deploymentInfo.getDefaultEncoding()))
.build();
authenticationMechanisms.add(new ServletFormAuthenticationMechanism(parser, FORM_AUTH, loginConfig.getLoginPage(),
loginConfig.getErrorPage()));
} else if (mechanism.equalsIgnoreCase(CLIENT_CERT_AUTH)) {
authenticationMechanisms.add(new ClientCertAuthenticationMechanism());
} else if (mechanism.equalsIgnoreCase(DIGEST_AUTH)) {
authenticationMechanisms.add(new DigestAuthenticationMechanism(loginConfig.getRealmName(), deploymentInfo.getContextPath(), DIGEST_AUTH));
} else {
throw UndertowServletMessages.MESSAGES.unknownAuthenticationMechanism(mechanism);
}
}
}
}
}
current = new AuthenticationMechanismsHandler(current, authenticationMechanisms);
}
current = new CachedAuthenticatedSessionHandler(current, this.deployment.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.
current = new SecurityInitialHandler(AuthenticationMode.PRO_ACTIVE, deploymentInfo.getIdentityManager(), mechName, current);
return current;
}