io.undertow.servlet.api.DeploymentInfo Maven / Gradle / Ivy
/*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.undertow.servlet.api;
import java.io.File;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Executor;
import javax.servlet.DispatcherType;
import javax.servlet.MultipartConfigElement;
import javax.servlet.descriptor.JspConfigDescriptor;
import io.undertow.security.api.AuthenticationMechanism;
import io.undertow.security.api.AuthenticationMechanismFactory;
import io.undertow.security.api.AuthenticationMode;
import io.undertow.security.api.NotificationReceiver;
import io.undertow.security.api.SecurityContextFactory;
import io.undertow.security.idm.IdentityManager;
import io.undertow.server.HandlerWrapper;
import io.undertow.server.handlers.resource.ResourceManager;
import io.undertow.server.session.SecureRandomSessionIdGenerator;
import io.undertow.server.session.SessionIdGenerator;
import io.undertow.server.session.SessionListener;
import io.undertow.servlet.ServletExtension;
import io.undertow.servlet.UndertowServletMessages;
import io.undertow.servlet.core.DefaultAuthorizationManager;
import io.undertow.servlet.core.InMemorySessionManagerFactory;
import io.undertow.servlet.util.DefaultClassIntrospector;
import io.undertow.util.ImmediateAuthenticationMechanismFactory;
/**
* Represents a servlet deployment.
*
* @author Stuart Douglas
*/
public class DeploymentInfo implements Cloneable {
private String deploymentName;
private String displayName;
private String contextPath;
private ClassLoader classLoader;
private ResourceManager resourceManager = ResourceManager.EMPTY_RESOURCE_MANAGER;
private ClassIntrospecter classIntrospecter = DefaultClassIntrospector.INSTANCE;
private int majorVersion = 3;
private int minorVersion;
private Executor executor;
private Executor asyncExecutor;
private Path tempDir;
private JspConfigDescriptor jspConfigDescriptor;
private DefaultServletConfig defaultServletConfig;
private SessionManagerFactory sessionManagerFactory = new InMemorySessionManagerFactory();
private LoginConfig loginConfig;
private IdentityManager identityManager;
private ConfidentialPortManager confidentialPortManager;
private boolean allowNonStandardWrappers = false;
private int defaultSessionTimeout = 60 * 30;
private ConcurrentMap servletContextAttributeBackingMap;
private ServletSessionConfig servletSessionConfig;
private String hostName = "localhost";
private boolean denyUncoveredHttpMethods = false;
private ServletStackTraces servletStackTraces = ServletStackTraces.LOCAL_ONLY;
private boolean invalidateSessionOnLogout = false;
private int defaultCookieVersion = 0;
private SessionPersistenceManager sessionPersistenceManager;
private String defaultEncoding = "ISO-8859-1";
private String urlEncoding = null;
private boolean ignoreFlush = false;
private AuthorizationManager authorizationManager = DefaultAuthorizationManager.INSTANCE;
private AuthenticationMechanism jaspiAuthenticationMechanism;
private SecurityContextFactory securityContextFactory;
private String serverName = "Undertow";
private MetricsCollector metricsCollector = null;
private SessionConfigWrapper sessionConfigWrapper = null;
private boolean eagerFilterInit = false;
private boolean disableCachingForSecuredPages = true;
private boolean escapeErrorMessage = true;
private boolean sendCustomReasonPhraseOnError = false;
private AuthenticationMode authenticationMode = AuthenticationMode.PRO_ACTIVE;
private ExceptionHandler exceptionHandler;
private final Map servlets = new HashMap<>();
private final Map filters = new HashMap<>();
private final List filterServletNameMappings = new ArrayList<>();
private final List filterUrlMappings = new ArrayList<>();
private final List listeners = new ArrayList<>();
private final List servletContainerInitializers = new ArrayList<>();
private final List threadSetupActions = new ArrayList<>();
private final Map initParameters = new HashMap<>();
private final Map servletContextAttributes = new HashMap<>();
private final Map localeCharsetMapping = new HashMap<>();
private final List welcomePages = new ArrayList<>();
private final List errorPages = new ArrayList<>();
private final List mimeMappings = new ArrayList<>();
private final List securityConstraints = new ArrayList<>();
private final Set securityRoles = new HashSet<>();
private final List notificationReceivers = new ArrayList<>();
private final Map authenticationMechanisms = new HashMap<>();
private final List lifecycleInterceptors = new ArrayList<>();
private final List sessionListeners = new ArrayList<>();
/**
* additional servlet extensions
*/
private final List servletExtensions = new ArrayList<>();
/**
* map of additional roles that should be applied to the given principal.
*/
private final Map> principalVersusRolesMap = new HashMap<>();
/**
* Wrappers that are applied before the servlet initial handler, and before any servlet related object have been
* created. If a wrapper wants to bypass servlet entirely it should register itself here.
*/
private final List initialHandlerChainWrappers = new ArrayList<>();
/**
* Handler chain wrappers that are applied outside all other handlers, including security but after the initial
* servlet handler.
*/
private final List outerHandlerChainWrappers = new ArrayList<>();
/**
* Handler chain wrappers that are applied just before the servlet request is dispatched. At this point the security
* handlers have run, and any security information is attached to the request.
*/
private final List innerHandlerChainWrappers = new ArrayList<>();
/**
* Multipart config that will be applied to all servlets that do not have an explicit config
*/
private MultipartConfigElement defaultMultipartConfig;
/**
* Cache of common content types, to prevent allocations when parsing the charset
*/
private int contentTypeCacheSize = 100;
private SessionIdGenerator sessionIdGenerator = new SecureRandomSessionIdGenerator();
public void validate() {
if (deploymentName == null) {
throw UndertowServletMessages.MESSAGES.paramCannotBeNull("deploymentName");
}
if (contextPath == null) {
throw UndertowServletMessages.MESSAGES.paramCannotBeNull("contextName");
}
if (classLoader == null) {
throw UndertowServletMessages.MESSAGES.paramCannotBeNull("classLoader");
}
if (resourceManager == null) {
throw UndertowServletMessages.MESSAGES.paramCannotBeNull("resourceManager");
}
if (classIntrospecter == null) {
throw UndertowServletMessages.MESSAGES.paramCannotBeNull("classIntrospecter");
}
if (defaultEncoding == null) {
throw UndertowServletMessages.MESSAGES.paramCannotBeNull("defaultEncoding");
}
for (final ServletInfo servlet : this.servlets.values()) {
servlet.validate();
}
for (final FilterInfo filter : this.filters.values()) {
filter.validate();
}
for (FilterMappingInfo mapping : this.filterServletNameMappings) {
if (!this.filters.containsKey(mapping.getFilterName())) {
throw UndertowServletMessages.MESSAGES.filterNotFound(mapping.getFilterName(), mapping.getMappingType() + " - " + mapping.getMapping());
}
}
for (FilterMappingInfo mapping : this.filterUrlMappings) {
if (!this.filters.containsKey(mapping.getFilterName())) {
throw UndertowServletMessages.MESSAGES.filterNotFound(mapping.getFilterName(), mapping.getMappingType() + " - " + mapping.getMapping());
}
}
}
public String getDeploymentName() {
return deploymentName;
}
public DeploymentInfo setDeploymentName(final String deploymentName) {
this.deploymentName = deploymentName;
return this;
}
public String getDisplayName() {
return displayName;
}
public DeploymentInfo setDisplayName(final String displayName) {
this.displayName = displayName;
return this;
}
public String getContextPath() {
return contextPath;
}
public DeploymentInfo setContextPath(final String contextPath) {
if(contextPath != null && contextPath.isEmpty()) {
this.contextPath = "/"; //we represent the root context as / instead of "", but both work
} else {
this.contextPath = contextPath;
}
return this;
}
public ClassLoader getClassLoader() {
return classLoader;
}
public DeploymentInfo setClassLoader(final ClassLoader classLoader) {
this.classLoader = classLoader;
return this;
}
public ResourceManager getResourceManager() {
return resourceManager;
}
public DeploymentInfo setResourceManager(final ResourceManager resourceManager) {
this.resourceManager = resourceManager;
return this;
}
public ClassIntrospecter getClassIntrospecter() {
return classIntrospecter;
}
public DeploymentInfo setClassIntrospecter(final ClassIntrospecter classIntrospecter) {
this.classIntrospecter = classIntrospecter;
return this;
}
public boolean isAllowNonStandardWrappers() {
return allowNonStandardWrappers;
}
public DeploymentInfo setAllowNonStandardWrappers(final boolean allowNonStandardWrappers) {
this.allowNonStandardWrappers = allowNonStandardWrappers;
return this;
}
public int getDefaultSessionTimeout() {
return defaultSessionTimeout;
}
/**
* @param defaultSessionTimeout The default session timeout, in seconds
*/
public DeploymentInfo setDefaultSessionTimeout(final int defaultSessionTimeout) {
this.defaultSessionTimeout = defaultSessionTimeout;
return this;
}
public String getDefaultEncoding() {
return defaultEncoding;
}
/**
* Sets the default encoding that will be used for servlet responses
*
* @param defaultEncoding The default encoding
*/
public DeploymentInfo setDefaultEncoding(String defaultEncoding) {
this.defaultEncoding = defaultEncoding;
return this;
}
public String getUrlEncoding() {
return urlEncoding;
}
/**
* Sets the URL encoding. This will only take effect if the {@link io.undertow.UndertowOptions#DECODE_URL}
* parameter has been set to false. This allows multiple deployments in the same server to use a different URL encoding
*
* @param urlEncoding The encoding to use
*/
public DeploymentInfo setUrlEncoding(String urlEncoding) {
this.urlEncoding = urlEncoding;
return this;
}
public DeploymentInfo addServlet(final ServletInfo servlet) {
servlets.put(servlet.getName(), servlet);
return this;
}
public DeploymentInfo addServlets(final ServletInfo... servlets) {
for (final ServletInfo servlet : servlets) {
addServlet(servlet);
}
return this;
}
public DeploymentInfo addServlets(final Collection servlets) {
for (final ServletInfo servlet : servlets) {
addServlet(servlet);
}
return this;
}
public Map getServlets() {
return Collections.unmodifiableMap(servlets);
}
public DeploymentInfo addFilter(final FilterInfo filter) {
filters.put(filter.getName(), filter);
return this;
}
public DeploymentInfo addFilters(final FilterInfo... filters) {
for (final FilterInfo filter : filters) {
addFilter(filter);
}
return this;
}
public DeploymentInfo addFilters(final Collection filters) {
for (final FilterInfo filter : filters) {
addFilter(filter);
}
return this;
}
public Map getFilters() {
return Collections.unmodifiableMap(filters);
}
public DeploymentInfo addFilterUrlMapping(final String filterName, final String mapping, DispatcherType dispatcher) {
filterUrlMappings.add(new FilterMappingInfo(filterName, FilterMappingInfo.MappingType.URL, mapping, dispatcher));
return this;
}
public DeploymentInfo addFilterServletNameMapping(final String filterName, final String mapping, DispatcherType dispatcher) {
filterServletNameMappings.add(new FilterMappingInfo(filterName, FilterMappingInfo.MappingType.SERVLET, mapping, dispatcher));
return this;
}
public DeploymentInfo insertFilterUrlMapping(final int pos, final String filterName, final String mapping, DispatcherType dispatcher) {
filterUrlMappings.add(pos, new FilterMappingInfo(filterName, FilterMappingInfo.MappingType.URL, mapping, dispatcher));
return this;
}
public DeploymentInfo insertFilterServletNameMapping(final int pos, final String filterName, final String mapping, DispatcherType dispatcher) {
filterServletNameMappings.add(pos, new FilterMappingInfo(filterName, FilterMappingInfo.MappingType.SERVLET, mapping, dispatcher));
return this;
}
public List getFilterMappings() {
final ArrayList ret = new ArrayList<>(filterUrlMappings);
ret.addAll(filterServletNameMappings);
return Collections.unmodifiableList(ret);
}
public DeploymentInfo addListener(final ListenerInfo listener) {
listeners.add(listener);
return this;
}
public DeploymentInfo addListeners(final ListenerInfo... listeners) {
this.listeners.addAll(Arrays.asList(listeners));
return this;
}
public DeploymentInfo addListeners(final Collection listeners) {
this.listeners.addAll(listeners);
return this;
}
public List getListeners() {
return listeners;
}
public int getMajorVersion() {
return majorVersion;
}
public DeploymentInfo setMajorVersion(final int majorVersion) {
this.majorVersion = majorVersion;
return this;
}
public int getMinorVersion() {
return minorVersion;
}
public DeploymentInfo setMinorVersion(final int minorVersion) {
this.minorVersion = minorVersion;
return this;
}
public DeploymentInfo addServletContainerInitalizer(final ServletContainerInitializerInfo servletContainerInitializer) {
servletContainerInitializers.add(servletContainerInitializer);
return this;
}
public DeploymentInfo addServletContainerInitalizers(final ServletContainerInitializerInfo... servletContainerInitializer) {
servletContainerInitializers.addAll(Arrays.asList(servletContainerInitializer));
return this;
}
public DeploymentInfo addServletContainerInitalizers(final List servletContainerInitializer) {
servletContainerInitializers.addAll(servletContainerInitializer);
return this;
}
public List getServletContainerInitializers() {
return servletContainerInitializers;
}
public DeploymentInfo addThreadSetupAction(final ThreadSetupAction action) {
threadSetupActions.add(action);
return this;
}
public List getThreadSetupActions() {
return threadSetupActions;
}
public boolean isEagerFilterInit() {
return eagerFilterInit;
}
public DeploymentInfo setEagerFilterInit(boolean eagerFilterInit) {
this.eagerFilterInit = eagerFilterInit;
return this;
}
public DeploymentInfo addInitParameter(final String name, final String value) {
initParameters.put(name, value);
return this;
}
public Map getInitParameters() {
return Collections.unmodifiableMap(initParameters);
}
public DeploymentInfo addServletContextAttribute(final String name, final Object value) {
servletContextAttributes.put(name, value);
return this;
}
public Map getServletContextAttributes() {
return Collections.unmodifiableMap(servletContextAttributes);
}
public DeploymentInfo addWelcomePage(final String welcomePage) {
this.welcomePages.add(welcomePage);
return this;
}
public DeploymentInfo addWelcomePages(final String... welcomePages) {
this.welcomePages.addAll(Arrays.asList(welcomePages));
return this;
}
public DeploymentInfo addWelcomePages(final Collection welcomePages) {
this.welcomePages.addAll(welcomePages);
return this;
}
public List getWelcomePages() {
return Collections.unmodifiableList(welcomePages);
}
public DeploymentInfo addErrorPage(final ErrorPage errorPage) {
this.errorPages.add(errorPage);
return this;
}
public DeploymentInfo addErrorPages(final ErrorPage... errorPages) {
this.errorPages.addAll(Arrays.asList(errorPages));
return this;
}
public DeploymentInfo addErrorPages(final Collection errorPages) {
this.errorPages.addAll(errorPages);
return this;
}
public List getErrorPages() {
return Collections.unmodifiableList(errorPages);
}
public DeploymentInfo addMimeMapping(final MimeMapping mimeMappings) {
this.mimeMappings.add(mimeMappings);
return this;
}
public DeploymentInfo addMimeMappings(final MimeMapping... mimeMappings) {
this.mimeMappings.addAll(Arrays.asList(mimeMappings));
return this;
}
public DeploymentInfo addMimeMappings(final Collection mimeMappings) {
this.mimeMappings.addAll(mimeMappings);
return this;
}
public List getMimeMappings() {
return Collections.unmodifiableList(mimeMappings);
}
public DeploymentInfo addSecurityConstraint(final SecurityConstraint securityConstraint) {
this.securityConstraints.add(securityConstraint);
return this;
}
public DeploymentInfo addSecurityConstraints(final SecurityConstraint... securityConstraints) {
this.securityConstraints.addAll(Arrays.asList(securityConstraints));
return this;
}
public DeploymentInfo addSecurityConstraints(final Collection securityConstraints) {
this.securityConstraints.addAll(securityConstraints);
return this;
}
public List getSecurityConstraints() {
return Collections.unmodifiableList(securityConstraints);
}
public Executor getExecutor() {
return executor;
}
/**
* Sets the executor that will be used to run servlet invocations. If this is null then the XNIO worker pool will be
* used.
*
* Individual servlets may use a different executor
*
* If this is null then the current executor is used, which is generally the XNIO worker pool
*
* @param executor The executor
* @see ServletInfo#executor
*/
public DeploymentInfo setExecutor(final Executor executor) {
this.executor = executor;
return this;
}
public Executor getAsyncExecutor() {
return asyncExecutor;
}
/**
* Sets the executor that is used to run async tasks.
*
* If this is null then {@link #executor} is used, if this is also null then the default is used
*
* @param asyncExecutor The executor
*/
public DeploymentInfo setAsyncExecutor(final Executor asyncExecutor) {
this.asyncExecutor = asyncExecutor;
return this;
}
public File getTempDir() {
if(tempDir == null) {
return null;
}
return tempDir.toFile();
}
public Path getTempPath() {
return tempDir;
}
public DeploymentInfo setTempDir(final File tempDir) {
this.tempDir = tempDir != null ? tempDir.toPath() : null;
return this;
}
public DeploymentInfo setTempDir(final Path tempDir) {
this.tempDir = tempDir;
return this;
}
public boolean isIgnoreFlush() {
return ignoreFlush;
}
public DeploymentInfo setIgnoreFlush(boolean ignoreFlush) {
this.ignoreFlush = ignoreFlush;
return this;
}
public JspConfigDescriptor getJspConfigDescriptor() {
return jspConfigDescriptor;
}
public DeploymentInfo setJspConfigDescriptor(JspConfigDescriptor jspConfigDescriptor) {
this.jspConfigDescriptor = jspConfigDescriptor;
return this;
}
public DefaultServletConfig getDefaultServletConfig() {
return defaultServletConfig;
}
public DeploymentInfo setDefaultServletConfig(final DefaultServletConfig defaultServletConfig) {
this.defaultServletConfig = defaultServletConfig;
return this;
}
public DeploymentInfo addLocaleCharsetMapping(final String locale, final String charset) {
localeCharsetMapping.put(locale, charset);
return this;
}
public Map getLocaleCharsetMapping() {
return localeCharsetMapping;
}
public SessionManagerFactory getSessionManagerFactory() {
return sessionManagerFactory;
}
public DeploymentInfo setSessionManagerFactory(final SessionManagerFactory sessionManagerFactory) {
this.sessionManagerFactory = sessionManagerFactory;
return this;
}
public LoginConfig getLoginConfig() {
return loginConfig;
}
public DeploymentInfo setLoginConfig(LoginConfig loginConfig) {
this.loginConfig = loginConfig;
return this;
}
public IdentityManager getIdentityManager() {
return identityManager;
}
public DeploymentInfo setIdentityManager(IdentityManager identityManager) {
this.identityManager = identityManager;
return this;
}
public ConfidentialPortManager getConfidentialPortManager() {
return confidentialPortManager;
}
public DeploymentInfo setConfidentialPortManager(ConfidentialPortManager confidentialPortManager) {
this.confidentialPortManager = confidentialPortManager;
return this;
}
public DeploymentInfo addSecurityRole(final String role) {
this.securityRoles.add(role);
return this;
}
public DeploymentInfo addSecurityRoles(final String... roles) {
this.securityRoles.addAll(Arrays.asList(roles));
return this;
}
public DeploymentInfo addSecurityRoles(final Collection roles) {
this.securityRoles.addAll(roles);
return this;
}
public Set getSecurityRoles() {
return Collections.unmodifiableSet(securityRoles);
}
/**
* Adds an outer handler wrapper. This handler will be run after the servlet initial handler,
* but before any other handlers. These are only run on REQUEST invocations, they
* are not invoked on a FORWARD or INCLUDE.
*
* @param wrapper The wrapper
*/
public DeploymentInfo addOuterHandlerChainWrapper(final HandlerWrapper wrapper) {
outerHandlerChainWrappers.add(wrapper);
return this;
}
public List getOuterHandlerChainWrappers() {
return Collections.unmodifiableList(outerHandlerChainWrappers);
}
/**
* Adds an inner handler chain wrapper. This handler will be run after the security handler,
* but before any other servlet handlers, and will be run for every request
*
* @param wrapper The wrapper
*/
public DeploymentInfo addInnerHandlerChainWrapper(final HandlerWrapper wrapper) {
innerHandlerChainWrappers.add(wrapper);
return this;
}
public List getInnerHandlerChainWrappers() {
return Collections.unmodifiableList(innerHandlerChainWrappers);
}
public DeploymentInfo addInitialHandlerChainWrapper(final HandlerWrapper wrapper) {
initialHandlerChainWrappers.add(wrapper);
return this;
}
public List getInitialHandlerChainWrappers() {
return Collections.unmodifiableList(initialHandlerChainWrappers);
}
public DeploymentInfo addNotificationReceiver(final NotificationReceiver notificationReceiver) {
this.notificationReceivers.add(notificationReceiver);
return this;
}
public DeploymentInfo addNotificactionReceivers(final NotificationReceiver... notificationReceivers) {
this.notificationReceivers.addAll(Arrays.asList(notificationReceivers));
return this;
}
public DeploymentInfo addNotificationReceivers(final Collection notificationReceivers) {
this.notificationReceivers.addAll(notificationReceivers);
return this;
}
public List getNotificationReceivers() {
return Collections.unmodifiableList(notificationReceivers);
}
public ConcurrentMap getServletContextAttributeBackingMap() {
return servletContextAttributeBackingMap;
}
/**
* Sets the map that will be used by the ServletContext implementation to store attributes.
*
* This should usuablly be null, in which case Undertow will create a new map. This is only
* used in situations where you want multiple deployments to share the same servlet context
* attributes.
*
* @param servletContextAttributeBackingMap
* The backing map
*/
public DeploymentInfo setServletContextAttributeBackingMap(final ConcurrentMap servletContextAttributeBackingMap) {
this.servletContextAttributeBackingMap = servletContextAttributeBackingMap;
return this;
}
public ServletSessionConfig getServletSessionConfig() {
return servletSessionConfig;
}
public DeploymentInfo setServletSessionConfig(final ServletSessionConfig servletSessionConfig) {
this.servletSessionConfig = servletSessionConfig;
return this;
}
/**
* @return the host name
*/
public String getHostName() {
return hostName;
}
public DeploymentInfo setHostName(final String hostName) {
this.hostName = hostName;
return this;
}
public boolean isDenyUncoveredHttpMethods() {
return denyUncoveredHttpMethods;
}
public DeploymentInfo setDenyUncoveredHttpMethods(final boolean denyUncoveredHttpMethods) {
this.denyUncoveredHttpMethods = denyUncoveredHttpMethods;
return this;
}
public ServletStackTraces getServletStackTraces() {
return servletStackTraces;
}
public DeploymentInfo setServletStackTraces(ServletStackTraces servletStackTraces) {
this.servletStackTraces = servletStackTraces;
return this;
}
public boolean isInvalidateSessionOnLogout() {
return invalidateSessionOnLogout;
}
public DeploymentInfo setInvalidateSessionOnLogout(boolean invalidateSessionOnLogout) {
this.invalidateSessionOnLogout = invalidateSessionOnLogout;
return this;
}
public int getDefaultCookieVersion() {
return defaultCookieVersion;
}
public DeploymentInfo setDefaultCookieVersion(int defaultCookieVersion) {
this.defaultCookieVersion = defaultCookieVersion;
return this;
}
public SessionPersistenceManager getSessionPersistenceManager() {
return sessionPersistenceManager;
}
public DeploymentInfo setSessionPersistenceManager(SessionPersistenceManager sessionPersistenceManager) {
this.sessionPersistenceManager = sessionPersistenceManager;
return this;
}
public AuthorizationManager getAuthorizationManager() {
return authorizationManager;
}
public DeploymentInfo setAuthorizationManager(AuthorizationManager authorizationManager) {
this.authorizationManager = authorizationManager;
return this;
}
public DeploymentInfo addPrincipalVsRoleMapping(final String principal, final String mapping) {
Set set = principalVersusRolesMap.get(principal);
if (set == null) {
principalVersusRolesMap.put(principal, set = new HashSet<>());
}
set.add(mapping);
return this;
}
public DeploymentInfo addPrincipalVsRoleMappings(final String principal, final String... mappings) {
Set set = principalVersusRolesMap.get(principal);
if (set == null) {
principalVersusRolesMap.put(principal, set = new HashSet<>());
}
set.addAll(Arrays.asList(mappings));
return this;
}
public DeploymentInfo addPrincipalVsRoleMappings(final String principal, final Collection mappings) {
Set set = principalVersusRolesMap.get(principal);
if (set == null) {
principalVersusRolesMap.put(principal, set = new HashSet<>());
}
set.addAll(mappings);
return this;
}
public Map> getPrincipalVersusRolesMap() {
return Collections.unmodifiableMap(principalVersusRolesMap);
}
/**
* Removes all configured authentication mechanisms from the deployment.
*
* @return this deployment info
*/
public DeploymentInfo clearLoginMethods() {
if(loginConfig != null) {
loginConfig.getAuthMethods().clear();
}
return this;
}
/**
* Adds an authentication mechanism directly to the deployment. This mechanism will be first in the list.
*
* In general you should just use {@link #addAuthenticationMechanism(String, io.undertow.security.api.AuthenticationMechanismFactory)}
* and allow the user to configure the methods they want by name.
*
* This method is essentially a convenience method, if is the same as registering a factory under the provided name that returns
* and authentication mechanism, and then adding it to the login config list.
*
* If you want your mechanism to be the only one in the deployment you should first invoke {@link #clearLoginMethods()}.
*
* @param name The authentication mechanism name
* @param mechanism The mechanism
* @return this deployment info
*/
public DeploymentInfo addFirstAuthenticationMechanism(final String name, final AuthenticationMechanism mechanism) {
authenticationMechanisms.put(name, new ImmediateAuthenticationMechanismFactory(mechanism));
if(loginConfig == null) {
loginConfig = new LoginConfig(null);
}
loginConfig.addFirstAuthMethod(new AuthMethodConfig(name));
return this;
}
/**
* Adds an authentication mechanism directly to the deployment. This mechanism will be last in the list.
*
* In general you should just use {@link #addAuthenticationMechanism(String, io.undertow.security.api.AuthenticationMechanismFactory)}
* and allow the user to configure the methods they want by name.
*
* This method is essentially a convenience method, if is the same as registering a factory under the provided name that returns
* and authentication mechanism, and then adding it to the login config list.
*
* If you want your mechanism to be the only one in the deployment you should first invoke {@link #clearLoginMethods()}.
*
* @param name The authentication mechanism name
* @param mechanism The mechanism
* @return
*/
public DeploymentInfo addLastAuthenticationMechanism(final String name, final AuthenticationMechanism mechanism) {
authenticationMechanisms.put(name, new ImmediateAuthenticationMechanismFactory(mechanism));
if(loginConfig == null) {
loginConfig = new LoginConfig(null);
}
loginConfig.addLastAuthMethod(new AuthMethodConfig(name));
return this;
}
/**
* Adds an authentication mechanism. The name is case insenstive, and will be converted to uppercase internally.
*
* @param name The name
* @param factory The factory
* @return
*/
public DeploymentInfo addAuthenticationMechanism(final String name, final AuthenticationMechanismFactory factory) {
authenticationMechanisms.put(name.toUpperCase(Locale.US), factory);
return this;
}
public Map getAuthenticationMechanisms() {
return Collections.unmodifiableMap(authenticationMechanisms);
}
/**
* Returns true if the specified mechanism is present in the login config
* @param mechanismName The mechanism name
* @return true if the mechanism is enabled
*/
public boolean isAuthenticationMechanismPresent(final String mechanismName) {
if(loginConfig != null) {
for(AuthMethodConfig method : loginConfig.getAuthMethods()) {
if(method.getName().equalsIgnoreCase(mechanismName)) {
return true;
}
}
}
return false;
}
/**
* Adds an additional servlet extension to the deployment. Servlet extensions are generally discovered
* using META-INF/services entries, however this may not be practical in all environments.
* @param servletExtension The servlet extension
* @return this
*/
public DeploymentInfo addServletExtension(final ServletExtension servletExtension) {
this.servletExtensions.add(servletExtension);
return this;
}
public List getServletExtensions() {
return servletExtensions;
}
public AuthenticationMechanism getJaspiAuthenticationMechanism() {
return jaspiAuthenticationMechanism;
}
public void setJaspiAuthenticationMechanism(AuthenticationMechanism jaspiAuthenticationMechanism) {
this.jaspiAuthenticationMechanism = jaspiAuthenticationMechanism;
}
public SecurityContextFactory getSecurityContextFactory() {
return this.securityContextFactory;
}
public void setSecurityContextFactory(final SecurityContextFactory securityContextFactory) {
this.securityContextFactory = securityContextFactory;
}
public String getServerName() {
return serverName;
}
public DeploymentInfo setServerName(String serverName) {
this.serverName = serverName;
return this;
}
public DeploymentInfo setMetricsCollector(MetricsCollector metricsCollector){
this.metricsCollector = metricsCollector;
return this;
}
public MetricsCollector getMetricsCollector() {
return metricsCollector;
}
public SessionConfigWrapper getSessionConfigWrapper() {
return sessionConfigWrapper;
}
public DeploymentInfo setSessionConfigWrapper(SessionConfigWrapper sessionConfigWrapper) {
this.sessionConfigWrapper = sessionConfigWrapper;
return this;
}
public boolean isDisableCachingForSecuredPages() {
return disableCachingForSecuredPages;
}
public void setDisableCachingForSecuredPages(boolean disableCachingForSecuredPages) {
this.disableCachingForSecuredPages = disableCachingForSecuredPages;
}
public DeploymentInfo addLifecycleInterceptor(final LifecycleInterceptor interceptor) {
lifecycleInterceptors.add(interceptor);
return this;
}
public List getLifecycleInterceptors() {
return Collections.unmodifiableList(lifecycleInterceptors);
}
/**
* Returns the exception handler that is used by this deployment. By default this will simply
* log unhandled exceptions
*/
public ExceptionHandler getExceptionHandler() {
return exceptionHandler;
}
/**
* Sets the default exception handler for this deployment
* @param exceptionHandler The exception handler
* @return
*/
public DeploymentInfo setExceptionHandler(ExceptionHandler exceptionHandler) {
this.exceptionHandler = exceptionHandler;
return this;
}
public boolean isEscapeErrorMessage() {
return escapeErrorMessage;
}
/**
* Set if if the message passed to {@link javax.servlet.http.HttpServletResponse#sendError(int, String)} should be escaped.
*
* If this is false applications must be careful not to use user provided data (such as the URI) in the message
*
* @param escapeErrorMessage If the error message should be escaped
*/
public void setEscapeErrorMessage(boolean escapeErrorMessage) {
this.escapeErrorMessage = escapeErrorMessage;
}
public DeploymentInfo addSessionListener(SessionListener sessionListener) {
this.sessionListeners.add(sessionListener);
return this;
}
public List getSessionListeners() {
return Collections.unmodifiableList(sessionListeners);
}
public AuthenticationMode getAuthenticationMode() {
return authenticationMode;
}
/**
* Sets if this deployment should use pro-active authentication and always authenticate if the credentials are present
* or constraint driven auth which will only call the authentication mechanisms for protected resources.
*
* Pro active auth means that requests for unprotected resources will still be associated with a user, which may be
* useful for access logging.
*
*
* @param authenticationMode The authentication mode to use
* @return
*/
public DeploymentInfo setAuthenticationMode(AuthenticationMode authenticationMode) {
this.authenticationMode = authenticationMode;
return this;
}
public MultipartConfigElement getDefaultMultipartConfig() {
return defaultMultipartConfig;
}
public void setDefaultMultipartConfig(MultipartConfigElement defaultMultipartConfig) {
this.defaultMultipartConfig = defaultMultipartConfig;
}
public int getContentTypeCacheSize() {
return contentTypeCacheSize;
}
public void setContentTypeCacheSize(int contentTypeCacheSize) {
this.contentTypeCacheSize = contentTypeCacheSize;
}
public SessionIdGenerator getSessionIdGenerator() {
return sessionIdGenerator;
}
public void setSessionIdGenerator(SessionIdGenerator sessionIdGenerator) {
this.sessionIdGenerator = sessionIdGenerator;
}
public boolean isSendCustomReasonPhraseOnError() {
return sendCustomReasonPhraseOnError;
}
/**
* If this is true then the message parameter of {@link javax.servlet.http.HttpServletResponse#sendError(int, String)} and
* {@link javax.servlet.http.HttpServletResponse#setStatus(int, String)} will be used as the HTTP reason phrase in
* the response.
*
* @param sendCustomReasonPhraseOnError If the parameter to sendError should be used as a HTTP reason phrase
* @return this
*/
public DeploymentInfo setSendCustomReasonPhraseOnError(boolean sendCustomReasonPhraseOnError) {
this.sendCustomReasonPhraseOnError = sendCustomReasonPhraseOnError;
return this;
}
@Override
public DeploymentInfo clone() {
final DeploymentInfo info = new DeploymentInfo()
.setClassLoader(classLoader)
.setContextPath(contextPath)
.setResourceManager(resourceManager)
.setMajorVersion(majorVersion)
.setMinorVersion(minorVersion)
.setDeploymentName(deploymentName)
.setClassIntrospecter(classIntrospecter);
for (Map.Entry e : servlets.entrySet()) {
info.addServlet(e.getValue().clone());
}
for (Map.Entry e : filters.entrySet()) {
info.addFilter(e.getValue().clone());
}
info.displayName = displayName;
info.filterUrlMappings.addAll(filterUrlMappings);
info.filterServletNameMappings.addAll(filterServletNameMappings);
info.listeners.addAll(listeners);
info.servletContainerInitializers.addAll(servletContainerInitializers);
info.threadSetupActions.addAll(threadSetupActions);
info.initParameters.putAll(initParameters);
info.servletContextAttributes.putAll(servletContextAttributes);
info.welcomePages.addAll(welcomePages);
info.errorPages.addAll(errorPages);
info.mimeMappings.addAll(mimeMappings);
info.executor = executor;
info.asyncExecutor = asyncExecutor;
info.tempDir = tempDir;
info.jspConfigDescriptor = jspConfigDescriptor;
info.defaultServletConfig = defaultServletConfig;
info.localeCharsetMapping.putAll(localeCharsetMapping);
info.sessionManagerFactory = sessionManagerFactory;
if (loginConfig != null) {
info.loginConfig = loginConfig.clone();
}
info.identityManager = identityManager;
info.confidentialPortManager = confidentialPortManager;
info.defaultEncoding = defaultEncoding;
info.urlEncoding = urlEncoding;
info.securityConstraints.addAll(securityConstraints);
info.outerHandlerChainWrappers.addAll(outerHandlerChainWrappers);
info.innerHandlerChainWrappers.addAll(innerHandlerChainWrappers);
info.initialHandlerChainWrappers.addAll(initialHandlerChainWrappers);
info.securityRoles.addAll(securityRoles);
info.notificationReceivers.addAll(notificationReceivers);
info.allowNonStandardWrappers = allowNonStandardWrappers;
info.defaultSessionTimeout = defaultSessionTimeout;
info.servletContextAttributeBackingMap = servletContextAttributeBackingMap;
info.servletSessionConfig = servletSessionConfig;
info.hostName = hostName;
info.denyUncoveredHttpMethods = denyUncoveredHttpMethods;
info.servletStackTraces = servletStackTraces;
info.invalidateSessionOnLogout = invalidateSessionOnLogout;
info.defaultCookieVersion = defaultCookieVersion;
info.sessionPersistenceManager = sessionPersistenceManager;
info.principalVersusRolesMap.putAll(principalVersusRolesMap);
info.ignoreFlush = ignoreFlush;
info.authorizationManager = authorizationManager;
info.authenticationMechanisms.putAll(authenticationMechanisms);
info.servletExtensions.addAll(servletExtensions);
info.jaspiAuthenticationMechanism = jaspiAuthenticationMechanism;
info.securityContextFactory = securityContextFactory;
info.serverName = serverName;
info.metricsCollector = metricsCollector;
info.sessionConfigWrapper = sessionConfigWrapper;
info.eagerFilterInit = eagerFilterInit;
info.disableCachingForSecuredPages = disableCachingForSecuredPages;
info.exceptionHandler = exceptionHandler;
info.escapeErrorMessage = escapeErrorMessage;
info.sessionListeners.addAll(sessionListeners);
info.lifecycleInterceptors.addAll(lifecycleInterceptors);
info.authenticationMode = authenticationMode;
info.defaultMultipartConfig = defaultMultipartConfig;
info.contentTypeCacheSize = contentTypeCacheSize;
info.sessionIdGenerator = sessionIdGenerator;
info.sendCustomReasonPhraseOnError = sendCustomReasonPhraseOnError;
return info;
}
}