Polish spring-security-config main code

Manually polish `spring-security-config` following the formatting
and checkstyle fixes.

Issue gh-8945
This commit is contained in:
Phillip Webb 2020-07-30 14:04:38 -07:00 committed by Rob Winch
parent 4e5aa6c9d3
commit 7bf6008efe
106 changed files with 770 additions and 1846 deletions

View File

@ -35,7 +35,9 @@ public abstract class BeanIds {
*/
public static final String AUTHENTICATION_MANAGER = PREFIX + "authenticationManager";
/** External alias for FilterChainProxy bean, for use in web.xml files */
/**
* External alias for FilterChainProxy bean, for use in web.xml files
*/
public static final String SPRING_SECURITY_FILTER_CHAIN = "springSecurityFilterChain";
public static final String CONTEXT_SOURCE_SETTING_POST_PROCESSOR = PREFIX + "contextSettingPostProcessor";

View File

@ -33,7 +33,6 @@ public class DebugBeanDefinitionParser implements BeanDefinitionParser {
public BeanDefinition parse(Element element, ParserContext parserContext) {
RootBeanDefinition debugPP = new RootBeanDefinition(SecurityDebugBeanFactoryPostProcessor.class);
parserContext.getReaderContext().registerWithGeneratedName(debugPP);
return null;
}

View File

@ -75,17 +75,13 @@ public final class SecurityNamespaceHandler implements NamespaceHandler {
public SecurityNamespaceHandler() {
String coreVersion = SpringSecurityCoreVersion.getVersion();
Package pkg = SpringSecurityCoreVersion.class.getPackage();
if (pkg == null || coreVersion == null) {
this.logger.info("Couldn't determine package version information.");
return;
}
String version = pkg.getImplementationVersion();
this.logger.info("Spring Security 'config' module version is " + version);
if (version.compareTo(coreVersion) != 0) {
this.logger.error(
"You are running with different versions of the Spring Security 'core' and 'config' modules");
@ -95,44 +91,37 @@ public final class SecurityNamespaceHandler implements NamespaceHandler {
@Override
public BeanDefinition parse(Element element, ParserContext pc) {
if (!namespaceMatchesVersion(element)) {
pc.getReaderContext().fatal(
"You cannot use a spring-security-2.0.xsd or spring-security-3.0.xsd or spring-security-3.1.xsd schema or spring-security-3.2.xsd schema or spring-security-4.0.xsd schema "
+ "with Spring Security 5.4. Please update your schema declarations to the 5.4 schema.",
element);
pc.getReaderContext().fatal("You cannot use a spring-security-2.0.xsd or spring-security-3.0.xsd or "
+ "spring-security-3.1.xsd schema or spring-security-3.2.xsd schema or spring-security-4.0.xsd schema "
+ "with Spring Security 5.4. Please update your schema declarations to the 5.4 schema.", element);
}
String name = pc.getDelegate().getLocalName(element);
BeanDefinitionParser parser = this.parsers.get(name);
if (parser == null) {
// SEC-1455. Load parsers when required, not just on init().
loadParsers();
}
if (parser == null) {
if (Elements.HTTP.equals(name) || Elements.FILTER_SECURITY_METADATA_SOURCE.equals(name)
|| Elements.FILTER_CHAIN_MAP.equals(name) || Elements.FILTER_CHAIN.equals(name)) {
reportMissingWebClasses(name, pc, element);
}
else {
reportUnsupportedNodeType(name, pc, element);
}
return null;
if (parser != null) {
return parser.parse(element, pc);
}
return parser.parse(element, pc);
if (Elements.HTTP.equals(name) || Elements.FILTER_SECURITY_METADATA_SOURCE.equals(name)
|| Elements.FILTER_CHAIN_MAP.equals(name) || Elements.FILTER_CHAIN.equals(name)) {
reportMissingWebClasses(name, pc, element);
}
else {
reportUnsupportedNodeType(name, pc, element);
}
return null;
}
@Override
public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext pc) {
String name = pc.getDelegate().getLocalName(node);
// We only handle elements
if (node instanceof Element) {
// We only handle elements
if (Elements.INTERCEPT_METHODS.equals(name)) {
return this.interceptMethodsBDD.decorate(node, definition, pc);
}
if (Elements.FILTER_CHAIN_MAP.equals(name)) {
if (this.filterChainMapBDD == null) {
loadParsers();
@ -143,9 +132,7 @@ public final class SecurityNamespaceHandler implements NamespaceHandler {
return this.filterChainMapBDD.decorate(node, definition, pc);
}
}
reportUnsupportedNodeType(name, pc, node);
return null;
}
@ -162,9 +149,9 @@ public final class SecurityNamespaceHandler implements NamespaceHandler {
// no details available
pc.getReaderContext().fatal(errorMessage, node);
}
catch (Throwable cause) {
catch (Throwable ex) {
// provide details on why it could not be loaded
pc.getReaderContext().fatal(errorMessage, node, cause);
pc.getReaderContext().fatal(errorMessage, node, ex);
}
}
@ -185,25 +172,28 @@ public final class SecurityNamespaceHandler implements NamespaceHandler {
this.parsers.put(Elements.AUTHENTICATION_MANAGER, new AuthenticationManagerBeanDefinitionParser());
this.parsers.put(Elements.METHOD_SECURITY_METADATA_SOURCE,
new MethodSecurityMetadataSourceBeanDefinitionParser());
// Only load the web-namespace parsers if the web classes are available
if (ClassUtils.isPresent(FILTER_CHAIN_PROXY_CLASSNAME, getClass().getClassLoader())) {
this.parsers.put(Elements.DEBUG, new DebugBeanDefinitionParser());
this.parsers.put(Elements.HTTP, new HttpSecurityBeanDefinitionParser());
this.parsers.put(Elements.HTTP_FIREWALL, new HttpFirewallBeanDefinitionParser());
this.parsers.put(Elements.FILTER_SECURITY_METADATA_SOURCE,
new FilterInvocationSecurityMetadataSourceParser());
this.parsers.put(Elements.FILTER_CHAIN, new FilterChainBeanDefinitionParser());
this.filterChainMapBDD = new FilterChainMapBeanDefinitionDecorator();
this.parsers.put(Elements.CLIENT_REGISTRATIONS, new ClientRegistrationsBeanDefinitionParser());
loadWebParsers();
}
if (ClassUtils.isPresent(MESSAGE_CLASSNAME, getClass().getClassLoader())) {
this.parsers.put(Elements.WEBSOCKET_MESSAGE_BROKER,
new WebSocketMessageBrokerSecurityBeanDefinitionParser());
loadWebSocketParsers();
}
}
private void loadWebParsers() {
this.parsers.put(Elements.DEBUG, new DebugBeanDefinitionParser());
this.parsers.put(Elements.HTTP, new HttpSecurityBeanDefinitionParser());
this.parsers.put(Elements.HTTP_FIREWALL, new HttpFirewallBeanDefinitionParser());
this.parsers.put(Elements.FILTER_SECURITY_METADATA_SOURCE, new FilterInvocationSecurityMetadataSourceParser());
this.parsers.put(Elements.FILTER_CHAIN, new FilterChainBeanDefinitionParser());
this.filterChainMapBDD = new FilterChainMapBeanDefinitionDecorator();
this.parsers.put(Elements.CLIENT_REGISTRATIONS, new ClientRegistrationsBeanDefinitionParser());
}
private void loadWebSocketParsers() {
this.parsers.put(Elements.WEBSOCKET_MESSAGE_BROKER, new WebSocketMessageBrokerSecurityBeanDefinitionParser());
}
/**
* Check that the schema location declared in the source file being parsed matches the
* Spring Security version. The old 2.0 schema is not compatible with the 3.1 parser,

View File

@ -99,18 +99,16 @@ public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBui
* while building, returns null.
*/
public O getOrBuild() {
if (isUnbuilt()) {
try {
return build();
}
catch (Exception ex) {
this.logger.debug("Failed to perform build. Returning null", ex);
return null;
}
}
else {
if (!isUnbuilt()) {
return getObject();
}
try {
return build();
}
catch (Exception ex) {
this.logger.debug("Failed to perform build. Returning null", ex);
return null;
}
}
/**
@ -177,18 +175,17 @@ public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBui
@SuppressWarnings("unchecked")
private <C extends SecurityConfigurer<O, B>> void add(C configurer) {
Assert.notNull(configurer, "configurer cannot be null");
Class<? extends SecurityConfigurer<O, B>> clazz = (Class<? extends SecurityConfigurer<O, B>>) configurer
.getClass();
synchronized (this.configurers) {
if (this.buildState.isConfigured()) {
throw new IllegalStateException("Cannot apply " + configurer + " to already built object");
}
List<SecurityConfigurer<O, B>> configs = this.allowConfigurersOfSameType ? this.configurers.get(clazz)
: null;
if (configs == null) {
configs = new ArrayList<>(1);
List<SecurityConfigurer<O, B>> configs = null;
if (this.allowConfigurersOfSameType) {
configs = this.configurers.get(clazz);
}
configs = (configs != null) ? configs : new ArrayList<>(1);
configs.add(configurer);
this.configurers.put(clazz, configs);
if (this.buildState.isInitializing()) {
@ -239,9 +236,8 @@ public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBui
if (configs == null) {
return null;
}
if (configs.size() != 1) {
throw new IllegalStateException("Only one configurer expected for type " + clazz + ", but got " + configs);
}
Assert.state(configs.size() == 1,
() -> "Only one configurer expected for type " + clazz + ", but got " + configs);
return (C) configs.get(0);
}
@ -257,9 +253,8 @@ public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBui
if (configs == null) {
return null;
}
if (configs.size() != 1) {
throw new IllegalStateException("Only one configurer expected for type " + clazz + ", but got " + configs);
}
Assert.state(configs.size() == 1,
() -> "Only one configurer expected for type " + clazz + ", but got " + configs);
return (C) configs.get(0);
}
@ -301,21 +296,14 @@ public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBui
protected final O doBuild() throws Exception {
synchronized (this.configurers) {
this.buildState = BuildState.INITIALIZING;
beforeInit();
init();
this.buildState = BuildState.CONFIGURING;
beforeConfigure();
configure();
this.buildState = BuildState.BUILDING;
O result = performBuild();
this.buildState = BuildState.BUILT;
return result;
}
}
@ -346,11 +334,9 @@ public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBui
@SuppressWarnings("unchecked")
private void init() throws Exception {
Collection<SecurityConfigurer<O, B>> configurers = getConfigurers();
for (SecurityConfigurer<O, B> configurer : configurers) {
configurer.init((B) this);
}
for (SecurityConfigurer<O, B> configurer : this.configurersAddedInInitializing) {
configurer.init((B) this);
}
@ -359,7 +345,6 @@ public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBui
@SuppressWarnings("unchecked")
private void configure() throws Exception {
Collection<SecurityConfigurer<O, B>> configurers = getConfigurers();
for (SecurityConfigurer<O, B> configurer : configurers) {
configurer.configure((B) this);
}

View File

@ -21,6 +21,7 @@ import java.util.List;
import org.springframework.core.GenericTypeResolver;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.util.Assert;
/**
* A base class for {@link SecurityConfigurer} that allows subclasses to only implement
@ -63,9 +64,7 @@ public abstract class SecurityConfigurerAdapter<O, B extends SecurityBuilder<O>>
* @throws IllegalStateException if {@link SecurityBuilder} is null
*/
protected final B getBuilder() {
if (this.securityBuilder == null) {
throw new IllegalStateException("securityBuilder cannot be null");
}
Assert.state(this.securityBuilder != null, "securityBuilder cannot be null");
return this.securityBuilder;
}

View File

@ -36,6 +36,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.log.LogMessage;
import org.springframework.security.authentication.AuthenticationEventPublisher;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.ObjectPostProcessor;
@ -80,7 +81,6 @@ public class AuthenticationConfiguration {
LazyPasswordEncoder defaultPasswordEncoder = new LazyPasswordEncoder(context);
AuthenticationEventPublisher authenticationEventPublisher = getBeanOrNull(context,
AuthenticationEventPublisher.class);
DefaultPasswordEncoderAuthenticationManagerBuilder result = new DefaultPasswordEncoderAuthenticationManagerBuilder(
objectPostProcessor, defaultPasswordEncoder);
if (authenticationEventPublisher != null) {
@ -115,17 +115,13 @@ public class AuthenticationConfiguration {
if (this.buildingAuthenticationManager.getAndSet(true)) {
return new AuthenticationManagerDelegator(authBuilder);
}
for (GlobalAuthenticationConfigurerAdapter config : this.globalAuthConfigurers) {
authBuilder.apply(config);
}
this.authenticationManager = authBuilder.build();
if (this.authenticationManager == null) {
this.authenticationManager = getAuthenticationManagerBean();
}
this.authenticationManagerInitialized = true;
return this.authenticationManager;
}
@ -154,20 +150,7 @@ public class AuthenticationConfiguration {
if (beanNamesForType.length == 0) {
return null;
}
String beanName;
if (beanNamesForType.length > 1) {
List<String> primaryBeanNames = getPrimaryBeanNames(beanNamesForType);
Assert.isTrue(primaryBeanNames.size() != 0, () -> "Found " + beanNamesForType.length + " beans for type "
+ interfaceName + ", but none marked as primary");
Assert.isTrue(primaryBeanNames.size() == 1, () -> "Found " + primaryBeanNames.size() + " beans for type "
+ interfaceName + " marked as primary");
beanName = primaryBeanNames.get(0);
}
else {
beanName = beanNamesForType[0];
}
String beanName = getBeanName(interfaceName, beanNamesForType);
lazyTargetSource.setTargetBeanName(beanName);
lazyTargetSource.setBeanFactory(this.applicationContext);
ProxyFactoryBean proxyFactory = new ProxyFactoryBean();
@ -176,6 +159,18 @@ public class AuthenticationConfiguration {
return (T) proxyFactory.getObject();
}
private <T> String getBeanName(Class<T> interfaceName, String[] beanNamesForType) {
if (beanNamesForType.length == 1) {
return beanNamesForType[0];
}
List<String> primaryBeanNames = getPrimaryBeanNames(beanNamesForType);
Assert.isTrue(primaryBeanNames.size() != 0, () -> "Found " + beanNamesForType.length + " beans for type "
+ interfaceName + ", but none marked as primary");
Assert.isTrue(primaryBeanNames.size() == 1,
() -> "Found " + primaryBeanNames.size() + " beans for type " + interfaceName + " marked as primary");
return primaryBeanNames.get(0);
}
private List<String> getPrimaryBeanNames(String[] beanNamesForType) {
List<String> list = new ArrayList<>();
if (!(this.applicationContext instanceof ConfigurableApplicationContext)) {
@ -217,9 +212,7 @@ public class AuthenticationConfiguration {
public void init(AuthenticationManagerBuilder auth) {
Map<String, Object> beansWithAnnotation = this.context
.getBeansWithAnnotation(EnableGlobalAuthentication.class);
if (logger.isDebugEnabled()) {
logger.debug("Eagerly initializing " + beansWithAnnotation);
}
logger.debug(LogMessage.format("Eagerly initializing %s", beansWithAnnotation));
}
}
@ -249,14 +242,12 @@ public class AuthenticationConfiguration {
if (this.delegate != null) {
return this.delegate.authenticate(authentication);
}
synchronized (this.delegateMonitor) {
if (this.delegate == null) {
this.delegate = this.delegateBuilder.getObject();
this.delegateBuilder = null;
}
}
return this.delegate.authenticate(authentication);
}

View File

@ -58,7 +58,6 @@ class InitializeAuthenticationProviderBeanManagerConfigurer extends GlobalAuthen
if (authenticationProvider == null) {
return;
}
auth.authenticationProvider(authenticationProvider);
}
@ -72,7 +71,6 @@ class InitializeAuthenticationProviderBeanManagerConfigurer extends GlobalAuthen
if (beanNames.length != 1) {
return null;
}
return InitializeAuthenticationProviderBeanManagerConfigurer.this.context.getBean(beanNames[0], type);
}

View File

@ -63,10 +63,8 @@ class InitializeUserDetailsBeanManagerConfigurer extends GlobalAuthenticationCon
if (userDetailsService == null) {
return;
}
PasswordEncoder passwordEncoder = getBeanOrNull(PasswordEncoder.class);
UserDetailsPasswordService passwordManager = getBeanOrNull(UserDetailsPasswordService.class);
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(userDetailsService);
if (passwordEncoder != null) {
@ -76,7 +74,6 @@ class InitializeUserDetailsBeanManagerConfigurer extends GlobalAuthenticationCon
provider.setUserDetailsPasswordService(passwordManager);
}
provider.afterPropertiesSet();
auth.authenticationProvider(provider);
}
@ -89,7 +86,6 @@ class InitializeUserDetailsBeanManagerConfigurer extends GlobalAuthenticationCon
if (beanNames.length != 1) {
return null;
}
return InitializeUserDetailsBeanManagerConfigurer.this.context.getBean(beanNames[0], type);
}

View File

@ -93,9 +93,7 @@ public class LdapAuthenticationProviderConfigurer<B extends ProviderManagerBuild
private LdapAuthenticationProvider build() throws Exception {
BaseLdapPathContextSource contextSource = getContextSource();
LdapAuthenticator ldapAuthenticator = createLdapAuthenticator(contextSource);
LdapAuthoritiesPopulator authoritiesPopulator = getLdapAuthoritiesPopulator();
LdapAuthenticationProvider ldapAuthenticationProvider = new LdapAuthenticationProvider(ldapAuthenticator,
authoritiesPopulator);
ldapAuthenticationProvider.setAuthoritiesMapper(getAuthoritiesMapper());
@ -136,14 +134,12 @@ public class LdapAuthenticationProviderConfigurer<B extends ProviderManagerBuild
if (this.ldapAuthoritiesPopulator != null) {
return this.ldapAuthoritiesPopulator;
}
DefaultLdapAuthoritiesPopulator defaultAuthoritiesPopulator = new DefaultLdapAuthoritiesPopulator(
this.contextSource, this.groupSearchBase);
defaultAuthoritiesPopulator.setGroupRoleAttribute(this.groupRoleAttribute);
defaultAuthoritiesPopulator.setGroupSearchFilter(this.groupSearchFilter);
defaultAuthoritiesPopulator.setSearchSubtree(this.groupSearchSubtree);
defaultAuthoritiesPopulator.setRolePrefix(this.rolePrefix);
this.ldapAuthoritiesPopulator = defaultAuthoritiesPopulator;
return defaultAuthoritiesPopulator;
}
@ -173,7 +169,6 @@ public class LdapAuthenticationProviderConfigurer<B extends ProviderManagerBuild
if (this.authoritiesMapper != null) {
return this.authoritiesMapper;
}
SimpleAuthorityMapper simpleAuthorityMapper = new SimpleAuthorityMapper();
simpleAuthorityMapper.setPrefix(this.rolePrefix);
simpleAuthorityMapper.afterPropertiesSet();
@ -554,7 +549,6 @@ public class LdapAuthenticationProviderConfigurer<B extends ProviderManagerBuild
if (this.url == null) {
startEmbeddedLdapServer();
}
DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(getProviderUrl());
if (this.managerDn != null) {
contextSource.setUserDn(this.managerDn);

View File

@ -45,7 +45,6 @@ public class UserDetailsServiceConfigurer<B extends ProviderManagerBuilder<B>, C
@Override
public void configure(B builder) throws Exception {
initUserDetailsService();
super.configure(builder);
}

View File

@ -91,8 +91,8 @@ final class AutowireBeanFactoryObjectPostProcessor
try {
disposable.destroy();
}
catch (Exception error) {
this.logger.error(error);
catch (Exception ex) {
this.logger.error(ex);
}
}
}

View File

@ -46,15 +46,12 @@ class GlobalMethodSecurityAspectJAutoProxyRegistrar implements ImportBeanDefinit
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
BeanDefinition interceptor = registry.getBeanDefinition("methodSecurityInterceptor");
BeanDefinitionBuilder aspect = BeanDefinitionBuilder.rootBeanDefinition(
"org.springframework.security.access.intercept.aspectj.aspect.AnnotationSecurityAspect");
aspect.setFactoryMethod("aspectOf");
aspect.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
aspect.addPropertyValue("securityInterceptor", interceptor);
registry.registerBeanDefinition("annotationSecurityAspect$0", aspect.getBeanDefinition());
}

View File

@ -92,11 +92,13 @@ public class GlobalMethodSecurityConfiguration implements ImportAware, SmartInit
private static final Log logger = LogFactory.getLog(GlobalMethodSecurityConfiguration.class);
private ObjectPostProcessor<Object> objectPostProcessor = new ObjectPostProcessor<Object>() {
@Override
public <T> T postProcess(T object) {
throw new IllegalStateException(ObjectPostProcessor.class.getName()
+ " is a required bean. Ensure you have used @" + EnableGlobalMethodSecurity.class.getName());
}
};
private DefaultMethodSecurityExpressionHandler defaultMethodExpressionHandler = new DefaultMethodSecurityExpressionHandler();
@ -145,7 +147,6 @@ public class GlobalMethodSecurityConfiguration implements ImportAware, SmartInit
if (runAsManager != null) {
this.methodSecurityInterceptor.setRunAsManager(runAsManager);
}
return this.methodSecurityInterceptor;
}
@ -157,22 +158,18 @@ public class GlobalMethodSecurityConfiguration implements ImportAware, SmartInit
catch (Exception ex) {
throw new RuntimeException(ex);
}
PermissionEvaluator permissionEvaluator = getSingleBeanOrNull(PermissionEvaluator.class);
if (permissionEvaluator != null) {
this.defaultMethodExpressionHandler.setPermissionEvaluator(permissionEvaluator);
}
RoleHierarchy roleHierarchy = getSingleBeanOrNull(RoleHierarchy.class);
if (roleHierarchy != null) {
this.defaultMethodExpressionHandler.setRoleHierarchy(roleHierarchy);
}
AuthenticationTrustResolver trustResolver = getSingleBeanOrNull(AuthenticationTrustResolver.class);
if (trustResolver != null) {
this.defaultMethodExpressionHandler.setTrustResolver(trustResolver);
}
GrantedAuthorityDefaults grantedAuthorityDefaults = getSingleBeanOrNull(GrantedAuthorityDefaults.class);
if (grantedAuthorityDefaults != null) {
this.defaultMethodExpressionHandler.setDefaultRolePrefix(grantedAuthorityDefaults.getRolePrefix());
@ -315,12 +312,8 @@ public class GlobalMethodSecurityConfiguration implements ImportAware, SmartInit
this.auth = new AuthenticationManagerBuilder(this.objectPostProcessor);
this.auth.authenticationEventPublisher(eventPublisher);
configure(this.auth);
if (this.disableAuthenticationRegistry) {
this.authenticationManager = getAuthenticationConfiguration().getAuthenticationManager();
}
else {
this.authenticationManager = this.auth.build();
}
this.authenticationManager = (this.disableAuthenticationRegistry)
? getAuthenticationConfiguration().getAuthenticationManager() : this.auth.build();
}
return this.authenticationManager;
}
@ -353,17 +346,13 @@ public class GlobalMethodSecurityConfiguration implements ImportAware, SmartInit
if (customMethodSecurityMetadataSource != null) {
sources.add(customMethodSecurityMetadataSource);
}
boolean hasCustom = customMethodSecurityMetadataSource != null;
boolean isPrePostEnabled = prePostEnabled();
boolean isSecuredEnabled = securedEnabled();
boolean isJsr250Enabled = jsr250Enabled();
if (!isPrePostEnabled && !isSecuredEnabled && !isJsr250Enabled && !hasCustom) {
throw new IllegalStateException("In the composition of all global method configuration, "
+ "no annotation support was actually activated");
}
Assert.state(isPrePostEnabled || isSecuredEnabled || isJsr250Enabled || hasCustom,
"In the composition of all global method configuration, "
+ "no annotation support was actually activated");
if (isPrePostEnabled) {
sources.add(new PrePostAnnotationSecurityMetadataSource(attributeFactory));
}
@ -441,10 +430,6 @@ public class GlobalMethodSecurityConfiguration implements ImportAware, SmartInit
return enableMethodSecurity().getBoolean("jsr250Enabled");
}
private int order() {
return (Integer) enableMethodSecurity().get("order");
}
private boolean isAspectJ() {
return enableMethodSecurity().getEnum("mode") == AdviceMode.ASPECTJ;
}

View File

@ -45,35 +45,27 @@ final class GlobalMethodSecuritySelector implements ImportSelector {
AnnotationAttributes attributes = AnnotationAttributes.fromMap(annotationAttributes);
Assert.notNull(attributes, () -> String.format("@%s is not present on importing class '%s' as expected",
annoType.getSimpleName(), importingClassMetadata.getClassName()));
// TODO would be nice if could use BeanClassLoaderAware (does not work)
Class<?> importingClass = ClassUtils.resolveClassName(importingClassMetadata.getClassName(),
ClassUtils.getDefaultClassLoader());
boolean skipMethodSecurityConfiguration = GlobalMethodSecurityConfiguration.class
.isAssignableFrom(importingClass);
AdviceMode mode = attributes.getEnum("mode");
boolean isProxy = AdviceMode.PROXY == mode;
String autoProxyClassName = isProxy ? AutoProxyRegistrar.class.getName()
: GlobalMethodSecurityAspectJAutoProxyRegistrar.class.getName();
boolean jsr250Enabled = attributes.getBoolean("jsr250Enabled");
List<String> classNames = new ArrayList<>(4);
if (isProxy) {
classNames.add(MethodSecurityMetadataSourceAdvisorRegistrar.class.getName());
}
classNames.add(autoProxyClassName);
if (!skipMethodSecurityConfiguration) {
classNames.add(GlobalMethodSecurityConfiguration.class.getName());
}
if (jsr250Enabled) {
classNames.add(Jsr250MetadataSourceConfiguration.class.getName());
}
return classNames.toArray(new String[0]);
}

View File

@ -42,21 +42,18 @@ class MethodSecurityMetadataSourceAdvisorRegistrar implements ImportBeanDefiniti
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
BeanDefinitionBuilder advisor = BeanDefinitionBuilder
.rootBeanDefinition(MethodSecurityMetadataSourceAdvisor.class);
advisor.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
advisor.addConstructorArgValue("methodSecurityInterceptor");
advisor.addConstructorArgReference("methodSecurityMetadataSource");
advisor.addConstructorArgValue("methodSecurityMetadataSource");
MultiValueMap<String, Object> attributes = importingClassMetadata
.getAllAnnotationAttributes(EnableGlobalMethodSecurity.class.getName());
Integer order = (Integer) attributes.getFirst("order");
if (order != null) {
advisor.addPropertyValue("order", order);
}
registry.registerBeanDefinition("metaDataSourceAdvisor", advisor.getBeanDefinition());
}

View File

@ -72,11 +72,9 @@ class ReactiveMethodSecurityConfiguration implements ImportAware {
@Bean
PrePostAdviceReactiveMethodInterceptor securityMethodInterceptor(AbstractMethodSecurityMetadataSource source,
MethodSecurityExpressionHandler handler) {
ExpressionBasedPostInvocationAdvice postAdvice = new ExpressionBasedPostInvocationAdvice(handler);
ExpressionBasedPreInvocationAdvice preAdvice = new ExpressionBasedPreInvocationAdvice();
preAdvice.setExpressionHandler(handler);
return new PrePostAdviceReactiveMethodInterceptor(source, preAdvice, postAdvice);
}

View File

@ -31,12 +31,10 @@ class ReactiveMethodSecuritySelector extends AdviceModeImportSelector<EnableReac
@Override
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
case PROXY:
if (adviceMode == AdviceMode.PROXY) {
return getProxyImports();
default:
throw new IllegalStateException("AdviceMode " + adviceMode + " is not supported");
}
throw new IllegalStateException("AdviceMode " + adviceMode + " is not supported");
}
/**

View File

@ -202,7 +202,6 @@ public class RSocketSecurity {
private List<PayloadInterceptor> payloadInterceptors() {
List<PayloadInterceptor> result = new ArrayList<>(this.payloadInterceptors);
if (this.basicAuthSpec != null) {
result.add(this.basicAuthSpec.build());
}
@ -213,7 +212,6 @@ public class RSocketSecurity {
result.addAll(this.jwtSpec.build());
}
result.add(anonymous());
if (this.authorizePayload != null) {
result.add(this.authorizePayload.build());
}
@ -260,6 +258,9 @@ public class RSocketSecurity {
private ReactiveAuthenticationManager authenticationManager;
private SimpleAuthenticationSpec() {
}
public SimpleAuthenticationSpec authenticationManager(ReactiveAuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
return this;
@ -280,15 +281,15 @@ public class RSocketSecurity {
return result;
}
private SimpleAuthenticationSpec() {
}
}
public final class BasicAuthenticationSpec {
private ReactiveAuthenticationManager authenticationManager;
private BasicAuthenticationSpec() {
}
public BasicAuthenticationSpec authenticationManager(ReactiveAuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
return this;
@ -308,15 +309,15 @@ public class RSocketSecurity {
return result;
}
private BasicAuthenticationSpec() {
}
}
public final class JwtSpec {
private ReactiveAuthenticationManager authenticationManager;
private JwtSpec() {
}
public JwtSpec authenticationManager(ReactiveAuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
return this;
@ -339,17 +340,12 @@ public class RSocketSecurity {
AuthenticationPayloadInterceptor legacy = new AuthenticationPayloadInterceptor(manager);
legacy.setAuthenticationConverter(new BearerPayloadExchangeConverter());
legacy.setOrder(PayloadInterceptorOrder.AUTHENTICATION.getOrder());
AuthenticationPayloadInterceptor standard = new AuthenticationPayloadInterceptor(manager);
standard.setAuthenticationConverter(new AuthenticationPayloadExchangeConverter());
standard.setOrder(PayloadInterceptorOrder.AUTHENTICATION.getOrder());
return Arrays.asList(standard, legacy);
}
private JwtSpec() {
}
}
public class AuthorizePayloadsSpec {

View File

@ -170,7 +170,6 @@ public abstract class AbstractRequestMatcherRegistry<C> {
for (String mvcPattern : mvcPatterns) {
MvcRequestMatcher matcher = new MvcRequestMatcher(introspector, mvcPattern);
opp.postProcess(matcher);
if (method != null) {
matcher.setMethod(method);
}

View File

@ -46,6 +46,7 @@ import org.springframework.security.web.savedrequest.RequestCacheAwareFilter;
import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
import org.springframework.security.web.session.ConcurrentSessionFilter;
import org.springframework.security.web.session.SessionManagementFilter;
import org.springframework.util.Assert;
import org.springframework.web.filter.CorsFilter;
/**
@ -138,10 +139,7 @@ final class FilterComparator implements Comparator<Filter>, Serializable {
*/
void registerAfter(Class<? extends Filter> filter, Class<? extends Filter> afterFilter) {
Integer position = getOrder(afterFilter);
if (position == null) {
throw new IllegalArgumentException("Cannot register after unregistered Filter " + afterFilter);
}
Assert.notNull(position, () -> "Cannot register after unregistered Filter " + afterFilter);
put(filter, position + 1);
}
@ -153,10 +151,7 @@ final class FilterComparator implements Comparator<Filter>, Serializable {
*/
void registerAt(Class<? extends Filter> filter, Class<? extends Filter> atFilter) {
Integer position = getOrder(atFilter);
if (position == null) {
throw new IllegalArgumentException("Cannot register after unregistered Filter " + atFilter);
}
Assert.notNull(position, () -> "Cannot register after unregistered Filter " + atFilter);
put(filter, position);
}
@ -169,10 +164,7 @@ final class FilterComparator implements Comparator<Filter>, Serializable {
*/
void registerBefore(Class<? extends Filter> filter, Class<? extends Filter> beforeFilter) {
Integer position = getOrder(beforeFilter);
if (position == null) {
throw new IllegalArgumentException("Cannot register after unregistered Filter " + beforeFilter);
}
Assert.notNull(position, () -> "Cannot register after unregistered Filter " + beforeFilter);
put(filter, position - 1);
}

View File

@ -308,20 +308,17 @@ public final class WebSecurity extends AbstractConfiguredSecurityBuilder<Filter,
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.defaultWebSecurityExpressionHandler.setApplicationContext(applicationContext);
try {
this.defaultWebSecurityExpressionHandler.setRoleHierarchy(applicationContext.getBean(RoleHierarchy.class));
}
catch (NoSuchBeanDefinitionException ex) {
}
try {
this.defaultWebSecurityExpressionHandler
.setPermissionEvaluator(applicationContext.getBean(PermissionEvaluator.class));
}
catch (NoSuchBeanDefinitionException ex) {
}
this.ignoredRequestRegistry = new IgnoredRequestConfigurer(applicationContext);
try {
this.httpFirewall = applicationContext.getBean(HttpFirewall.class);

View File

@ -80,27 +80,27 @@ class HttpSecurityConfiguration {
HttpSecurity httpSecurity() throws Exception {
WebSecurityConfigurerAdapter.LazyPasswordEncoder passwordEncoder = new WebSecurityConfigurerAdapter.LazyPasswordEncoder(
this.context);
AuthenticationManagerBuilder authenticationBuilder = new WebSecurityConfigurerAdapter.DefaultPasswordEncoderAuthenticationManagerBuilder(
this.objectPostProcessor, passwordEncoder);
authenticationBuilder.parentAuthenticationManager(authenticationManager());
HttpSecurity http = new HttpSecurity(this.objectPostProcessor, authenticationBuilder, createSharedObjects());
http.csrf(withDefaults()).addFilter(new WebAsyncManagerIntegrationFilter()).exceptionHandling(withDefaults())
.headers(withDefaults()).sessionManagement(withDefaults()).securityContext(withDefaults())
.requestCache(withDefaults()).anonymous(withDefaults()).servletApi(withDefaults())
.logout(withDefaults()).apply(new DefaultLoginPageConfigurer<>());
http.csrf(withDefaults());
http.addFilter(new WebAsyncManagerIntegrationFilter());
http.exceptionHandling(withDefaults());
http.headers(withDefaults());
http.sessionManagement(withDefaults());
http.securityContext(withDefaults());
http.requestCache(withDefaults());
http.anonymous(withDefaults());
http.servletApi(withDefaults());
http.logout(withDefaults());
http.apply(new DefaultLoginPageConfigurer<>());
return http;
}
private AuthenticationManager authenticationManager() throws Exception {
if (this.authenticationManager != null) {
return this.authenticationManager;
}
else {
return this.authenticationConfiguration.getAuthenticationManager();
}
return (this.authenticationManager != null) ? this.authenticationManager
: this.authenticationConfiguration.getAuthenticationManager();
}
private Map<Class<?>, Object> createSharedObjects() {

View File

@ -54,12 +54,12 @@ final class OAuth2ClientConfiguration {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
boolean webmvcPresent = ClassUtils.isPresent("org.springframework.web.servlet.DispatcherServlet",
getClass().getClassLoader());
return webmvcPresent ? new String[] {
"org.springframework.security.config.annotation.web.configuration.OAuth2ClientConfiguration.OAuth2ClientWebMvcSecurityConfiguration" }
: new String[] {};
if (!ClassUtils.isPresent("org.springframework.web.servlet.DispatcherServlet",
getClass().getClassLoader())) {
return new String[0];
}
return new String[] { "org.springframework.security.config.annotation.web.configuration."
+ "OAuth2ClientConfiguration.OAuth2ClientWebMvcSecurityConfiguration" };
}
}
@ -114,7 +114,6 @@ final class OAuth2ClientConfiguration {
if (this.authorizedClientManager != null) {
return this.authorizedClientManager;
}
OAuth2AuthorizedClientManager authorizedClientManager = null;
if (this.clientRegistrationRepository != null && this.authorizedClientRepository != null) {
if (this.accessTokenResponseClient != null) {

View File

@ -22,6 +22,7 @@ import java.util.Set;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
* Used by {@link EnableWebSecurity} to conditionally import:
@ -45,29 +46,25 @@ final class OAuth2ImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
Set<String> imports = new LinkedHashSet<>();
boolean oauth2ClientPresent = ClassUtils.isPresent(
"org.springframework.security.oauth2.client.registration.ClientRegistration",
getClass().getClassLoader());
ClassLoader classLoader = getClass().getClassLoader();
boolean oauth2ClientPresent = ClassUtils
.isPresent("org.springframework.security.oauth2.client.registration.ClientRegistration", classLoader);
boolean webfluxPresent = ClassUtils
.isPresent("org.springframework.web.reactive.function.client.ExchangeFilterFunction", classLoader);
boolean oauth2ResourceServerPresent = ClassUtils
.isPresent("org.springframework.security.oauth2.server.resource.BearerTokenError", classLoader);
if (oauth2ClientPresent) {
imports.add("org.springframework.security.config.annotation.web.configuration.OAuth2ClientConfiguration");
}
boolean webfluxPresent = ClassUtils.isPresent(
"org.springframework.web.reactive.function.client.ExchangeFilterFunction", getClass().getClassLoader());
if (webfluxPresent && oauth2ClientPresent) {
imports.add(
"org.springframework.security.config.annotation.web.configuration.SecurityReactorContextConfiguration");
}
boolean oauth2ResourceServerPresent = ClassUtils.isPresent(
"org.springframework.security.oauth2.server.resource.BearerTokenError", getClass().getClassLoader());
if (webfluxPresent && oauth2ResourceServerPresent) {
imports.add(
"org.springframework.security.config.annotation.web.configuration.SecurityReactorContextConfiguration");
}
return imports.toArray(new String[0]);
return StringUtils.toStringArray(imports);
}
}

View File

@ -71,7 +71,6 @@ class SecurityReactorContextConfiguration {
public void afterPropertiesSet() throws Exception {
Function<? super Publisher<Object>, ? extends Publisher<Object>> lifter = Operators
.liftPublisher((pub, sub) -> createSubscriberIfNecessary(sub));
Hooks.onLastOperator(SECURITY_REACTOR_CONTEXT_OPERATOR_KEY, (pub) -> {
if (!contextAttributesAvailable()) {
// No need to decorate so return original Publisher
@ -112,7 +111,6 @@ class SecurityReactorContextConfiguration {
if (authentication == null && servletRequest == null) {
return Collections.emptyMap();
}
Map<Object, Object> contextAttributes = new HashMap<>();
if (servletRequest != null) {
contextAttributes.put(HttpServletRequest.class, servletRequest);
@ -139,17 +137,17 @@ class SecurityReactorContextConfiguration {
SecurityReactorContextSubscriber(CoreSubscriber<T> delegate, Map<Object, Object> attributes) {
this.delegate = delegate;
Context currentContext = this.delegate.currentContext();
Context context;
if (currentContext.hasKey(SECURITY_CONTEXT_ATTRIBUTES)) {
context = currentContext;
}
else {
context = currentContext.put(SECURITY_CONTEXT_ATTRIBUTES, attributes);
}
Context context = getOrPutContext(attributes, this.delegate.currentContext());
this.context = context;
}
private Context getOrPutContext(Map<Object, Object> attributes, Context currentContext) {
if (currentContext.hasKey(SECURITY_CONTEXT_ATTRIBUTES)) {
return currentContext;
}
return currentContext.put(SECURITY_CONTEXT_ATTRIBUTES, attributes);
}
@Override
public Context currentContext() {
return this.context;

View File

@ -32,12 +32,11 @@ class SpringWebMvcImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
boolean webmvcPresent = ClassUtils.isPresent("org.springframework.web.servlet.DispatcherServlet",
getClass().getClassLoader());
return webmvcPresent
? new String[] {
"org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration" }
: new String[] {};
if (!ClassUtils.isPresent("org.springframework.web.servlet.DispatcherServlet", getClass().getClassLoader())) {
return new String[0];
}
return new String[] {
"org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration" };
}
}

View File

@ -58,7 +58,6 @@ class WebMvcSecurityConfiguration implements WebMvcConfigurer, ApplicationContex
argumentResolvers.add(authenticationPrincipalResolver);
argumentResolvers
.add(new org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver());
CurrentSecurityContextArgumentResolver currentSecurityContextArgumentResolver = new CurrentSecurityContextArgumentResolver();
currentSecurityContextArgumentResolver.setBeanResolver(this.beanResolver);
argumentResolvers.add(currentSecurityContextArgumentResolver);

View File

@ -50,6 +50,7 @@ import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.WebInvocationPrivilegeEvaluator;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
import org.springframework.util.Assert;
/**
* Uses a {@link WebSecurity} to create the {@link FilterChainProxy} that performs the web
@ -101,10 +102,8 @@ public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAwa
public Filter springSecurityFilterChain() throws Exception {
boolean hasConfigurers = this.webSecurityConfigurers != null && !this.webSecurityConfigurers.isEmpty();
boolean hasFilterChain = !this.securityFilterChains.isEmpty();
if (hasConfigurers && hasFilterChain) {
throw new IllegalStateException(
"Found WebSecurityConfigurerAdapter as well as SecurityFilterChain." + "Please select just one.");
}
Assert.state(!(hasConfigurers && hasFilterChain),
"Found WebSecurityConfigurerAdapter as well as SecurityFilterChain. Please select just one.");
if (!hasConfigurers && !hasFilterChain) {
WebSecurityConfigurerAdapter adapter = this.objectObjectPostProcessor
.postProcess(new WebSecurityConfigurerAdapter() {
@ -152,9 +151,7 @@ public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAwa
if (this.debugEnabled != null) {
this.webSecurity.debug(this.debugEnabled);
}
webSecurityConfigurers.sort(AnnotationAwareOrderComparator.INSTANCE);
Integer previousOrder = null;
Object previousConfig = null;
for (SecurityConfigurer<Filter, WebSecurity> config : webSecurityConfigurers) {

View File

@ -18,7 +18,6 @@ package org.springframework.security.config.annotation.web.configuration;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@ -200,34 +199,17 @@ public abstract class WebSecurityConfigurerAdapter implements WebSecurityConfigu
if (this.http != null) {
return this.http;
}
AuthenticationEventPublisher eventPublisher = getAuthenticationEventPublisher();
this.localConfigureAuthenticationBldr.authenticationEventPublisher(eventPublisher);
AuthenticationManager authenticationManager = authenticationManager();
this.authenticationBuilder.parentAuthenticationManager(authenticationManager);
Map<Class<?>, Object> sharedObjects = createSharedObjects();
this.http = new HttpSecurity(this.objectPostProcessor, this.authenticationBuilder, sharedObjects);
if (!this.disableDefaults) {
// @formatter:off
this.http
.csrf().and()
.addFilter(new WebAsyncManagerIntegrationFilter())
.exceptionHandling().and()
.headers().and()
.sessionManagement().and()
.securityContext().and()
.requestCache().and()
.anonymous().and()
.servletApi().and()
.apply(new DefaultLoginPageConfigurer<>()).and()
.logout();
// @formatter:on
applyDefaultConfiguration(this.http);
ClassLoader classLoader = this.context.getClassLoader();
List<AbstractHttpConfigurer> defaultHttpConfigurers = SpringFactoriesLoader
.loadFactories(AbstractHttpConfigurer.class, classLoader);
for (AbstractHttpConfigurer configurer : defaultHttpConfigurers) {
this.http.apply(configurer);
}
@ -236,6 +218,20 @@ public abstract class WebSecurityConfigurerAdapter implements WebSecurityConfigu
return this.http;
}
private void applyDefaultConfiguration(HttpSecurity http) throws Exception {
http.csrf();
http.addFilter(new WebAsyncManagerIntegrationFilter());
http.exceptionHandling();
http.headers();
http.sessionManagement();
http.securityContext();
http.requestCache();
http.anonymous();
http.servletApi();
http.apply(new DefaultLoginPageConfigurer<>());
http.logout();
}
/**
* Override this method to expose the {@link AuthenticationManager} from
* {@link #configure(AuthenticationManagerBuilder)} to be exposed as a Bean. For
@ -315,8 +311,8 @@ public abstract class WebSecurityConfigurerAdapter implements WebSecurityConfigu
}
@Override
public void init(final WebSecurity web) throws Exception {
final HttpSecurity http = getHttp();
public void init(WebSecurity web) throws Exception {
HttpSecurity http = getHttp();
web.addSecurityFilterChainBuilder(http).postBuildAction(() -> {
FilterSecurityInterceptor securityInterceptor = http.getSharedObject(FilterSecurityInterceptor.class);
web.securityInterceptor(securityInterceptor);
@ -354,17 +350,11 @@ public abstract class WebSecurityConfigurerAdapter implements WebSecurityConfigu
* @throws Exception if an error occurs
*/
protected void configure(HttpSecurity http) throws Exception {
this.logger.debug(
"Using default configure(HttpSecurity). If subclassed this will potentially override subclass configure(HttpSecurity).");
// @formatter:off
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().and()
.httpBasic();
// @formatter:on
this.logger.debug("Using default configure(HttpSecurity). "
+ "If subclassed this will potentially override subclass configure(HttpSecurity).");
http.authorizeRequests((requests) -> requests.anyRequest().authenticated());
http.formLogin();
http.httpBasic();
}
/**
@ -378,14 +368,13 @@ public abstract class WebSecurityConfigurerAdapter implements WebSecurityConfigu
@Autowired
public void setApplicationContext(ApplicationContext context) {
this.context = context;
ObjectPostProcessor<Object> objectPostProcessor = context.getBean(ObjectPostProcessor.class);
LazyPasswordEncoder passwordEncoder = new LazyPasswordEncoder(context);
this.authenticationBuilder = new DefaultPasswordEncoderAuthenticationManagerBuilder(objectPostProcessor,
passwordEncoder);
this.localConfigureAuthenticationBldr = new DefaultPasswordEncoderAuthenticationManagerBuilder(
objectPostProcessor, passwordEncoder) {
@Override
public AuthenticationManagerBuilder eraseCredentials(boolean eraseCredentials) {
WebSecurityConfigurerAdapter.this.authenticationBuilder.eraseCredentials(eraseCredentials);
@ -398,6 +387,7 @@ public abstract class WebSecurityConfigurerAdapter implements WebSecurityConfigu
WebSecurityConfigurerAdapter.this.authenticationBuilder.authenticationEventPublisher(eventPublisher);
return super.authenticationEventPublisher(eventPublisher);
}
};
}
@ -458,10 +448,8 @@ public abstract class WebSecurityConfigurerAdapter implements WebSecurityConfigu
private final Object delegateMonitor = new Object();
UserDetailsServiceDelegator(List<AuthenticationManagerBuilder> delegateBuilders) {
if (delegateBuilders.contains(null)) {
throw new IllegalArgumentException(
"delegateBuilders cannot contain null values. Got " + delegateBuilders);
}
Assert.isTrue(!delegateBuilders.contains(null),
() -> "delegateBuilders cannot contain null values. Got " + delegateBuilders);
this.delegateBuilders = delegateBuilders;
}
@ -470,7 +458,6 @@ public abstract class WebSecurityConfigurerAdapter implements WebSecurityConfigu
if (this.delegate != null) {
return this.delegate.loadUserByUsername(username);
}
synchronized (this.delegateMonitor) {
if (this.delegate == null) {
for (AuthenticationManagerBuilder delegateBuilder : this.delegateBuilders) {
@ -479,14 +466,12 @@ public abstract class WebSecurityConfigurerAdapter implements WebSecurityConfigu
break;
}
}
if (this.delegate == null) {
throw new IllegalStateException("UserDetailsService is required.");
}
this.delegateBuilders = null;
}
}
return this.delegate.loadUserByUsername(username);
}
@ -524,14 +509,12 @@ public abstract class WebSecurityConfigurerAdapter implements WebSecurityConfigu
if (this.delegate != null) {
return this.delegate.authenticate(authentication);
}
synchronized (this.delegateMonitor) {
if (this.delegate == null) {
this.delegate = this.delegateBuilder.getObject();
this.delegateBuilder = null;
}
}
return this.delegate.authenticate(authentication);
}
@ -542,19 +525,18 @@ public abstract class WebSecurityConfigurerAdapter implements WebSecurityConfigu
}
private static void validateBeanCycle(Object auth, Set<String> beanNames) {
if (auth != null && !beanNames.isEmpty()) {
if (auth instanceof Advised) {
Advised advised = (Advised) auth;
TargetSource targetSource = advised.getTargetSource();
if (targetSource instanceof LazyInitTargetSource) {
LazyInitTargetSource lits = (LazyInitTargetSource) targetSource;
if (beanNames.contains(lits.getTargetBeanName())) {
throw new FatalBeanException(
"A dependency cycle was detected when trying to resolve the AuthenticationManager. Please ensure you have configured authentication.");
}
}
}
beanNames = Collections.emptySet();
if (auth == null || beanNames.isEmpty() || !(auth instanceof Advised)) {
return;
}
TargetSource targetSource = ((Advised) auth).getTargetSource();
if (!(targetSource instanceof LazyInitTargetSource)) {
return;
}
LazyInitTargetSource lits = (LazyInitTargetSource) targetSource;
if (beanNames.contains(lits.getTargetBeanName())) {
throw new FatalBeanException(
"A dependency cycle was detected when trying to resolve the AuthenticationManager. "
+ "Please ensure you have configured authentication.");
}
}
@ -634,7 +616,7 @@ public abstract class WebSecurityConfigurerAdapter implements WebSecurityConfigu
try {
return this.applicationContext.getBean(type);
}
catch (NoSuchBeanDefinitionException notFound) {
catch (NoSuchBeanDefinitionException ex) {
return null;
}
}

View File

@ -253,15 +253,12 @@ public abstract class AbstractAuthenticationFilterConfigurer<B extends HttpSecur
if (contentNegotiationStrategy == null) {
contentNegotiationStrategy = new HeaderContentNegotiationStrategy();
}
MediaTypeRequestMatcher mediaMatcher = new MediaTypeRequestMatcher(contentNegotiationStrategy,
MediaType.APPLICATION_XHTML_XML, new MediaType("image", "*"), MediaType.TEXT_HTML,
MediaType.TEXT_PLAIN);
mediaMatcher.setIgnoredMediaTypes(Collections.singleton(MediaType.ALL));
RequestMatcher notXRequestedWith = new NegatedRequestMatcher(
new RequestHeaderRequestMatcher("X-Requested-With", "XMLHttpRequest"));
return new AndRequestMatcher(Arrays.asList(notXRequestedWith, mediaMatcher));
}
@ -271,12 +268,10 @@ public abstract class AbstractAuthenticationFilterConfigurer<B extends HttpSecur
if (portMapper != null) {
this.authenticationEntryPoint.setPortMapper(portMapper);
}
RequestCache requestCache = http.getSharedObject(RequestCache.class);
if (requestCache != null) {
this.defaultSuccessHandler.setRequestCache(requestCache);
}
this.authFilter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class));
this.authFilter.setAuthenticationSuccessHandler(this.successHandler);
this.authFilter.setAuthenticationFailureHandler(this.failureHandler);
@ -383,8 +378,7 @@ public abstract class AbstractAuthenticationFilterConfigurer<B extends HttpSecur
if (this.failureHandler == null) {
failureUrl(this.loginPage + "?error");
}
final LogoutConfigurer<B> logoutConfigurer = getBuilder().getConfigurer(LogoutConfigurer.class);
LogoutConfigurer<B> logoutConfigurer = getBuilder().getConfigurer(LogoutConfigurer.class);
if (logoutConfigurer != null && !logoutConfigurer.isCustomLogoutSuccess()) {
logoutConfigurer.logoutSuccessUrl(this.loginPage + "?logout");
}

View File

@ -24,6 +24,7 @@ import java.util.List;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.config.annotation.web.AbstractRequestMatcherRegistry;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.util.Assert;
/**
* A base class for registering {@link RequestMatcher}'s. For example, it might allow for
@ -102,11 +103,8 @@ public abstract class AbstractConfigAttributeRequestMatcherRegistry<C> extends A
* {@link ConfigAttribute} instances. Cannot be null.
*/
final LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> createRequestMap() {
if (this.unmappedMatchers != null) {
throw new IllegalStateException("An incomplete mapping was found for " + this.unmappedMatchers
+ ". Try completing it with something like requestUrls().<something>.hasRole('USER')");
}
Assert.state(this.unmappedMatchers == null, () -> "An incomplete mapping was found for " + this.unmappedMatchers
+ ". Try completing it with something like requestUrls().<something>.hasRole('USER')");
LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> requestMap = new LinkedHashMap<>();
for (UrlMapping mapping : getUrlMappings()) {
RequestMatcher matcher = mapping.getRequestMatcher();

View File

@ -28,7 +28,6 @@ import org.springframework.security.web.DefaultSecurityFilterChain;
* {@link HttpSecurity}.
*
* @author Rob Winch
*
*/
public abstract class AbstractHttpConfigurer<T extends AbstractHttpConfigurer<T, B>, B extends HttpSecurityBuilder<B>>
extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, B> {

View File

@ -105,13 +105,10 @@ public final class ChannelSecurityConfigurer<H extends HttpSecurityBuilder<H>>
ChannelDecisionManagerImpl channelDecisionManager = new ChannelDecisionManagerImpl();
channelDecisionManager.setChannelProcessors(getChannelProcessors(http));
channelDecisionManager = postProcess(channelDecisionManager);
this.channelFilter.setChannelDecisionManager(channelDecisionManager);
DefaultFilterInvocationSecurityMetadataSource filterInvocationSecurityMetadataSource = new DefaultFilterInvocationSecurityMetadataSource(
this.requestMap);
this.channelFilter.setSecurityMetadataSource(filterInvocationSecurityMetadataSource);
this.channelFilter = postProcess(this.channelFilter);
http.addFilter(this.channelFilter);
}
@ -120,28 +117,25 @@ public final class ChannelSecurityConfigurer<H extends HttpSecurityBuilder<H>>
if (this.channelProcessors != null) {
return this.channelProcessors;
}
InsecureChannelProcessor insecureChannelProcessor = new InsecureChannelProcessor();
SecureChannelProcessor secureChannelProcessor = new SecureChannelProcessor();
PortMapper portMapper = http.getSharedObject(PortMapper.class);
if (portMapper != null) {
RetryWithHttpEntryPoint httpEntryPoint = new RetryWithHttpEntryPoint();
httpEntryPoint.setPortMapper(portMapper);
insecureChannelProcessor.setEntryPoint(httpEntryPoint);
RetryWithHttpsEntryPoint httpsEntryPoint = new RetryWithHttpsEntryPoint();
httpsEntryPoint.setPortMapper(portMapper);
secureChannelProcessor.setEntryPoint(httpsEntryPoint);
}
insecureChannelProcessor = postProcess(insecureChannelProcessor);
secureChannelProcessor = postProcess(secureChannelProcessor);
return Arrays.<ChannelProcessor>asList(insecureChannelProcessor, secureChannelProcessor);
return Arrays.asList(insecureChannelProcessor, secureChannelProcessor);
}
private ChannelRequestMatcherRegistry addAttribute(String attribute, List<? extends RequestMatcher> matchers) {
for (RequestMatcher matcher : matchers) {
Collection<ConfigAttribute> attrs = Arrays.<ConfigAttribute>asList(new SecurityConfig(attribute));
Collection<ConfigAttribute> attrs = Arrays.asList(new SecurityConfig(attribute));
this.requestMap.put(matcher, attrs);
}
return this.REGISTRY;

View File

@ -20,6 +20,7 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
@ -63,12 +64,9 @@ public class CorsConfigurer<H extends HttpSecurityBuilder<H>> extends AbstractHt
@Override
public void configure(H http) {
ApplicationContext context = http.getSharedObject(ApplicationContext.class);
CorsFilter corsFilter = getCorsFilter(context);
if (corsFilter == null) {
throw new IllegalStateException("Please configure either a " + CORS_FILTER_BEAN_NAME + " bean or a "
+ CORS_CONFIGURATION_SOURCE_BEAN_NAME + "bean.");
}
Assert.state(corsFilter != null, () -> "Please configure either a " + CORS_FILTER_BEAN_NAME + " bean or a "
+ CORS_CONFIGURATION_SOURCE_BEAN_NAME + "bean.");
http.addFilter(corsFilter);
}
@ -76,19 +74,16 @@ public class CorsConfigurer<H extends HttpSecurityBuilder<H>> extends AbstractHt
if (this.configurationSource != null) {
return new CorsFilter(this.configurationSource);
}
boolean containsCorsFilter = context.containsBeanDefinition(CORS_FILTER_BEAN_NAME);
if (containsCorsFilter) {
return context.getBean(CORS_FILTER_BEAN_NAME, CorsFilter.class);
}
boolean containsCorsSource = context.containsBean(CORS_CONFIGURATION_SOURCE_BEAN_NAME);
if (containsCorsSource) {
CorsConfigurationSource configurationSource = context.getBean(CORS_CONFIGURATION_SOURCE_BEAN_NAME,
CorsConfigurationSource.class);
return new CorsFilter(configurationSource);
}
boolean mvcPresent = ClassUtils.isPresent(HANDLER_MAPPING_INTROSPECTOR, context.getClassLoader());
if (mvcPresent) {
return MvcCorsFilter.getMvcCorsFilter(context);

View File

@ -289,7 +289,6 @@ public final class CsrfConfigurer<H extends HttpSecurityBuilder<H>>
if (invalidSessionStrategy == null) {
return defaultAccessDeniedHandler;
}
InvalidSessionAccessDeniedHandler invalidSessionDeniedHandler = new InvalidSessionAccessDeniedHandler(
invalidSessionStrategy);
LinkedHashMap<Class<? extends AccessDeniedException>, AccessDeniedHandler> handlers = new LinkedHashMap<>();
@ -307,9 +306,7 @@ public final class CsrfConfigurer<H extends HttpSecurityBuilder<H>>
if (this.sessionAuthenticationStrategy != null) {
return this.sessionAuthenticationStrategy;
}
else {
return new CsrfAuthenticationStrategy(this.csrfTokenRepository);
}
return new CsrfAuthenticationStrategy(this.csrfTokenRepository);
}
/**

View File

@ -18,7 +18,6 @@ package org.springframework.security.config.annotation.web.configurers;
import java.util.Collections;
import java.util.Map;
import java.util.function.Function;
import javax.servlet.http.HttpServletRequest;
@ -76,18 +75,17 @@ public final class DefaultLoginPageConfigurer<H extends HttpSecurityBuilder<H>>
@Override
public void init(H http) {
Function<HttpServletRequest, Map<String, String>> hiddenInputs = (request) -> {
CsrfToken token = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
if (token == null) {
return Collections.emptyMap();
}
return Collections.singletonMap(token.getParameterName(), token.getToken());
};
this.loginPageGeneratingFilter.setResolveHiddenInputs(hiddenInputs);
this.logoutPageGeneratingFilter.setResolveHiddenInputs(hiddenInputs);
this.loginPageGeneratingFilter.setResolveHiddenInputs(DefaultLoginPageConfigurer.this::hiddenInputs);
this.logoutPageGeneratingFilter.setResolveHiddenInputs(DefaultLoginPageConfigurer.this::hiddenInputs);
http.setSharedObject(DefaultLoginPageGeneratingFilter.class, this.loginPageGeneratingFilter);
}
private Map<String, String> hiddenInputs(HttpServletRequest request) {
CsrfToken token = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
return (token != null) ? Collections.singletonMap(token.getParameterName(), token.getToken())
: Collections.emptyMap();
}
@Override
@SuppressWarnings("unchecked")
public void configure(H http) {
@ -96,7 +94,6 @@ public final class DefaultLoginPageConfigurer<H extends HttpSecurityBuilder<H>>
if (exceptionConf != null) {
authenticationEntryPoint = exceptionConf.getAuthenticationEntryPoint();
}
if (this.loginPageGeneratingFilter.isEnabled() && authenticationEntryPoint == null) {
this.loginPageGeneratingFilter = postProcess(this.loginPageGeneratingFilter);
http.addFilter(this.loginPageGeneratingFilter);

View File

@ -139,44 +139,40 @@ public final class ExpressionUrlAuthorizationConfigurer<H extends HttpSecurityBu
@Override
ExpressionBasedFilterInvocationSecurityMetadataSource createMetadataSource(H http) {
LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> requestMap = this.REGISTRY.createRequestMap();
if (requestMap.isEmpty()) {
throw new IllegalStateException(
"At least one mapping is required (i.e. authorizeRequests().anyRequest().authenticated())");
}
Assert.state(!requestMap.isEmpty(),
"At least one mapping is required (i.e. authorizeRequests().anyRequest().authenticated())");
return new ExpressionBasedFilterInvocationSecurityMetadataSource(requestMap, getExpressionHandler(http));
}
private SecurityExpressionHandler<FilterInvocation> getExpressionHandler(H http) {
if (this.expressionHandler == null) {
DefaultWebSecurityExpressionHandler defaultHandler = new DefaultWebSecurityExpressionHandler();
AuthenticationTrustResolver trustResolver = http.getSharedObject(AuthenticationTrustResolver.class);
if (trustResolver != null) {
defaultHandler.setTrustResolver(trustResolver);
}
ApplicationContext context = http.getSharedObject(ApplicationContext.class);
if (context != null) {
String[] roleHiearchyBeanNames = context.getBeanNamesForType(RoleHierarchy.class);
if (roleHiearchyBeanNames.length == 1) {
defaultHandler.setRoleHierarchy(context.getBean(roleHiearchyBeanNames[0], RoleHierarchy.class));
}
String[] grantedAuthorityDefaultsBeanNames = context
.getBeanNamesForType(GrantedAuthorityDefaults.class);
if (grantedAuthorityDefaultsBeanNames.length == 1) {
GrantedAuthorityDefaults grantedAuthorityDefaults = context
.getBean(grantedAuthorityDefaultsBeanNames[0], GrantedAuthorityDefaults.class);
defaultHandler.setDefaultRolePrefix(grantedAuthorityDefaults.getRolePrefix());
}
String[] permissionEvaluatorBeanNames = context.getBeanNamesForType(PermissionEvaluator.class);
if (permissionEvaluatorBeanNames.length == 1) {
PermissionEvaluator permissionEvaluator = context.getBean(permissionEvaluatorBeanNames[0],
PermissionEvaluator.class);
defaultHandler.setPermissionEvaluator(permissionEvaluator);
}
}
this.expressionHandler = postProcess(defaultHandler);
if (this.expressionHandler != null) {
return this.expressionHandler;
}
DefaultWebSecurityExpressionHandler defaultHandler = new DefaultWebSecurityExpressionHandler();
AuthenticationTrustResolver trustResolver = http.getSharedObject(AuthenticationTrustResolver.class);
if (trustResolver != null) {
defaultHandler.setTrustResolver(trustResolver);
}
ApplicationContext context = http.getSharedObject(ApplicationContext.class);
if (context != null) {
String[] roleHiearchyBeanNames = context.getBeanNamesForType(RoleHierarchy.class);
if (roleHiearchyBeanNames.length == 1) {
defaultHandler.setRoleHierarchy(context.getBean(roleHiearchyBeanNames[0], RoleHierarchy.class));
}
String[] grantedAuthorityDefaultsBeanNames = context.getBeanNamesForType(GrantedAuthorityDefaults.class);
if (grantedAuthorityDefaultsBeanNames.length == 1) {
GrantedAuthorityDefaults grantedAuthorityDefaults = context
.getBean(grantedAuthorityDefaultsBeanNames[0], GrantedAuthorityDefaults.class);
defaultHandler.setDefaultRolePrefix(grantedAuthorityDefaults.getRolePrefix());
}
String[] permissionEvaluatorBeanNames = context.getBeanNamesForType(PermissionEvaluator.class);
if (permissionEvaluatorBeanNames.length == 1) {
PermissionEvaluator permissionEvaluator = context.getBean(permissionEvaluatorBeanNames[0],
PermissionEvaluator.class);
defaultHandler.setPermissionEvaluator(permissionEvaluator);
}
}
this.expressionHandler = postProcess(defaultHandler);
return this.expressionHandler;
}
@ -187,10 +183,8 @@ public final class ExpressionUrlAuthorizationConfigurer<H extends HttpSecurityBu
private static String hasRole(String role) {
Assert.notNull(role, "role cannot be null");
if (role.startsWith("ROLE_")) {
throw new IllegalArgumentException(
"role should not start with 'ROLE_' since it is automatically inserted. Got '" + role + "'");
}
Assert.isTrue(!role.startsWith("ROLE_"),
() -> "role should not start with 'ROLE_' since it is automatically inserted. Got '" + role + "'");
return "hasRole('ROLE_" + role + "')";
}
@ -210,9 +204,6 @@ public final class ExpressionUrlAuthorizationConfigurer<H extends HttpSecurityBu
public final class ExpressionInterceptUrlRegistry extends
ExpressionUrlAuthorizationConfigurer<H>.AbstractInterceptUrlRegistry<ExpressionInterceptUrlRegistry, AuthorizedUrl> {
/**
* @param context
*/
private ExpressionInterceptUrlRegistry(ApplicationContext context) {
setApplicationContext(context);
}

View File

@ -329,7 +329,6 @@ public class HeadersConfigurer<H extends HttpSecurityBuilder<H>>
Customizer<ContentSecurityPolicyConfig> contentSecurityCustomizer) {
this.contentSecurityPolicy.writer = new ContentSecurityPolicyHeaderWriter();
contentSecurityCustomizer.customize(this.contentSecurityPolicy);
return HeadersConfigurer.this;
}

View File

@ -97,10 +97,8 @@ public final class HttpBasicConfigurer<B extends HttpSecurityBuilder<B>>
*/
public HttpBasicConfigurer() {
realmName(DEFAULT_REALM);
LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> entryPoints = new LinkedHashMap<>();
entryPoints.put(X_REQUESTED_WITH, new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
DelegatingAuthenticationEntryPoint defaultEntryPoint = new DelegatingAuthenticationEntryPoint(entryPoints);
defaultEntryPoint.setDefaultEntryPoint(this.basicAuthEntryPoint);
this.authenticationEntryPoint = defaultEntryPoint;
@ -154,24 +152,19 @@ public final class HttpBasicConfigurer<B extends HttpSecurityBuilder<B>>
if (contentNegotiationStrategy == null) {
contentNegotiationStrategy = new HeaderContentNegotiationStrategy();
}
MediaTypeRequestMatcher restMatcher = new MediaTypeRequestMatcher(contentNegotiationStrategy,
MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_JSON,
MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_XML, MediaType.MULTIPART_FORM_DATA,
MediaType.TEXT_XML);
restMatcher.setIgnoredMediaTypes(Collections.singleton(MediaType.ALL));
MediaTypeRequestMatcher allMatcher = new MediaTypeRequestMatcher(contentNegotiationStrategy, MediaType.ALL);
allMatcher.setUseEquals(true);
RequestMatcher notHtmlMatcher = new NegatedRequestMatcher(
new MediaTypeRequestMatcher(contentNegotiationStrategy, MediaType.TEXT_HTML));
RequestMatcher restNotHtmlMatcher = new AndRequestMatcher(
Arrays.<RequestMatcher>asList(notHtmlMatcher, restMatcher));
RequestMatcher preferredMatcher = new OrRequestMatcher(
Arrays.asList(X_REQUESTED_WITH, restNotHtmlMatcher, allMatcher));
registerDefaultEntryPoint(http, preferredMatcher);
registerDefaultLogoutSuccessHandler(http, preferredMatcher);
}

View File

@ -192,12 +192,8 @@ public final class JeeConfigurer<H extends HttpSecurityBuilder<H>> extends Abstr
PreAuthenticatedAuthenticationProvider authenticationProvider = new PreAuthenticatedAuthenticationProvider();
authenticationProvider.setPreAuthenticatedUserDetailsService(getUserDetailsService());
authenticationProvider = postProcess(authenticationProvider);
// @formatter:off
http
.authenticationProvider(authenticationProvider)
.setSharedObject(AuthenticationEntryPoint.class, new Http403ForbiddenEntryPoint());
// @formatter:on
http.authenticationProvider(authenticationProvider).setSharedObject(AuthenticationEntryPoint.class,
new Http403ForbiddenEntryPoint());
}
@Override
@ -245,7 +241,6 @@ public final class JeeConfigurer<H extends HttpSecurityBuilder<H>> extends Abstr
SimpleMappableAttributesRetriever rolesRetriever = new SimpleMappableAttributesRetriever();
rolesRetriever.setMappableAttributes(this.mappableRoles);
detailsSource.setMappableRolesRetriever(rolesRetriever);
detailsSource = postProcess(detailsSource);
return detailsSource;
}

View File

@ -276,7 +276,6 @@ public final class LogoutConfigurer<H extends HttpSecurityBuilder<H>>
PermitAllSupport.permitAll(http, this.logoutSuccessUrl);
PermitAllSupport.permitAll(http, this.getLogoutRequestMatcher(http));
}
DefaultLoginPageGeneratingFilter loginPageGeneratingFilter = http
.getSharedObject(DefaultLoginPageGeneratingFilter.class);
if (loginPageGeneratingFilter != null && !isCustomLogoutSuccess()) {
@ -334,20 +333,28 @@ public final class LogoutConfigurer<H extends HttpSecurityBuilder<H>>
return result;
}
@SuppressWarnings("unchecked")
private RequestMatcher getLogoutRequestMatcher(H http) {
if (this.logoutRequestMatcher != null) {
return this.logoutRequestMatcher;
}
if (http.getConfigurer(CsrfConfigurer.class) != null) {
this.logoutRequestMatcher = new AntPathRequestMatcher(this.logoutUrl, "POST");
}
else {
this.logoutRequestMatcher = new OrRequestMatcher(new AntPathRequestMatcher(this.logoutUrl, "GET"),
new AntPathRequestMatcher(this.logoutUrl, "POST"), new AntPathRequestMatcher(this.logoutUrl, "PUT"),
new AntPathRequestMatcher(this.logoutUrl, "DELETE"));
}
this.logoutRequestMatcher = createLogoutRequestMatcher(http);
return this.logoutRequestMatcher;
}
@SuppressWarnings("unchecked")
private RequestMatcher createLogoutRequestMatcher(H http) {
RequestMatcher post = createLogoutRequestMatcher("POST");
if (http.getConfigurer(CsrfConfigurer.class) != null) {
return post;
}
RequestMatcher get = createLogoutRequestMatcher("GET");
RequestMatcher put = createLogoutRequestMatcher("PUT");
RequestMatcher delete = createLogoutRequestMatcher("DELETE");
return new OrRequestMatcher(get, post, put, delete);
}
private RequestMatcher createLogoutRequestMatcher(String httpMethod) {
return new AntPathRequestMatcher(this.logoutUrl, httpMethod);
}
}

View File

@ -22,6 +22,7 @@ import org.springframework.security.access.SecurityConfig;
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
import org.springframework.security.config.annotation.web.configurers.AbstractConfigAttributeRequestMatcherRegistry.UrlMapping;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.util.Assert;
/**
* Configures non-null URL's to grant access to every URL
@ -47,11 +48,7 @@ final class PermitAllSupport {
RequestMatcher... requestMatchers) {
ExpressionUrlAuthorizationConfigurer<?> configurer = http
.getConfigurer(ExpressionUrlAuthorizationConfigurer.class);
if (configurer == null) {
throw new IllegalStateException("permitAll only works with HttpSecurity.authorizeRequests()");
}
Assert.state(configurer != null, "permitAll only works with HttpSecurity.authorizeRequests()");
for (RequestMatcher matcher : requestMatchers) {
if (matcher != null) {
configurer.getRegistry().addMapping(0, new UrlMapping(matcher,
@ -72,15 +69,12 @@ final class PermitAllSupport {
public boolean matches(HttpServletRequest request) {
String uri = request.getRequestURI();
String query = request.getQueryString();
if (query != null) {
uri += "?" + query;
}
if ("".equals(request.getContextPath())) {
return uri.equals(this.processUrl);
}
return uri.equals(request.getContextPath() + this.processUrl);
}

View File

@ -35,6 +35,7 @@ import org.springframework.security.web.authentication.rememberme.PersistentToke
import org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices;
import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter;
import org.springframework.util.Assert;
/**
* Configures Remember Me authentication. This typically involves the user checking a box
@ -275,11 +276,9 @@ public final class RememberMeConfigurer<H extends HttpSecurityBuilder<H>>
if (logoutConfigurer != null && this.logoutHandler != null) {
logoutConfigurer.addLogoutHandler(this.logoutHandler);
}
RememberMeAuthenticationProvider authenticationProvider = new RememberMeAuthenticationProvider(key);
authenticationProvider = postProcess(authenticationProvider);
http.authenticationProvider(authenticationProvider);
initDefaultLoginFilter(http);
}
@ -299,8 +298,8 @@ public final class RememberMeConfigurer<H extends HttpSecurityBuilder<H>>
* time.
*/
private void validateInput() {
if (this.rememberMeServices != null && this.rememberMeCookieName != DEFAULT_REMEMBER_ME_NAME) {
throw new IllegalArgumentException("Can not set rememberMeCookieName " + "and custom rememberMeServices.");
if (this.rememberMeServices != null && !DEFAULT_REMEMBER_ME_NAME.equals(this.rememberMeCookieName)) {
throw new IllegalArgumentException("Can not set rememberMeCookieName and custom rememberMeServices.");
}
}
@ -406,11 +405,9 @@ public final class RememberMeConfigurer<H extends HttpSecurityBuilder<H>>
if (this.userDetailsService == null) {
this.userDetailsService = http.getSharedObject(UserDetailsService.class);
}
if (this.userDetailsService == null) {
throw new IllegalStateException(
"userDetailsService cannot be null. Invoke " + RememberMeConfigurer.class.getSimpleName()
+ "#userDetailsService(UserDetailsService) or see its javadoc for alternative approaches.");
}
Assert.state(this.userDetailsService != null,
() -> "userDetailsService cannot be null. Invoke " + RememberMeConfigurer.class.getSimpleName()
+ "#userDetailsService(UserDetailsService) or see its javadoc for alternative approaches.");
return this.userDetailsService;
}

View File

@ -145,12 +145,9 @@ public final class RequestCacheConfigurer<H extends HttpSecurityBuilder<H>>
@SuppressWarnings("unchecked")
private RequestMatcher createDefaultSavedRequestMatcher(H http) {
RequestMatcher notFavIcon = new NegatedRequestMatcher(new AntPathRequestMatcher("/**/favicon.*"));
RequestMatcher notXRequestedWith = new NegatedRequestMatcher(
new RequestHeaderRequestMatcher("X-Requested-With", "XMLHttpRequest"));
boolean isCsrfEnabled = http.getConfigurer(CsrfConfigurer.class) != null;
List<RequestMatcher> matchers = new ArrayList<>();
if (isCsrfEnabled) {
RequestMatcher getRequests = new AntPathRequestMatcher("/**", "GET");
@ -161,7 +158,6 @@ public final class RequestCacheConfigurer<H extends HttpSecurityBuilder<H>>
matchers.add(notXRequestedWith);
matchers.add(notMatchingMediaType(http, MediaType.MULTIPART_FORM_DATA));
matchers.add(notMatchingMediaType(http, MediaType.TEXT_EVENT_STREAM));
return new AndRequestMatcher(matchers);
}
@ -170,7 +166,6 @@ public final class RequestCacheConfigurer<H extends HttpSecurityBuilder<H>>
if (contentNegotiationStrategy == null) {
contentNegotiationStrategy = new HeaderContentNegotiationStrategy();
}
MediaTypeRequestMatcher mediaRequest = new MediaTypeRequestMatcher(contentNegotiationStrategy, mediaType);
mediaRequest.setIgnoredMediaTypes(Collections.singleton(MediaType.ALL));
return new NegatedRequestMatcher(mediaRequest);

View File

@ -82,7 +82,6 @@ public final class SecurityContextConfigurer<H extends HttpSecurityBuilder<H>>
@Override
@SuppressWarnings("unchecked")
public void configure(H http) {
SecurityContextRepository securityContextRepository = http.getSharedObject(SecurityContextRepository.class);
if (securityContextRepository == null) {
securityContextRepository = new HttpSessionSecurityContextRepository();

View File

@ -316,7 +316,6 @@ public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>
public void init(H http) {
SecurityContextRepository securityContextRepository = http.getSharedObject(SecurityContextRepository.class);
boolean stateless = isStateless();
if (securityContextRepository == null) {
if (stateless) {
http.setSharedObject(SecurityContextRepository.class, new NullSecurityContextRepository());
@ -332,7 +331,6 @@ public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>
http.setSharedObject(SecurityContextRepository.class, httpSecurityRepository);
}
}
RequestCache requestCache = http.getSharedObject(RequestCache.class);
if (requestCache == null) {
if (stateless) {
@ -365,7 +363,6 @@ public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>
sessionManagementFilter.setTrustResolver(trustResolver);
}
sessionManagementFilter = postProcess(sessionManagementFilter);
http.addFilter(sessionManagementFilter);
if (isConcurrentSessionControlEnabled()) {
ConcurrentSessionFilter concurrentSessionFilter = createConcurrencyFilter(http);
@ -378,13 +375,9 @@ public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>
private ConcurrentSessionFilter createConcurrencyFilter(H http) {
SessionInformationExpiredStrategy expireStrategy = getExpiredSessionStrategy();
SessionRegistry sessionRegistry = getSessionRegistry(http);
ConcurrentSessionFilter concurrentSessionFilter;
if (expireStrategy == null) {
concurrentSessionFilter = new ConcurrentSessionFilter(sessionRegistry);
}
else {
concurrentSessionFilter = new ConcurrentSessionFilter(sessionRegistry, expireStrategy);
}
ConcurrentSessionFilter concurrentSessionFilter = (expireStrategy != null)
? new ConcurrentSessionFilter(sessionRegistry, expireStrategy)
: new ConcurrentSessionFilter(sessionRegistry);
LogoutConfigurer<H> logoutConfigurer = http.getConfigurer(LogoutConfigurer.class);
if (logoutConfigurer != null) {
List<LogoutHandler> logoutHandlers = logoutConfigurer.getLogoutHandlers();
@ -405,11 +398,9 @@ public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>
if (this.invalidSessionStrategy != null) {
return this.invalidSessionStrategy;
}
if (this.invalidSessionUrl == null) {
return null;
}
this.invalidSessionStrategy = new SimpleRedirectInvalidSessionStrategy(this.invalidSessionUrl);
return this.invalidSessionStrategy;
}
@ -418,11 +409,9 @@ public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>
if (this.expiredSessionStrategy != null) {
return this.expiredSessionStrategy;
}
if (this.expiredUrl == null) {
return null;
}
this.expiredSessionStrategy = new SimpleRedirectSessionInformationExpiredStrategy(this.expiredUrl);
return this.expiredSessionStrategy;
}
@ -431,11 +420,9 @@ public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>
if (this.sessionAuthenticationFailureHandler != null) {
return this.sessionAuthenticationFailureHandler;
}
if (this.sessionAuthenticationErrorUrl == null) {
return null;
}
this.sessionAuthenticationFailureHandler = new SimpleUrlAuthenticationFailureHandler(
this.sessionAuthenticationErrorUrl);
return this.sessionAuthenticationFailureHandler;
@ -449,7 +436,6 @@ public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>
if (this.sessionPolicy != null) {
return this.sessionPolicy;
}
SessionCreationPolicy sessionPolicy = getBuilder().getSharedObject(SessionCreationPolicy.class);
return (sessionPolicy != null) ? sessionPolicy : SessionCreationPolicy.IF_REQUIRED;
}
@ -628,6 +614,9 @@ public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>
*/
public final class ConcurrencyControlConfigurer {
private ConcurrencyControlConfigurer() {
}
/**
* Controls the maximum number of sessions for a user. The default is to allow any
* number of users.
@ -699,9 +688,6 @@ public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>
return SessionManagementConfigurer.this;
}
private ConcurrencyControlConfigurer() {
}
}
}

View File

@ -89,10 +89,10 @@ import org.springframework.util.Assert;
public final class UrlAuthorizationConfigurer<H extends HttpSecurityBuilder<H>>
extends AbstractInterceptUrlConfigurer<UrlAuthorizationConfigurer<H>, H> {
private final StandardInterceptUrlRegistry REGISTRY;
private final StandardInterceptUrlRegistry registry;
public UrlAuthorizationConfigurer(ApplicationContext context) {
this.REGISTRY = new StandardInterceptUrlRegistry(context);
this.registry = new StandardInterceptUrlRegistry(context);
}
/**
@ -101,7 +101,7 @@ public final class UrlAuthorizationConfigurer<H extends HttpSecurityBuilder<H>>
* @return the {@link ExpressionUrlAuthorizationConfigurer} for further customizations
*/
public StandardInterceptUrlRegistry getRegistry() {
return this.REGISTRY;
return this.registry;
}
/**
@ -136,7 +136,7 @@ public final class UrlAuthorizationConfigurer<H extends HttpSecurityBuilder<H>>
*/
@Override
FilterInvocationSecurityMetadataSource createMetadataSource(H http) {
return new DefaultFilterInvocationSecurityMetadataSource(this.REGISTRY.createRequestMap());
return new DefaultFilterInvocationSecurityMetadataSource(this.registry.createRequestMap());
}
/**
@ -151,10 +151,10 @@ public final class UrlAuthorizationConfigurer<H extends HttpSecurityBuilder<H>>
private StandardInterceptUrlRegistry addMapping(Iterable<? extends RequestMatcher> requestMatchers,
Collection<ConfigAttribute> configAttributes) {
for (RequestMatcher requestMatcher : requestMatchers) {
this.REGISTRY.addMapping(
this.registry.addMapping(
new AbstractConfigAttributeRequestMatcherRegistry.UrlMapping(requestMatcher, configAttributes));
}
return this.REGISTRY;
return this.registry;
}
/**
@ -196,9 +196,6 @@ public final class UrlAuthorizationConfigurer<H extends HttpSecurityBuilder<H>>
public final class StandardInterceptUrlRegistry extends
ExpressionUrlAuthorizationConfigurer<H>.AbstractInterceptUrlRegistry<StandardInterceptUrlRegistry, AuthorizedUrl> {
/**
* @param context
*/
private StandardInterceptUrlRegistry(ApplicationContext context) {
setApplicationContext(context);
}
@ -337,7 +334,7 @@ public final class UrlAuthorizationConfigurer<H extends HttpSecurityBuilder<H>>
*/
public StandardInterceptUrlRegistry access(String... attributes) {
addMapping(this.requestMatchers, SecurityConfig.createList(attributes));
return UrlAuthorizationConfigurer.this.REGISTRY;
return UrlAuthorizationConfigurer.this.registry;
}
protected List<? extends RequestMatcher> getMatchers() {

View File

@ -171,12 +171,8 @@ public final class X509Configurer<H extends HttpSecurityBuilder<H>>
public void init(H http) {
PreAuthenticatedAuthenticationProvider authenticationProvider = new PreAuthenticatedAuthenticationProvider();
authenticationProvider.setPreAuthenticatedUserDetailsService(getAuthenticationUserDetailsService(http));
// @formatter:off
http
.authenticationProvider(authenticationProvider)
.setSharedObject(AuthenticationEntryPoint.class, new Http403ForbiddenEntryPoint());
// @formatter:on
http.authenticationProvider(authenticationProvider).setSharedObject(AuthenticationEntryPoint.class,
new Http403ForbiddenEntryPoint());
}
@Override

View File

@ -197,7 +197,6 @@ public final class OAuth2ClientConfigurer<B extends HttpSecurityBuilder<B>>
*/
public AuthorizationCodeGrantConfigurer authorizationRequestRepository(
AuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository) {
Assert.notNull(authorizationRequestRepository, "authorizationRequestRepository cannot be null");
this.authorizationRequestRepository = authorizationRequestRepository;
return this;
@ -212,7 +211,6 @@ public final class OAuth2ClientConfigurer<B extends HttpSecurityBuilder<B>>
*/
public AuthorizationCodeGrantConfigurer accessTokenResponseClient(
OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient) {
Assert.notNull(accessTokenResponseClient, "accessTokenResponseClient cannot be null");
this.accessTokenResponseClient = accessTokenResponseClient;
return this;
@ -245,7 +243,6 @@ public final class OAuth2ClientConfigurer<B extends HttpSecurityBuilder<B>>
OAuth2AuthorizationRequestResolver resolver = getAuthorizationRequestResolver();
OAuth2AuthorizationRequestRedirectFilter authorizationRequestRedirectFilter = new OAuth2AuthorizationRequestRedirectFilter(
resolver);
if (this.authorizationRequestRepository != null) {
authorizationRequestRedirectFilter
.setAuthorizationRequestRepository(this.authorizationRequestRepository);
@ -272,7 +269,6 @@ public final class OAuth2ClientConfigurer<B extends HttpSecurityBuilder<B>>
OAuth2AuthorizationCodeGrantFilter authorizationCodeGrantFilter = new OAuth2AuthorizationCodeGrantFilter(
OAuth2ClientConfigurerUtils.getClientRegistrationRepository(builder),
OAuth2ClientConfigurerUtils.getAuthorizedClientRepository(builder), authenticationManager);
if (this.authorizationRequestRepository != null) {
authorizationCodeGrantFilter.setAuthorizationRequestRepository(this.authorizationRequestRepository);
}

View File

@ -291,7 +291,6 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
OAuth2ClientConfigurerUtils.getAuthorizedClientRepository(this.getBuilder()), this.loginProcessingUrl);
this.setAuthenticationFilter(authenticationFilter);
super.loginProcessingUrl(this.loginProcessingUrl);
if (this.loginPage != null) {
// Set custom login page
super.loginPage(this.loginPage);
@ -311,12 +310,10 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
super.init(http);
}
}
OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient = this.tokenEndpointConfig.accessTokenResponseClient;
if (accessTokenResponseClient == null) {
accessTokenResponseClient = new DefaultAuthorizationCodeTokenResponseClient();
}
OAuth2UserService<OAuth2UserRequest, OAuth2User> oauth2UserService = getOAuth2UserService();
OAuth2LoginAuthenticationProvider oauth2LoginAuthenticationProvider = new OAuth2LoginAuthenticationProvider(
accessTokenResponseClient, oauth2UserService);
@ -325,10 +322,8 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
oauth2LoginAuthenticationProvider.setAuthoritiesMapper(userAuthoritiesMapper);
}
http.authenticationProvider(this.postProcess(oauth2LoginAuthenticationProvider));
boolean oidcAuthenticationProviderEnabled = ClassUtils
.isPresent("org.springframework.security.oauth2.jwt.JwtDecoder", this.getClass().getClassLoader());
if (oidcAuthenticationProviderEnabled) {
OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService = getOidcUserService();
OidcAuthorizationCodeAuthenticationProvider oidcAuthorizationCodeAuthenticationProvider = new OidcAuthorizationCodeAuthenticationProvider(
@ -345,14 +340,12 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
else {
http.authenticationProvider(new OidcAuthenticationRequestChecker());
}
this.initDefaultLoginFilter(http);
}
@Override
public void configure(B http) throws Exception {
OAuth2AuthorizationRequestRedirectFilter authorizationRequestFilter;
if (this.authorizationEndpointConfig.authorizationRequestResolver != null) {
authorizationRequestFilter = new OAuth2AuthorizationRequestRedirectFilter(
this.authorizationEndpointConfig.authorizationRequestResolver);
@ -366,7 +359,6 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
OAuth2ClientConfigurerUtils.getClientRegistrationRepository(this.getBuilder()),
authorizationRequestBaseUri);
}
if (this.authorizationEndpointConfig.authorizationRequestRepository != null) {
authorizationRequestFilter
.setAuthorizationRequestRepository(this.authorizationEndpointConfig.authorizationRequestRepository);
@ -376,7 +368,6 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
authorizationRequestFilter.setRequestCache(requestCache);
}
http.addFilter(this.postProcess(authorizationRequestFilter));
OAuth2LoginAuthenticationFilter authenticationFilter = this.getAuthenticationFilter();
if (this.redirectionEndpointConfig.authorizationResponseBaseUri != null) {
authenticationFilter.setFilterProcessesUrl(this.redirectionEndpointConfig.authorizationResponseBaseUri);
@ -433,11 +424,7 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
ResolvableType type = ResolvableType.forClassWithGenerics(OAuth2UserService.class, OidcUserRequest.class,
OidcUser.class);
OAuth2UserService<OidcUserRequest, OidcUser> bean = getBeanOrNull(type);
if (bean == null) {
return new OidcUserService();
}
return bean;
return (bean != null) ? bean : new OidcUserService();
}
private OAuth2UserService<OAuth2UserRequest, OAuth2User> getOAuth2UserService() {
@ -447,29 +434,25 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
ResolvableType type = ResolvableType.forClassWithGenerics(OAuth2UserService.class, OAuth2UserRequest.class,
OAuth2User.class);
OAuth2UserService<OAuth2UserRequest, OAuth2User> bean = getBeanOrNull(type);
if (bean == null) {
if (!this.userInfoEndpointConfig.customUserTypes.isEmpty()) {
List<OAuth2UserService<OAuth2UserRequest, OAuth2User>> userServices = new ArrayList<>();
userServices.add(new CustomUserTypesOAuth2UserService(this.userInfoEndpointConfig.customUserTypes));
userServices.add(new DefaultOAuth2UserService());
return new DelegatingOAuth2UserService<>(userServices);
}
else {
return new DefaultOAuth2UserService();
}
if (bean != null) {
return bean;
}
return bean;
if (this.userInfoEndpointConfig.customUserTypes.isEmpty()) {
return new DefaultOAuth2UserService();
}
List<OAuth2UserService<OAuth2UserRequest, OAuth2User>> userServices = new ArrayList<>();
userServices.add(new CustomUserTypesOAuth2UserService(this.userInfoEndpointConfig.customUserTypes));
userServices.add(new DefaultOAuth2UserService());
return new DelegatingOAuth2UserService<>(userServices);
}
private <T> T getBeanOrNull(ResolvableType type) {
ApplicationContext context = getBuilder().getSharedObject(ApplicationContext.class);
if (context == null) {
return null;
}
String[] names = context.getBeanNamesForType(type);
if (names.length == 1) {
return (T) context.getBean(names[0]);
if (context != null) {
String[] names = context.getBeanNamesForType(type);
if (names.length == 1) {
return (T) context.getBean(names[0]);
}
}
return null;
}
@ -480,7 +463,6 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
if (loginPageGeneratingFilter == null || this.isCustomLoginPage()) {
return;
}
loginPageGeneratingFilter.setOauth2LoginEnabled(true);
loginPageGeneratingFilter.setOauth2AuthenticationUrlToClientName(this.getLoginLinks());
loginPageGeneratingFilter.setLoginPageUrl(this.getLoginPage());
@ -499,14 +481,12 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
if (clientRegistrations == null) {
return Collections.emptyMap();
}
String authorizationRequestBaseUri = (this.authorizationEndpointConfig.authorizationRequestBaseUri != null)
? this.authorizationEndpointConfig.authorizationRequestBaseUri
: OAuth2AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI;
Map<String, String> loginUrlToClientName = new HashMap<>();
clientRegistrations.forEach((registration) -> loginUrlToClientName.put(
authorizationRequestBaseUri + "/" + registration.getRegistrationId(), registration.getClientName()));
return loginUrlToClientName;
}
@ -516,17 +496,13 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
RequestMatcher defaultEntryPointMatcher = this.getAuthenticationEntryPointMatcher(http);
RequestMatcher defaultLoginPageMatcher = new AndRequestMatcher(
new OrRequestMatcher(loginPageMatcher, faviconMatcher), defaultEntryPointMatcher);
RequestMatcher notXRequestedWith = new NegatedRequestMatcher(
new RequestHeaderRequestMatcher("X-Requested-With", "XMLHttpRequest"));
LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> entryPoints = new LinkedHashMap<>();
entryPoints.put(new AndRequestMatcher(notXRequestedWith, new NegatedRequestMatcher(defaultLoginPageMatcher)),
new LoginUrlAuthenticationEntryPoint(providerLoginPage));
DelegatingAuthenticationEntryPoint loginEntryPoint = new DelegatingAuthenticationEntryPoint(entryPoints);
loginEntryPoint.setDefaultEntryPoint(this.getAuthenticationEntryPoint());
return loginEntryPoint;
}
@ -612,7 +588,6 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
*/
public TokenEndpointConfig accessTokenResponseClient(
OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient) {
Assert.notNull(accessTokenResponseClient, "accessTokenResponseClient cannot be null");
this.accessTokenResponseClient = accessTokenResponseClient;
return this;
@ -746,21 +721,19 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
OAuth2LoginAuthenticationToken authorizationCodeAuthentication = (OAuth2LoginAuthenticationToken) authentication;
// Section 3.1.2.1 Authentication Request -
// https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
// scope
// REQUIRED. OpenID Connect requests MUST contain the "openid" scope value.
if (authorizationCodeAuthentication.getAuthorizationExchange().getAuthorizationRequest().getScopes()
.contains(OidcScopes.OPENID)) {
OAuth2AuthorizationRequest authorizationRequest = authorizationCodeAuthentication.getAuthorizationExchange()
.getAuthorizationRequest();
if (authorizationRequest.getScopes().contains(OidcScopes.OPENID)) {
// Section 3.1.2.1 Authentication Request -
// https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest scope
// REQUIRED. OpenID Connect requests MUST contain the "openid" scope
// value.
OAuth2Error oauth2Error = new OAuth2Error("oidc_provider_not_configured",
"An OpenID Connect Authentication Provider has not been configured. "
+ "Check to ensure you include the dependency 'spring-security-oauth2-jose'.",
null);
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
}
return null;
}

View File

@ -180,7 +180,6 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
if (this.jwtConfigurer == null) {
this.jwtConfigurer = new JwtConfigurer(this.context);
}
return this.jwtConfigurer;
}
@ -202,7 +201,6 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
if (this.opaqueTokenConfigurer == null) {
this.opaqueTokenConfigurer = new OpaqueTokenConfigurer(this.context);
}
return this.opaqueTokenConfigurer;
}
@ -223,11 +221,9 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
@Override
public void init(H http) {
validateConfiguration();
registerDefaultAccessDeniedHandler(http);
registerDefaultEntryPoint(http);
registerDefaultCsrfOverride(http);
AuthenticationProvider authenticationProvider = getAuthenticationProvider();
if (authenticationProvider != null) {
http.authenticationProvider(authenticationProvider);
@ -238,79 +234,63 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
public void configure(H http) {
BearerTokenResolver bearerTokenResolver = getBearerTokenResolver();
this.requestMatcher.setBearerTokenResolver(bearerTokenResolver);
AuthenticationManagerResolver resolver = this.authenticationManagerResolver;
if (resolver == null) {
AuthenticationManager authenticationManager = getAuthenticationManager(http);
resolver = (request) -> authenticationManager;
}
BearerTokenAuthenticationFilter filter = new BearerTokenAuthenticationFilter(resolver);
filter.setBearerTokenResolver(bearerTokenResolver);
filter.setAuthenticationEntryPoint(this.authenticationEntryPoint);
filter = postProcess(filter);
http.addFilter(filter);
}
private void validateConfiguration() {
if (this.authenticationManagerResolver == null) {
if (this.jwtConfigurer == null && this.opaqueTokenConfigurer == null) {
throw new IllegalStateException("Jwt and Opaque Token are the only supported formats for bearer tokens "
+ "in Spring Security and neither was found. Make sure to configure JWT "
+ "via http.oauth2ResourceServer().jwt() or Opaque Tokens via "
+ "http.oauth2ResourceServer().opaqueToken().");
}
if (this.jwtConfigurer != null && this.opaqueTokenConfigurer != null) {
throw new IllegalStateException(
"Spring Security only supports JWTs or Opaque Tokens, not both at the " + "same time.");
}
Assert.state(this.jwtConfigurer != null || this.opaqueTokenConfigurer != null,
"Jwt and Opaque Token are the only supported formats for bearer tokens "
+ "in Spring Security and neither was found. Make sure to configure JWT "
+ "via http.oauth2ResourceServer().jwt() or Opaque Tokens via "
+ "http.oauth2ResourceServer().opaqueToken().");
Assert.state(this.jwtConfigurer == null || this.opaqueTokenConfigurer == null,
"Spring Security only supports JWTs or Opaque Tokens, not both at the " + "same time.");
}
else {
if (this.jwtConfigurer != null || this.opaqueTokenConfigurer != null) {
throw new IllegalStateException("If an authenticationManagerResolver() is configured, then it takes "
+ "precedence over any jwt() or opaqueToken() configuration.");
}
Assert.state(this.jwtConfigurer == null && this.opaqueTokenConfigurer == null,
"If an authenticationManagerResolver() is configured, then it takes "
+ "precedence over any jwt() or opaqueToken() configuration.");
}
}
private void registerDefaultAccessDeniedHandler(H http) {
ExceptionHandlingConfigurer<H> exceptionHandling = http.getConfigurer(ExceptionHandlingConfigurer.class);
if (exceptionHandling == null) {
return;
if (exceptionHandling != null) {
exceptionHandling.defaultAccessDeniedHandlerFor(this.accessDeniedHandler, this.requestMatcher);
}
exceptionHandling.defaultAccessDeniedHandlerFor(this.accessDeniedHandler, this.requestMatcher);
}
private void registerDefaultEntryPoint(H http) {
ExceptionHandlingConfigurer<H> exceptionHandling = http.getConfigurer(ExceptionHandlingConfigurer.class);
if (exceptionHandling == null) {
return;
if (exceptionHandling != null) {
exceptionHandling.defaultAuthenticationEntryPointFor(this.authenticationEntryPoint, this.requestMatcher);
}
exceptionHandling.defaultAuthenticationEntryPointFor(this.authenticationEntryPoint, this.requestMatcher);
}
private void registerDefaultCsrfOverride(H http) {
CsrfConfigurer<H> csrf = http.getConfigurer(CsrfConfigurer.class);
if (csrf == null) {
return;
if (csrf != null) {
csrf.ignoringRequestMatchers(this.requestMatcher);
}
csrf.ignoringRequestMatchers(this.requestMatcher);
}
AuthenticationProvider getAuthenticationProvider() {
if (this.jwtConfigurer != null) {
return this.jwtConfigurer.getAuthenticationProvider();
}
if (this.opaqueTokenConfigurer != null) {
return this.opaqueTokenConfigurer.getAuthenticationProvider();
}
return null;
}
@ -318,11 +298,9 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
if (this.jwtConfigurer != null) {
return this.jwtConfigurer.getAuthenticationManager(http);
}
if (this.opaqueTokenConfigurer != null) {
return this.opaqueTokenConfigurer.getAuthenticationManager(http);
}
return http.getSharedObject(AuthenticationManager.class);
}
@ -335,7 +313,6 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
this.bearerTokenResolver = new DefaultBearerTokenResolver();
}
}
return this.bearerTokenResolver;
}
@ -371,7 +348,6 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
public JwtConfigurer jwtAuthenticationConverter(
Converter<Jwt, ? extends AbstractAuthenticationToken> jwtAuthenticationConverter) {
this.jwtAuthenticationConverter = jwtAuthenticationConverter;
return this;
}
@ -389,7 +365,6 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
this.jwtAuthenticationConverter = new JwtAuthenticationConverter();
}
}
return this.jwtAuthenticationConverter;
}
@ -397,7 +372,6 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
if (this.decoder == null) {
return this.context.getBean(JwtDecoder.class);
}
return this.decoder;
}
@ -405,10 +379,8 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
if (this.authenticationManager != null) {
return null;
}
JwtDecoder decoder = getJwtDecoder();
Converter<Jwt, ? extends AbstractAuthenticationToken> jwtAuthenticationConverter = getJwtAuthenticationConverter();
JwtAuthenticationProvider provider = new JwtAuthenticationProvider(decoder);
provider.setJwtAuthenticationConverter(jwtAuthenticationConverter);
return postProcess(provider);
@ -418,7 +390,6 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
if (this.authenticationManager != null) {
return this.authenticationManager;
}
return http.getSharedObject(AuthenticationManager.class);
}
@ -491,7 +462,6 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
if (this.authenticationManager != null) {
return this.authenticationManager;
}
return http.getSharedObject(AuthenticationManager.class);
}

View File

@ -280,12 +280,10 @@ public final class OpenIDLoginConfigurer<H extends HttpSecurityBuilder<H>>
@Override
public void init(H http) throws Exception {
super.init(http);
OpenIDAuthenticationProvider authenticationProvider = new OpenIDAuthenticationProvider();
authenticationProvider.setAuthenticationUserDetailsService(getAuthenticationUserDetailsService(http));
authenticationProvider = postProcess(authenticationProvider);
http.authenticationProvider(authenticationProvider);
initDefaultLoginFilter(http);
}

View File

@ -160,9 +160,6 @@ public final class Saml2LoginConfigurer<B extends HttpSecurityBuilder<B>>
return this;
}
/**
* {@inheritDoc}
*/
@Override
public Saml2LoginConfigurer<B> loginPage(String loginPage) {
Assert.hasText(loginPage, "loginPage cannot be empty");
@ -170,9 +167,6 @@ public final class Saml2LoginConfigurer<B extends HttpSecurityBuilder<B>>
return this;
}
/**
* {@inheritDoc}
*/
@Override
public Saml2LoginConfigurer<B> loginProcessingUrl(String loginProcessingUrl) {
Assert.hasText(loginProcessingUrl, "loginProcessingUrl cannot be empty");
@ -181,9 +175,6 @@ public final class Saml2LoginConfigurer<B extends HttpSecurityBuilder<B>>
return this;
}
/**
* {@inheritDoc}
*/
@Override
protected RequestMatcher createLoginProcessingUrlMatcher(String loginProcessingUrl) {
return new AntPathRequestMatcher(loginProcessingUrl);
@ -208,28 +199,24 @@ public final class Saml2LoginConfigurer<B extends HttpSecurityBuilder<B>>
if (this.relyingPartyRegistrationRepository == null) {
this.relyingPartyRegistrationRepository = getSharedOrBean(http, RelyingPartyRegistrationRepository.class);
}
this.saml2WebSsoAuthenticationFilter = new Saml2WebSsoAuthenticationFilter(getAuthenticationConverter(http),
this.loginProcessingUrl);
setAuthenticationFilter(this.saml2WebSsoAuthenticationFilter);
super.loginProcessingUrl(this.loginProcessingUrl);
if (StringUtils.hasText(this.loginPage)) {
// Set custom login page
super.loginPage(this.loginPage);
super.init(http);
}
else {
final Map<String, String> providerUrlMap = getIdentityProviderUrlMap(
Map<String, String> providerUrlMap = getIdentityProviderUrlMap(
this.authenticationRequestEndpoint.filterProcessingUrl, this.relyingPartyRegistrationRepository);
boolean singleProvider = providerUrlMap.size() == 1;
if (singleProvider) {
// Setup auto-redirect to provider login page
// when only 1 IDP is configured
this.updateAuthenticationDefaults();
this.updateAccessDefaults(http);
String loginUrl = providerUrlMap.entrySet().iterator().next().getKey();
final LoginUrlAuthenticationEntryPoint entryPoint = new LoginUrlAuthenticationEntryPoint(loginUrl);
registerAuthenticationEntryPoint(http, entryPoint);
@ -238,7 +225,6 @@ public final class Saml2LoginConfigurer<B extends HttpSecurityBuilder<B>>
super.init(http);
}
}
this.initDefaultLoginFilter(http);
}
@ -279,7 +265,6 @@ public final class Saml2LoginConfigurer<B extends HttpSecurityBuilder<B>>
if (csrf == null) {
return;
}
csrf.ignoringRequestMatchers(new AntPathRequestMatcher(this.loginProcessingUrl));
}
@ -289,7 +274,6 @@ public final class Saml2LoginConfigurer<B extends HttpSecurityBuilder<B>>
if (loginPageGeneratingFilter == null || this.isCustomLoginPage()) {
return;
}
loginPageGeneratingFilter.setSaml2LoginEnabled(true);
loginPageGeneratingFilter.setSaml2AuthenticationUrlToProviderName(this.getIdentityProviderUrlMap(
this.authenticationRequestEndpoint.filterProcessingUrl, this.relyingPartyRegistrationRepository));
@ -326,8 +310,8 @@ public final class Saml2LoginConfigurer<B extends HttpSecurityBuilder<B>>
return context.getBean(clazz);
}
catch (NoSuchBeanDefinitionException ex) {
return null;
}
return null;
}
private <C> void setSharedObject(B http, Class<C> clazz, C object) {
@ -346,7 +330,6 @@ public final class Saml2LoginConfigurer<B extends HttpSecurityBuilder<B>>
private Filter build(B http) {
Saml2AuthenticationRequestFactory authenticationRequestResolver = getResolver(http);
Saml2AuthenticationRequestContextResolver contextResolver = getContextResolver(http);
return postProcess(
new Saml2WebSsoAuthenticationRequestFilter(contextResolver, authenticationRequestResolver));
}

View File

@ -442,11 +442,11 @@ public class MessageSecurityMetadataSourceRegistry {
return new SimpDestinationMessageMatcher(this.pattern,
MessageSecurityMetadataSourceRegistry.this.pathMatcher);
}
else if (SimpMessageType.MESSAGE == this.type) {
if (SimpMessageType.MESSAGE == this.type) {
return SimpDestinationMessageMatcher.createMessageMatcher(this.pattern,
MessageSecurityMetadataSourceRegistry.this.pathMatcher);
}
else if (SimpMessageType.SUBSCRIBE == this.type) {
if (SimpMessageType.SUBSCRIBE == this.type) {
return SimpDestinationMessageMatcher.createSubscribeMatcher(this.pattern,
MessageSecurityMetadataSourceRegistry.this.pathMatcher);
}

View File

@ -47,13 +47,12 @@ final class ReactiveOAuth2ClientImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
boolean oauth2ClientPresent = ClassUtils.isPresent(
"org.springframework.security.oauth2.client.registration.ClientRegistration",
getClass().getClassLoader());
return oauth2ClientPresent ? new String[] {
"org.springframework.security.config.annotation.web.reactive.ReactiveOAuth2ClientImportSelector$OAuth2ClientWebFluxSecurityConfiguration" }
: new String[] {};
if (!ClassUtils.isPresent("org.springframework.security.oauth2.client.registration.ClientRegistration",
getClass().getClassLoader())) {
return new String[0];
}
return new String[] { "org.springframework.security.config.annotation.web.reactive."
+ "ReactiveOAuth2ClientImportSelector$OAuth2ClientWebFluxSecurityConfiguration" };
}
@Configuration(proxyBeanMethods = false)

View File

@ -98,23 +98,14 @@ class WebFluxSecurityConfiguration {
* @return
*/
private SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
// @formatter:off
http
.authorizeExchange()
.anyExchange().authenticated();
// @formatter:on
http.authorizeExchange().anyExchange().authenticated();
if (isOAuth2Present && OAuth2ClasspathGuard.shouldConfigure(this.context)) {
OAuth2ClasspathGuard.configure(this.context, http);
}
else {
// @formatter:off
http
.httpBasic().and()
.formLogin();
// @formatter:on
http.httpBasic();
http.formLogin();
}
SecurityWebFilterChain result = http.build();
return result;
}
@ -122,11 +113,8 @@ class WebFluxSecurityConfiguration {
private static class OAuth2ClasspathGuard {
static void configure(ApplicationContext context, ServerHttpSecurity http) {
// @formatter:off
http
.oauth2Login().and()
.oauth2Client();
// @formatter:on
http.oauth2Login();
http.oauth2Client();
}
static boolean shouldConfigure(ApplicationContext context) {

View File

@ -47,6 +47,7 @@ import org.springframework.security.messaging.context.SecurityContextChannelInte
import org.springframework.security.messaging.web.csrf.CsrfChannelInterceptor;
import org.springframework.security.messaging.web.socket.server.CsrfTokenHandshakeInterceptor;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.Assert;
import org.springframework.util.PathMatcher;
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
@ -160,10 +161,8 @@ public abstract class AbstractSecurityWebSocketMessageBrokerConfigurer extends A
messageSecurityMetadataSource);
MessageExpressionVoter<Object> voter = new MessageExpressionVoter<>();
voter.setExpressionHandler(getMessageExpressionHandler());
List<AccessDecisionVoter<?>> voters = new ArrayList<>();
voters.add(voter);
AffirmativeBased manager = new AffirmativeBased(voters);
channelSecurityInterceptor.setAccessDecisionManager(manager);
return channelSecurityInterceptor;
@ -221,50 +220,47 @@ public abstract class AbstractSecurityWebSocketMessageBrokerConfigurer extends A
if (sameOriginDisabled()) {
return;
}
String beanName = "stompWebSocketHandlerMapping";
SimpleUrlHandlerMapping mapping = this.context.getBean(beanName, SimpleUrlHandlerMapping.class);
Map<String, Object> mappings = mapping.getHandlerMap();
for (Object object : mappings.values()) {
if (object instanceof SockJsHttpRequestHandler) {
SockJsHttpRequestHandler sockjsHandler = (SockJsHttpRequestHandler) object;
SockJsService sockJsService = sockjsHandler.getSockJsService();
if (!(sockJsService instanceof TransportHandlingSockJsService)) {
throw new IllegalStateException(
"sockJsService must be instance of TransportHandlingSockJsService got " + sockJsService);
}
TransportHandlingSockJsService transportHandlingSockJsService = (TransportHandlingSockJsService) sockJsService;
List<HandshakeInterceptor> handshakeInterceptors = transportHandlingSockJsService
.getHandshakeInterceptors();
List<HandshakeInterceptor> interceptorsToSet = new ArrayList<>(handshakeInterceptors.size() + 1);
interceptorsToSet.add(new CsrfTokenHandshakeInterceptor());
interceptorsToSet.addAll(handshakeInterceptors);
transportHandlingSockJsService.setHandshakeInterceptors(interceptorsToSet);
setHandshakeInterceptors((SockJsHttpRequestHandler) object);
}
else if (object instanceof WebSocketHttpRequestHandler) {
WebSocketHttpRequestHandler handler = (WebSocketHttpRequestHandler) object;
List<HandshakeInterceptor> handshakeInterceptors = handler.getHandshakeInterceptors();
List<HandshakeInterceptor> interceptorsToSet = new ArrayList<>(handshakeInterceptors.size() + 1);
interceptorsToSet.add(new CsrfTokenHandshakeInterceptor());
interceptorsToSet.addAll(handshakeInterceptors);
handler.setHandshakeInterceptors(interceptorsToSet);
setHandshakeInterceptors((WebSocketHttpRequestHandler) object);
}
else {
throw new IllegalStateException("Bean " + beanName
+ " is expected to contain mappings to either a SockJsHttpRequestHandler or a WebSocketHttpRequestHandler but got "
+ object);
throw new IllegalStateException("Bean " + beanName + " is expected to contain mappings to either a "
+ "SockJsHttpRequestHandler or a WebSocketHttpRequestHandler but got " + object);
}
}
if (this.inboundRegistry.containsMapping() && !this.inboundRegistry.isSimpDestPathMatcherConfigured()) {
PathMatcher pathMatcher = getDefaultPathMatcher();
this.inboundRegistry.simpDestPathMatcher(pathMatcher);
}
}
private void setHandshakeInterceptors(SockJsHttpRequestHandler handler) {
SockJsService sockJsService = handler.getSockJsService();
Assert.state(sockJsService instanceof TransportHandlingSockJsService,
() -> "sockJsService must be instance of TransportHandlingSockJsService got " + sockJsService);
TransportHandlingSockJsService transportHandlingSockJsService = (TransportHandlingSockJsService) sockJsService;
List<HandshakeInterceptor> handshakeInterceptors = transportHandlingSockJsService.getHandshakeInterceptors();
List<HandshakeInterceptor> interceptorsToSet = new ArrayList<>(handshakeInterceptors.size() + 1);
interceptorsToSet.add(new CsrfTokenHandshakeInterceptor());
interceptorsToSet.addAll(handshakeInterceptors);
transportHandlingSockJsService.setHandshakeInterceptors(interceptorsToSet);
}
private void setHandshakeInterceptors(WebSocketHttpRequestHandler handler) {
List<HandshakeInterceptor> handshakeInterceptors = handler.getHandshakeInterceptors();
List<HandshakeInterceptor> interceptorsToSet = new ArrayList<>(handshakeInterceptors.size() + 1);
interceptorsToSet.add(new CsrfTokenHandshakeInterceptor());
interceptorsToSet.addAll(handshakeInterceptors);
handler.setHandshakeInterceptors(interceptorsToSet);
}
private static class WebSocketMessageSecurityMetadataSourceRegistry extends MessageSecurityMetadataSourceRegistry {
@Override

View File

@ -47,36 +47,27 @@ public abstract class AbstractUserDetailsServiceBeanDefinitionParser implements
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(getBeanClassName(element));
doParse(element, parserContext, builder);
RootBeanDefinition userService = (RootBeanDefinition) builder.getBeanDefinition();
final String beanId = resolveId(element, userService, parserContext);
String beanId = resolveId(element, userService, parserContext);
parserContext.registerBeanComponent(new BeanComponentDefinition(userService, beanId));
String cacheRef = element.getAttribute(CACHE_REF);
// Register a caching version of the user service if there's a cache-ref
if (StringUtils.hasText(cacheRef)) {
BeanDefinitionBuilder cachingUSBuilder = BeanDefinitionBuilder
.rootBeanDefinition(CachingUserDetailsService.class);
cachingUSBuilder.addConstructorArgReference(beanId);
cachingUSBuilder.addPropertyValue("userCache", new RuntimeBeanReference(cacheRef));
BeanDefinition cachingUserService = cachingUSBuilder.getBeanDefinition();
parserContext
.registerBeanComponent(new BeanComponentDefinition(cachingUserService, beanId + CACHING_SUFFIX));
}
return null;
}
private String resolveId(Element element, AbstractBeanDefinition definition, ParserContext pc)
throws BeanDefinitionStoreException {
String id = element.getAttribute("id");
if (pc.isNested()) {
// We're inside an <authentication-provider> element
if (!StringUtils.hasText(id)) {
@ -85,17 +76,14 @@ public abstract class AbstractUserDetailsServiceBeanDefinitionParser implements
BeanDefinition container = pc.getContainingBeanDefinition();
container.getPropertyValues().add("userDetailsService", new RuntimeBeanReference(id));
}
if (StringUtils.hasText(id)) {
return id;
}
// If top level, use the default name or throw an exception if already used
if (pc.getRegistry().containsBeanDefinition(BeanIds.USER_DETAILS_SERVICE)) {
throw new BeanDefinitionStoreException(
"No id supplied and another " + "bean is already registered as " + BeanIds.USER_DETAILS_SERVICE);
"No id supplied and another bean is already registered as " + BeanIds.USER_DETAILS_SERVICE);
}
return BeanIds.USER_DETAILS_SERVICE;
}

View File

@ -60,7 +60,6 @@ public class AuthenticationManagerBeanDefinitionParser implements BeanDefinition
@Override
public BeanDefinition parse(Element element, ParserContext pc) {
String id = element.getAttribute("id");
if (!StringUtils.hasText(id)) {
if (pc.getRegistry().containsBeanDefinition(BeanIds.AUTHENTICATION_MANAGER)) {
pc.getReaderContext().warning("Overriding globally registered AuthenticationManager",
@ -69,65 +68,30 @@ public class AuthenticationManagerBeanDefinitionParser implements BeanDefinition
id = BeanIds.AUTHENTICATION_MANAGER;
}
pc.pushContainingComponent(new CompositeComponentDefinition(element.getTagName(), pc.extractSource(element)));
BeanDefinitionBuilder providerManagerBldr = BeanDefinitionBuilder.rootBeanDefinition(ProviderManager.class);
String alias = element.getAttribute(ATT_ALIAS);
List<BeanMetadataElement> providers = new ManagedList<>();
NamespaceHandlerResolver resolver = pc.getReaderContext().getNamespaceHandlerResolver();
NodeList children = element.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node node = children.item(i);
if (node instanceof Element) {
Element providerElt = (Element) node;
if (StringUtils.hasText(providerElt.getAttribute(ATT_REF))) {
if (providerElt.getAttributes().getLength() > 1) {
pc.getReaderContext()
.error("authentication-provider element cannot be used with other attributes "
+ "when using 'ref' attribute", pc.extractSource(element));
}
NodeList providerChildren = providerElt.getChildNodes();
for (int j = 0; j < providerChildren.getLength(); j++) {
if (providerChildren.item(j) instanceof Element) {
pc.getReaderContext()
.error("authentication-provider element cannot have child elements when used "
+ "with 'ref' attribute", pc.extractSource(element));
}
}
providers.add(new RuntimeBeanReference(providerElt.getAttribute(ATT_REF)));
}
else {
BeanDefinition provider = resolver.resolve(providerElt.getNamespaceURI()).parse(providerElt, pc);
Assert.notNull(provider,
() -> "Parser for " + providerElt.getNodeName() + " returned a null bean definition");
String providerId = pc.getReaderContext().generateBeanName(provider);
pc.registerBeanComponent(new BeanComponentDefinition(provider, providerId));
providers.add(new RuntimeBeanReference(providerId));
}
providers.add(extracted(element, pc, resolver, (Element) node));
}
}
if (providers.isEmpty()) {
providers.add(new RootBeanDefinition(NullAuthenticationProvider.class));
}
providerManagerBldr.addConstructorArgValue(providers);
if ("false".equals(element.getAttribute(ATT_ERASE_CREDENTIALS))) {
providerManagerBldr.addPropertyValue("eraseCredentialsAfterAuthentication", false);
}
// Add the default event publisher
BeanDefinition publisher = new RootBeanDefinition(DefaultAuthenticationEventPublisher.class);
String pubId = pc.getReaderContext().generateBeanName(publisher);
pc.registerBeanComponent(new BeanComponentDefinition(publisher, pubId));
providerManagerBldr.addPropertyReference("authenticationEventPublisher", pubId);
pc.registerBeanComponent(new BeanComponentDefinition(providerManagerBldr.getBeanDefinition(), id));
if (StringUtils.hasText(alias)) {
pc.getRegistry().registerAlias(id, alias);
pc.getReaderContext().fireAliasRegistered(id, alias, pc.extractSource(element));
@ -136,12 +100,35 @@ public class AuthenticationManagerBeanDefinitionParser implements BeanDefinition
pc.getRegistry().registerAlias(id, BeanIds.AUTHENTICATION_MANAGER);
pc.getReaderContext().fireAliasRegistered(id, BeanIds.AUTHENTICATION_MANAGER, pc.extractSource(element));
}
pc.popAndRegisterContainingComponent();
return null;
}
private BeanMetadataElement extracted(Element element, ParserContext pc, NamespaceHandlerResolver resolver,
Element providerElement) {
String ref = providerElement.getAttribute(ATT_REF);
if (!StringUtils.hasText(ref)) {
BeanDefinition provider = resolver.resolve(providerElement.getNamespaceURI()).parse(providerElement, pc);
Assert.notNull(provider,
() -> "Parser for " + providerElement.getNodeName() + " returned a null bean definition");
String providerId = pc.getReaderContext().generateBeanName(provider);
pc.registerBeanComponent(new BeanComponentDefinition(provider, providerId));
return new RuntimeBeanReference(providerId);
}
if (providerElement.getAttributes().getLength() > 1) {
pc.getReaderContext().error("authentication-provider element cannot be used with other attributes "
+ "when using 'ref' attribute", pc.extractSource(element));
}
NodeList providerChildren = providerElement.getChildNodes();
for (int i = 0; i < providerChildren.getLength(); i++) {
if (providerChildren.item(i) instanceof Element) {
pc.getReaderContext().error("authentication-provider element cannot have child elements when used "
+ "with 'ref' attribute", pc.extractSource(element));
}
}
return new RuntimeBeanReference(ref);
}
/**
* Provider which doesn't provide any service. Only used to prevent a configuration
* exception if the provider list is empty (usually because a child ProviderManager

View File

@ -56,12 +56,10 @@ public class AuthenticationManagerFactoryBean implements FactoryBean<Authenticat
if (!BeanIds.AUTHENTICATION_MANAGER.equals(ex.getBeanName())) {
throw ex;
}
UserDetailsService uds = getBeanOrNull(UserDetailsService.class);
if (uds == null) {
throw new NoSuchBeanDefinitionException(BeanIds.AUTHENTICATION_MANAGER, MISSING_BEAN_ERROR_MESSAGE);
}
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(uds);
PasswordEncoder passwordEncoder = getBeanOrNull(PasswordEncoder.class);

View File

@ -43,15 +43,12 @@ public class AuthenticationProviderBeanDefinitionParser implements BeanDefinitio
public BeanDefinition parse(Element element, ParserContext pc) {
RootBeanDefinition authProvider = new RootBeanDefinition(DaoAuthenticationProvider.class);
authProvider.setSource(pc.extractSource(element));
Element passwordEncoderElt = DomUtils.getChildElementByTagName(element, Elements.PASSWORD_ENCODER);
PasswordEncoderParser pep = new PasswordEncoderParser(passwordEncoderElt, pc);
BeanMetadataElement passwordEncoder = pep.getPasswordEncoder();
if (passwordEncoder != null) {
authProvider.getPropertyValues().addPropertyValue("passwordEncoder", passwordEncoder);
}
Element userServiceElt = DomUtils.getChildElementByTagName(element, Elements.USER_SERVICE);
if (userServiceElt == null) {
userServiceElt = DomUtils.getChildElementByTagName(element, Elements.JDBC_USER_SERVICE);
@ -59,9 +56,7 @@ public class AuthenticationProviderBeanDefinitionParser implements BeanDefinitio
if (userServiceElt == null) {
userServiceElt = DomUtils.getChildElementByTagName(element, Elements.LDAP_USER_SERVICE);
}
String ref = element.getAttribute(ATT_USER_DETAILS_REF);
if (StringUtils.hasText(ref)) {
if (userServiceElt != null) {
pc.getReaderContext()
@ -69,7 +64,6 @@ public class AuthenticationProviderBeanDefinitionParser implements BeanDefinitio
+ "elements '" + Elements.USER_SERVICE + "', '" + Elements.JDBC_USER_SERVICE + "' or '"
+ Elements.LDAP_USER_SERVICE + "'", element);
}
authProvider.getPropertyValues().add("userDetailsService", new RuntimeBeanReference(ref));
}
else {
@ -80,7 +74,6 @@ public class AuthenticationProviderBeanDefinitionParser implements BeanDefinitio
else {
pc.getReaderContext().error("A user-service is required", element);
}
// Pinch the cache-ref from the UserDetailService element, if set.
String cacheRef = userServiceElt.getAttribute(AbstractUserDetailsServiceBeanDefinitionParser.CACHE_REF);
@ -88,7 +81,6 @@ public class AuthenticationProviderBeanDefinitionParser implements BeanDefinitio
authProvider.getPropertyValues().addPropertyValue("userCache", new RuntimeBeanReference(cacheRef));
}
}
return authProvider;
}

View File

@ -42,7 +42,6 @@ public class JdbcUserServiceBeanDefinitionParser extends AbstractUserDetailsServ
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
String dataSource = element.getAttribute(ATT_DATA_SOURCE);
if (dataSource != null) {
builder.addPropertyReference("dataSource", dataSource);
}
@ -50,24 +49,19 @@ public class JdbcUserServiceBeanDefinitionParser extends AbstractUserDetailsServ
parserContext.getReaderContext().error(ATT_DATA_SOURCE + " is required for " + Elements.JDBC_USER_SERVICE,
parserContext.extractSource(element));
}
String usersQuery = element.getAttribute(ATT_USERS_BY_USERNAME_QUERY);
String authoritiesQuery = element.getAttribute(ATT_AUTHORITIES_BY_USERNAME_QUERY);
String groupAuthoritiesQuery = element.getAttribute(ATT_GROUP_AUTHORITIES_QUERY);
String rolePrefix = element.getAttribute(ATT_ROLE_PREFIX);
if (StringUtils.hasText(rolePrefix)) {
builder.addPropertyValue("rolePrefix", rolePrefix);
}
if (StringUtils.hasText(usersQuery)) {
builder.addPropertyValue("usersByUsernameQuery", usersQuery);
}
if (StringUtils.hasText(authoritiesQuery)) {
builder.addPropertyValue("authoritiesByUsernameQuery", authoritiesQuery);
}
if (StringUtils.hasText(groupAuthoritiesQuery)) {
builder.addPropertyValue("enableGroups", Boolean.TRUE);
builder.addPropertyValue("groupAuthoritiesByUsernameQuery", groupAuthoritiesQuery);

View File

@ -16,11 +16,9 @@
package org.springframework.security.config.authentication;
import java.util.HashMap;
import java.util.Collections;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Element;
import org.springframework.beans.BeanMetadataElement;
@ -42,17 +40,13 @@ public class PasswordEncoderParser {
static final String ATT_REF = "ref";
public static final String ATT_HASH = "hash";
static final String ATT_BASE_64 = "base64";
static final String OPT_HASH_BCRYPT = "bcrypt";
private static final Map<String, Class<?>> ENCODER_CLASSES;
static {
ENCODER_CLASSES = new HashMap<>();
ENCODER_CLASSES.put(OPT_HASH_BCRYPT, BCryptPasswordEncoder.class);
}
private static final Log logger = LogFactory.getLog(PasswordEncoderParser.class);
private static final Map<String, Class<?>> ENCODER_CLASSES = Collections.singletonMap(OPT_HASH_BCRYPT,
BCryptPasswordEncoder.class);
private BeanMetadataElement passwordEncoder;
@ -68,14 +62,9 @@ public class PasswordEncoderParser {
return;
}
String hash = element.getAttribute(ATT_HASH);
boolean useBase64 = false;
if (StringUtils.hasText(element.getAttribute(ATT_BASE_64))) {
useBase64 = Boolean.parseBoolean(element.getAttribute(ATT_BASE_64));
}
boolean useBase64 = StringUtils.hasText(element.getAttribute(ATT_BASE_64))
&& Boolean.parseBoolean(element.getAttribute(ATT_BASE_64));
String ref = element.getAttribute(ATT_REF);
if (StringUtils.hasText(ref)) {
this.passwordEncoder = new RuntimeBeanReference(ref);
}

View File

@ -62,43 +62,33 @@ public class UserServiceBeanDefinitionParser extends AbstractUserDetailsServiceB
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
String userProperties = element.getAttribute(ATT_PROPERTIES);
List<Element> userElts = DomUtils.getChildElementsByTagName(element, ELT_USER);
if (StringUtils.hasText(userProperties)) {
if (!CollectionUtils.isEmpty(userElts)) {
throw new BeanDefinitionStoreException(
"Use of a properties file and user elements are mutually exclusive");
}
BeanDefinition bd = new RootBeanDefinition(PropertiesFactoryBean.class);
bd.getPropertyValues().addPropertyValue("location", userProperties);
builder.addConstructorArgValue(bd);
return;
}
if (CollectionUtils.isEmpty(userElts)) {
throw new BeanDefinitionStoreException("You must supply user definitions, either with <" + ELT_USER
+ "> child elements or a " + "properties file (using the '" + ATT_PROPERTIES + "' attribute)");
}
ManagedList<BeanDefinition> users = new ManagedList<>();
for (Object elt : userElts) {
Element userElt = (Element) elt;
String userName = userElt.getAttribute(ATT_NAME);
String password = userElt.getAttribute(ATT_PASSWORD);
if (!StringUtils.hasLength(password)) {
password = generateRandomPassword();
}
boolean locked = "true".equals(userElt.getAttribute(ATT_LOCKED));
boolean disabled = "true".equals(userElt.getAttribute(ATT_DISABLED));
BeanDefinitionBuilder authorities = BeanDefinitionBuilder.rootBeanDefinition(AuthorityUtils.class);
authorities.addConstructorArgValue(userElt.getAttribute(ATT_AUTHORITIES));
authorities.setFactoryMethod("commaSeparatedStringToAuthorityList");
BeanDefinitionBuilder user = BeanDefinitionBuilder.rootBeanDefinition(User.class);
user.addConstructorArgValue(userName);
user.addConstructorArgValue(password);
@ -107,10 +97,8 @@ public class UserServiceBeanDefinitionParser extends AbstractUserDetailsServiceB
user.addConstructorArgValue(true);
user.addConstructorArgValue(!locked);
user.addConstructorArgValue(authorities.getBeanDefinition());
users.add(user.getBeanDefinition());
}
builder.addConstructorArgValue(users);
}

View File

@ -18,9 +18,11 @@ package org.springframework.security.config.core.userdetails;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.memory.UserAttribute;
@ -58,27 +60,19 @@ public class UserDetailsMapFactoryBean implements FactoryBean<Collection<UserDet
@Override
public Collection<UserDetails> getObject() {
Collection<UserDetails> users = new ArrayList<>(this.userProperties.size());
UserAttributeEditor editor = new UserAttributeEditor();
for (Map.Entry<String, String> entry : this.userProperties.entrySet()) {
String name = entry.getKey();
String property = entry.getValue();
this.userProperties.forEach((name, property) -> {
editor.setAsText(property);
UserAttribute attr = (UserAttribute) editor.getValue();
if (attr == null) {
throw new IllegalStateException("The entry with username '" + name + "' and value '" + property
+ "' could not be converted to a UserDetails.");
}
// @formatter:off
UserDetails user = User.withUsername(name)
.password(attr.getPassword())
.disabled(!attr.isEnabled())
.authorities(attr.getAuthorities())
.build();
users.add(user);
// @formatter:on
}
Assert.state(attr != null, () -> "The entry with username '" + name + "' and value '" + property
+ "' could not be converted to a UserDetails.");
String password = attr.getPassword();
boolean disabled = !attr.isEnabled();
List<GrantedAuthority> authorities = attr.getAuthorities();
users.add(User.withUsername(name).password(password).disabled(disabled).authorities(authorities).build());
});
return users;
}
@Override

View File

@ -57,18 +57,13 @@ public class RsaKeyConversionServicePostProcessor implements BeanFactoryPostProc
this.resourceLoader = resourceLoader;
}
/**
* {@inheritDoc}
*/
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
if (hasUserDefinedConversionService(beanFactory)) {
return;
}
Converter<String, RSAPrivateKey> pkcs8 = pkcs8();
Converter<String, RSAPublicKey> x509 = x509();
ConversionService service = beanFactory.getConversionService();
if (service instanceof ConverterRegistry) {
ConverterRegistry registry = (ConverterRegistry) service;

View File

@ -86,12 +86,15 @@ final class AuthenticationConfigBuilder {
private static final String DEF_REALM = "Realm";
static final String OPEN_ID_AUTHENTICATION_PROCESSING_FILTER_CLASS = "org.springframework.security.openid.OpenIDAuthenticationFilter";
static final String OPEN_ID_AUTHENTICATION_PROVIDER_CLASS = "org.springframework.security.openid.OpenIDAuthenticationProvider";
private static final String OPEN_ID_CONSUMER_CLASS = "org.springframework.security.openid.OpenID4JavaConsumer";
static final String OPEN_ID_ATTRIBUTE_CLASS = "org.springframework.security.openid.OpenIDAttribute";
private static final String OPEN_ID_ATTRIBUTE_FACTORY_CLASS = "org.springframework.security.openid.RegexBasedAxFetchListFactory";
static final String AUTHENTICATION_PROCESSING_FILTER_CLASS = "org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter";
static final String ATT_AUTH_DETAILS_SOURCE_REF = "authentication-details-source-ref";
@ -106,6 +109,8 @@ final class AuthenticationConfigBuilder {
private static final String ATT_KEY = "key";
private static final String ATT_MAPPABLE_ROLES = "mappable-roles";
private final Element httpElt;
private final ParserContext pc;
@ -226,7 +231,6 @@ final class AuthenticationConfigBuilder {
this.portMapper = portMapper;
this.portResolver = portResolver;
this.csrfLogoutHandler = csrfLogoutHandler;
createAnonymousFilter();
createRememberMeFilter(authenticationManager);
createBasicFilter(authenticationManager);
@ -243,18 +247,14 @@ final class AuthenticationConfigBuilder {
}
void createRememberMeFilter(BeanReference authenticationManager) {
// Parse remember me before logout as RememberMeServices is also a LogoutHandler
// implementation.
Element rememberMeElt = DomUtils.getChildElementByTagName(this.httpElt, Elements.REMEMBER_ME);
if (rememberMeElt != null) {
String key = rememberMeElt.getAttribute(ATT_KEY);
if (!StringUtils.hasText(key)) {
key = createKey();
}
RememberMeBeanDefinitionParser rememberMeParser = new RememberMeBeanDefinitionParser(key,
authenticationManager);
this.rememberMeFilter = rememberMeParser.parse(rememberMeElt, this.pc);
@ -266,36 +266,28 @@ final class AuthenticationConfigBuilder {
private void createRememberMeProvider(String key) {
RootBeanDefinition provider = new RootBeanDefinition(RememberMeAuthenticationProvider.class);
provider.setSource(this.rememberMeFilter.getSource());
provider.getConstructorArgumentValues().addGenericArgumentValue(key);
String id = this.pc.getReaderContext().generateBeanName(provider);
this.pc.registerBeanComponent(new BeanComponentDefinition(provider, id));
this.rememberMeProviderRef = new RuntimeBeanReference(id);
}
void createFormLoginFilter(BeanReference sessionStrategy, BeanReference authManager) {
Element formLoginElt = DomUtils.getChildElementByTagName(this.httpElt, Elements.FORM_LOGIN);
RootBeanDefinition formFilter = null;
if (formLoginElt != null || this.autoConfig) {
FormLoginBeanDefinitionParser parser = new FormLoginBeanDefinitionParser("/login", "POST",
AUTHENTICATION_PROCESSING_FILTER_CLASS, this.requestCache, sessionStrategy,
this.allowSessionCreation, this.portMapper, this.portResolver);
parser.parse(formLoginElt, this.pc);
formFilter = parser.getFilterBean();
this.formEntryPoint = parser.getEntryPointBean();
this.loginProcessingUrl = parser.getLoginProcessingUrl();
this.formLoginPage = parser.getLoginPage();
}
if (formFilter != null) {
formFilter.getPropertyValues().addPropertyValue("allowSessionCreation", this.allowSessionCreation);
formFilter.getPropertyValues().addPropertyValue("authenticationManager", authManager);
// Id is required by login page filter
this.formFilterId = this.pc.getReaderContext().generateBeanName(formFilter);
this.pc.registerBeanComponent(new BeanComponentDefinition(formFilter, this.formFilterId));
@ -316,14 +308,11 @@ final class AuthenticationConfigBuilder {
return;
}
this.oauth2LoginEnabled = true;
OAuth2LoginBeanDefinitionParser parser = new OAuth2LoginBeanDefinitionParser(this.requestCache, this.portMapper,
this.portResolver, sessionStrategy, this.allowSessionCreation);
BeanDefinition oauth2LoginFilterBean = parser.parse(oauth2LoginElt, this.pc);
BeanDefinition defaultAuthorizedClientRepository = parser.getDefaultAuthorizedClientRepository();
registerDefaultAuthorizedClientRepositoryIfNecessary(defaultAuthorizedClientRepository);
oauth2LoginFilterBean.getPropertyValues().addPropertyValue("authenticationManager", authManager);
// retrieve the other bean result
@ -360,26 +349,21 @@ final class AuthenticationConfigBuilder {
return;
}
this.oauth2ClientEnabled = true;
OAuth2ClientBeanDefinitionParser parser = new OAuth2ClientBeanDefinitionParser(requestCache,
authenticationManager);
parser.parse(oauth2ClientElt, this.pc);
BeanDefinition defaultAuthorizedClientRepository = parser.getDefaultAuthorizedClientRepository();
registerDefaultAuthorizedClientRepositoryIfNecessary(defaultAuthorizedClientRepository);
this.authorizationRequestRedirectFilter = parser.getAuthorizationRequestRedirectFilter();
String authorizationRequestRedirectFilterId = this.pc.getReaderContext()
.generateBeanName(this.authorizationRequestRedirectFilter);
this.pc.registerBeanComponent(new BeanComponentDefinition(this.authorizationRequestRedirectFilter,
authorizationRequestRedirectFilterId));
this.authorizationCodeGrantFilter = parser.getAuthorizationCodeGrantFilter();
String authorizationCodeGrantFilterId = this.pc.getReaderContext()
.generateBeanName(this.authorizationCodeGrantFilter);
this.pc.registerBeanComponent(
new BeanComponentDefinition(this.authorizationCodeGrantFilter, authorizationCodeGrantFilterId));
BeanDefinition authorizationCodeAuthenticationProvider = parser.getAuthorizationCodeAuthenticationProvider();
String authorizationCodeAuthenticationProviderId = this.pc.getReaderContext()
.generateBeanName(authorizationCodeAuthenticationProvider);
@ -403,7 +387,6 @@ final class AuthenticationConfigBuilder {
if (!this.oauth2LoginEnabled && !this.oauth2ClientEnabled) {
return;
}
boolean webmvcPresent = ClassUtils.isPresent("org.springframework.web.servlet.DispatcherServlet",
getClass().getClassLoader());
if (webmvcPresent) {
@ -415,11 +398,9 @@ final class AuthenticationConfigBuilder {
void createOpenIDLoginFilter(BeanReference sessionStrategy, BeanReference authManager) {
Element openIDLoginElt = DomUtils.getChildElementByTagName(this.httpElt, Elements.OPENID_LOGIN);
RootBeanDefinition openIDFilter = null;
if (openIDLoginElt != null) {
openIDFilter = parseOpenIDFilter(sessionStrategy, openIDLoginElt);
}
if (openIDFilter != null) {
openIDFilter.getPropertyValues().addPropertyValue("allowSessionCreation", this.allowSessionCreation);
openIDFilter.getPropertyValues().addPropertyValue("authenticationManager", authManager);
@ -427,7 +408,6 @@ final class AuthenticationConfigBuilder {
this.openIDFilterId = this.pc.getReaderContext().generateBeanName(openIDFilter);
this.pc.registerBeanComponent(new BeanComponentDefinition(openIDFilter, this.openIDFilterId));
injectRememberMeServicesRef(openIDFilter, this.rememberMeServicesId);
createOpenIDProvider();
}
}
@ -454,19 +434,15 @@ final class AuthenticationConfigBuilder {
this.openIDEntryPoint = parser.getEntryPointBean();
this.openidLoginProcessingUrl = parser.getLoginProcessingUrl();
this.openIDLoginPage = parser.getLoginPage();
List<Element> attrExElts = DomUtils.getChildElementsByTagName(openIDLoginElt,
Elements.OPENID_ATTRIBUTE_EXCHANGE);
if (!attrExElts.isEmpty()) {
// Set up the consumer with the required attribute list
BeanDefinitionBuilder consumerBldr = BeanDefinitionBuilder.rootBeanDefinition(OPEN_ID_CONSUMER_CLASS);
BeanDefinitionBuilder axFactory = BeanDefinitionBuilder.rootBeanDefinition(OPEN_ID_ATTRIBUTE_FACTORY_CLASS);
ManagedMap<String, ManagedList<BeanDefinition>> axMap = new ManagedMap<>();
for (Element attrExElt : attrExElts) {
String identifierMatch = attrExElt.getAttribute("identifier-match");
if (!StringUtils.hasText(identifierMatch)) {
if (attrExElts.size() > 1) {
this.pc.getReaderContext().error("You must supply an identifier-match attribute if using more"
@ -475,11 +451,9 @@ final class AuthenticationConfigBuilder {
// Match anything
identifierMatch = ".*";
}
axMap.put(identifierMatch, parseOpenIDAttributes(attrExElt));
}
axFactory.addConstructorArgValue(axMap);
consumerBldr.addConstructorArgValue(axFactory.getBeanDefinition());
openIDFilter.getPropertyValues().addPropertyValue("consumer", consumerBldr.getBeanDefinition());
}
@ -499,13 +473,11 @@ final class AuthenticationConfigBuilder {
if (StringUtils.hasLength(required)) {
attrBldr.addPropertyValue("required", Boolean.valueOf(required));
}
if (StringUtils.hasLength(count)) {
attrBldr.addPropertyValue("count", Integer.parseInt(count));
}
attributes.add(attrBldr.getBeanDefinition());
}
return attributes;
}
@ -513,14 +485,11 @@ final class AuthenticationConfigBuilder {
Element openIDLoginElt = DomUtils.getChildElementByTagName(this.httpElt, Elements.OPENID_LOGIN);
BeanDefinitionBuilder openIDProviderBuilder = BeanDefinitionBuilder
.rootBeanDefinition(OPEN_ID_AUTHENTICATION_PROVIDER_CLASS);
RootBeanDefinition uds = new RootBeanDefinition();
uds.setFactoryBeanName(BeanIds.USER_DETAILS_SERVICE_FACTORY);
uds.setFactoryMethodName("authenticationUserDetailsService");
uds.getConstructorArgumentValues().addGenericArgumentValue(openIDLoginElt.getAttribute(ATT_USER_SERVICE_REF));
openIDProviderBuilder.addPropertyValue("authenticationUserDetailsService", uds);
BeanDefinition openIDProvider = openIDProviderBuilder.getBeanDefinition();
this.openIDProviderRef = new RuntimeBeanReference(
this.pc.getReaderContext().registerWithGeneratedName(openIDProvider));
@ -535,30 +504,22 @@ final class AuthenticationConfigBuilder {
void createBasicFilter(BeanReference authManager) {
Element basicAuthElt = DomUtils.getChildElementByTagName(this.httpElt, Elements.BASIC_AUTH);
if (basicAuthElt == null && !this.autoConfig) {
// No basic auth, do nothing
return;
}
String realm = this.httpElt.getAttribute(ATT_REALM);
if (!StringUtils.hasText(realm)) {
realm = DEF_REALM;
}
BeanDefinitionBuilder filterBuilder = BeanDefinitionBuilder.rootBeanDefinition(BasicAuthenticationFilter.class);
String entryPointId;
if (basicAuthElt != null) {
if (StringUtils.hasText(basicAuthElt.getAttribute(ATT_ENTRY_POINT_REF))) {
this.basicEntryPoint = new RuntimeBeanReference(basicAuthElt.getAttribute(ATT_ENTRY_POINT_REF));
}
injectAuthenticationDetailsSource(basicAuthElt, filterBuilder);
}
if (this.basicEntryPoint == null) {
RootBeanDefinition entryPoint = new RootBeanDefinition(BasicAuthenticationEntryPoint.class);
entryPoint.setSource(this.pc.extractSource(this.httpElt));
@ -567,7 +528,6 @@ final class AuthenticationConfigBuilder {
this.pc.registerBeanComponent(new BeanComponentDefinition(entryPoint, entryPointId));
this.basicEntryPoint = new RuntimeBeanReference(entryPointId);
}
filterBuilder.addConstructorArgValue(authManager);
filterBuilder.addConstructorArgValue(this.basicEntryPoint);
this.basicFilter = filterBuilder.getBeanDefinition();
@ -575,12 +535,10 @@ final class AuthenticationConfigBuilder {
void createBearerTokenAuthenticationFilter(BeanReference authManager) {
Element resourceServerElt = DomUtils.getChildElementByTagName(this.httpElt, Elements.OAUTH2_RESOURCE_SERVER);
if (resourceServerElt == null) {
// No resource server, do nothing
return;
}
OAuth2ResourceServerBeanDefinitionParser resourceServerBuilder = new OAuth2ResourceServerBeanDefinitionParser(
authManager, this.authenticationProviders, this.defaultEntryPointMappings,
this.defaultDeniedHandlerMappings, this.csrfIgnoreRequestMatchers);
@ -590,37 +548,28 @@ final class AuthenticationConfigBuilder {
void createX509Filter(BeanReference authManager) {
Element x509Elt = DomUtils.getChildElementByTagName(this.httpElt, Elements.X509);
RootBeanDefinition filter = null;
if (x509Elt != null) {
BeanDefinitionBuilder filterBuilder = BeanDefinitionBuilder
.rootBeanDefinition(X509AuthenticationFilter.class);
filterBuilder.getRawBeanDefinition().setSource(this.pc.extractSource(x509Elt));
filterBuilder.addPropertyValue("authenticationManager", authManager);
String regex = x509Elt.getAttribute("subject-principal-regex");
if (StringUtils.hasText(regex)) {
BeanDefinitionBuilder extractor = BeanDefinitionBuilder
.rootBeanDefinition(SubjectDnX509PrincipalExtractor.class);
extractor.addPropertyValue("subjectDnRegex", regex);
filterBuilder.addPropertyValue("principalExtractor", extractor.getBeanDefinition());
}
injectAuthenticationDetailsSource(x509Elt, filterBuilder);
filter = (RootBeanDefinition) filterBuilder.getBeanDefinition();
createPrauthEntryPoint(x509Elt);
createX509Provider();
}
this.x509Filter = filter;
}
private void injectAuthenticationDetailsSource(Element elt, BeanDefinitionBuilder filterBuilder) {
String authDetailsSourceRef = elt.getAttribute(AuthenticationConfigBuilder.ATT_AUTH_DETAILS_SOURCE_REF);
if (StringUtils.hasText(authDetailsSourceRef)) {
filterBuilder.addPropertyReference("authenticationDetailsSource", authDetailsSourceRef);
}
@ -629,14 +578,11 @@ final class AuthenticationConfigBuilder {
private void createX509Provider() {
Element x509Elt = DomUtils.getChildElementByTagName(this.httpElt, Elements.X509);
BeanDefinition provider = new RootBeanDefinition(PreAuthenticatedAuthenticationProvider.class);
RootBeanDefinition uds = new RootBeanDefinition();
uds.setFactoryBeanName(BeanIds.USER_DETAILS_SERVICE_FACTORY);
uds.setFactoryMethodName("authenticationUserDetailsService");
uds.getConstructorArgumentValues().addGenericArgumentValue(x509Elt.getAttribute(ATT_USER_SERVICE_REF));
provider.getPropertyValues().addPropertyValue("preAuthenticatedUserDetailsService", uds);
this.x509ProviderRef = new RuntimeBeanReference(this.pc.getReaderContext().registerWithGeneratedName(provider));
}
@ -648,47 +594,37 @@ final class AuthenticationConfigBuilder {
}
void createJeeFilter(BeanReference authManager) {
final String ATT_MAPPABLE_ROLES = "mappable-roles";
Element jeeElt = DomUtils.getChildElementByTagName(this.httpElt, Elements.JEE);
RootBeanDefinition filter = null;
if (jeeElt != null) {
BeanDefinitionBuilder filterBuilder = BeanDefinitionBuilder
.rootBeanDefinition(J2eePreAuthenticatedProcessingFilter.class);
filterBuilder.getRawBeanDefinition().setSource(this.pc.extractSource(jeeElt));
filterBuilder.addPropertyValue("authenticationManager", authManager);
BeanDefinitionBuilder adsBldr = BeanDefinitionBuilder
.rootBeanDefinition(J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource.class);
adsBldr.addPropertyValue("userRoles2GrantedAuthoritiesMapper",
new RootBeanDefinition(SimpleAttributes2GrantedAuthoritiesMapper.class));
String roles = jeeElt.getAttribute(ATT_MAPPABLE_ROLES);
Assert.hasLength(roles, "roles is expected to have length");
BeanDefinitionBuilder rolesBuilder = BeanDefinitionBuilder.rootBeanDefinition(StringUtils.class);
rolesBuilder.addConstructorArgValue(roles);
rolesBuilder.setFactoryMethod("commaDelimitedListToSet");
RootBeanDefinition mappableRolesRetriever = new RootBeanDefinition(SimpleMappableAttributesRetriever.class);
mappableRolesRetriever.getPropertyValues().addPropertyValue("mappableAttributes",
rolesBuilder.getBeanDefinition());
adsBldr.addPropertyValue("mappableRolesRetriever", mappableRolesRetriever);
filterBuilder.addPropertyValue("authenticationDetailsSource", adsBldr.getBeanDefinition());
filter = (RootBeanDefinition) filterBuilder.getBeanDefinition();
createPrauthEntryPoint(jeeElt);
createJeeProvider();
}
this.jeeFilter = filter;
}
private void createJeeProvider() {
Element jeeElt = DomUtils.getChildElementByTagName(this.httpElt, Elements.JEE);
BeanDefinition provider = new RootBeanDefinition(PreAuthenticatedAuthenticationProvider.class);
RootBeanDefinition uds;
if (StringUtils.hasText(jeeElt.getAttribute(ATT_USER_SERVICE_REF))) {
uds = new RootBeanDefinition();
@ -699,16 +635,13 @@ final class AuthenticationConfigBuilder {
else {
uds = new RootBeanDefinition(PreAuthenticatedGrantedAuthoritiesUserDetailsService.class);
}
provider.getPropertyValues().addPropertyValue("preAuthenticatedUserDetailsService", uds);
this.jeeProviderRef = new RuntimeBeanReference(this.pc.getReaderContext().registerWithGeneratedName(provider));
}
void createLoginPageFilterIfNeeded() {
boolean needLoginPage = this.formFilterId != null || this.openIDFilterId != null
|| this.oauth2LoginFilterId != null;
// If no login page has been defined, add in the default page generator.
if (needLoginPage && this.formLoginPage == null && this.openIDLoginPage == null) {
this.logger.info("No login page configured. The default internal one will be used. Use the '"
@ -720,23 +653,19 @@ final class AuthenticationConfigBuilder {
BeanDefinitionBuilder logoutPageFilter = BeanDefinitionBuilder
.rootBeanDefinition(DefaultLogoutPageGeneratingFilter.class);
logoutPageFilter.addPropertyValue("resolveHiddenInputs", new CsrfTokenHiddenInputFunction());
if (this.formFilterId != null) {
loginPageFilter.addConstructorArgReference(this.formFilterId);
loginPageFilter.addPropertyValue("authenticationUrl", this.loginProcessingUrl);
}
if (this.openIDFilterId != null) {
loginPageFilter.addConstructorArgReference(this.openIDFilterId);
loginPageFilter.addPropertyValue("openIDauthenticationUrl", this.openidLoginProcessingUrl);
}
if (this.oauth2LoginFilterId != null) {
loginPageFilter.addConstructorArgReference(this.oauth2LoginFilterId);
loginPageFilter.addPropertyValue("Oauth2LoginEnabled", true);
loginPageFilter.addPropertyValue("Oauth2AuthenticationUrlToClientName", this.oauth2LoginLinks);
}
this.loginPageGenerationFilter = loginPageFilter.getBeanDefinition();
this.logoutPageGenerationFilter = logoutPageFilter.getBeanDefinition();
}
@ -784,51 +713,41 @@ final class AuthenticationConfigBuilder {
void createAnonymousFilter() {
Element anonymousElt = DomUtils.getChildElementByTagName(this.httpElt, Elements.ANONYMOUS);
if (anonymousElt != null && "false".equals(anonymousElt.getAttribute("enabled"))) {
return;
}
String grantedAuthority = null;
String username = null;
String key = null;
Object source = this.pc.extractSource(this.httpElt);
if (anonymousElt != null) {
grantedAuthority = anonymousElt.getAttribute("granted-authority");
username = anonymousElt.getAttribute("username");
key = anonymousElt.getAttribute(ATT_KEY);
source = this.pc.extractSource(anonymousElt);
}
if (!StringUtils.hasText(grantedAuthority)) {
grantedAuthority = "ROLE_ANONYMOUS";
}
if (!StringUtils.hasText(username)) {
username = "anonymousUser";
}
if (!StringUtils.hasText(key)) {
// Generate a random key for the Anonymous provider
key = createKey();
}
this.anonymousFilter = new RootBeanDefinition(AnonymousAuthenticationFilter.class);
this.anonymousFilter.getConstructorArgumentValues().addIndexedArgumentValue(0, key);
this.anonymousFilter.getConstructorArgumentValues().addIndexedArgumentValue(1, username);
this.anonymousFilter.getConstructorArgumentValues().addIndexedArgumentValue(2,
AuthorityUtils.commaSeparatedStringToAuthorityList(grantedAuthority));
this.anonymousFilter.setSource(source);
RootBeanDefinition anonymousProviderBean = new RootBeanDefinition(AnonymousAuthenticationProvider.class);
anonymousProviderBean.getConstructorArgumentValues().addIndexedArgumentValue(0, key);
anonymousProviderBean.setSource(this.anonymousFilter.getSource());
String id = this.pc.getReaderContext().generateBeanName(anonymousProviderBean);
this.pc.registerBeanComponent(new BeanComponentDefinition(anonymousProviderBean, id));
this.anonymousProviderRef = new RuntimeBeanReference(id);
}
private String createKey() {
@ -840,11 +759,10 @@ final class AuthenticationConfigBuilder {
BeanDefinitionBuilder etfBuilder = BeanDefinitionBuilder.rootBeanDefinition(ExceptionTranslationFilter.class);
this.accessDeniedHandler = createAccessDeniedHandler(this.httpElt, this.pc);
etfBuilder.addPropertyValue("accessDeniedHandler", this.accessDeniedHandler);
assert this.requestCache != null;
Assert.state(this.requestCache != null, "No request cache found");
this.mainEntryPoint = selectEntryPoint();
etfBuilder.addConstructorArgValue(this.mainEntryPoint);
etfBuilder.addConstructorArgValue(this.requestCache);
this.etf = etfBuilder.getBeanDefinition();
}
@ -852,11 +770,9 @@ final class AuthenticationConfigBuilder {
Element accessDeniedElt = DomUtils.getChildElementByTagName(element, Elements.ACCESS_DENIED_HANDLER);
BeanDefinitionBuilder accessDeniedHandler = BeanDefinitionBuilder
.rootBeanDefinition(AccessDeniedHandlerImpl.class);
if (accessDeniedElt != null) {
String errorPage = accessDeniedElt.getAttribute("error-page");
String ref = accessDeniedElt.getAttribute("ref");
if (StringUtils.hasText(errorPage)) {
if (StringUtils.hasText(ref)) {
pc.getReaderContext()
@ -868,25 +784,21 @@ final class AuthenticationConfigBuilder {
accessDeniedHandler.addPropertyValue("errorPage", errorPage);
return accessDeniedHandler.getBeanDefinition();
}
else if (StringUtils.hasText(ref)) {
if (StringUtils.hasText(ref)) {
return new RuntimeBeanReference(ref);
}
}
if (this.defaultDeniedHandlerMappings.isEmpty()) {
return accessDeniedHandler.getBeanDefinition();
}
if (this.defaultDeniedHandlerMappings.size() == 1) {
return this.defaultDeniedHandlerMappings.values().iterator().next();
}
accessDeniedHandler = BeanDefinitionBuilder
.rootBeanDefinition(RequestMatcherDelegatingAccessDeniedHandler.class);
accessDeniedHandler.addConstructorArgValue(this.defaultDeniedHandlerMappings);
accessDeniedHandler
.addConstructorArgValue(BeanDefinitionBuilder.rootBeanDefinition(AccessDeniedHandlerImpl.class));
return accessDeniedHandler.getBeanDefinition();
}
@ -894,11 +806,9 @@ final class AuthenticationConfigBuilder {
// We need to establish the main entry point.
// First check if a custom entry point bean is set
String customEntryPoint = this.httpElt.getAttribute(ATT_ENTRY_POINT_REF);
if (StringUtils.hasText(customEntryPoint)) {
return new RuntimeBeanReference(customEntryPoint);
}
if (!this.defaultEntryPointMappings.isEmpty()) {
if (this.defaultEntryPointMappings.size() == 1) {
return this.defaultEntryPointMappings.values().iterator().next();
@ -908,7 +818,6 @@ final class AuthenticationConfigBuilder {
delegatingEntryPoint.addConstructorArgValue(this.defaultEntryPointMappings);
return delegatingEntryPoint.getBeanDefinition();
}
Element basicAuthElt = DomUtils.getChildElementByTagName(this.httpElt, Elements.BASIC_AUTH);
Element formLoginElt = DomUtils.getChildElementByTagName(this.httpElt, Elements.FORM_LOGIN);
Element openIDLoginElt = DomUtils.getChildElementByTagName(this.httpElt, Elements.OPENID_LOGIN);
@ -917,21 +826,17 @@ final class AuthenticationConfigBuilder {
&& this.oauth2LoginEntryPoint == null) {
return this.basicEntryPoint;
}
// If formLogin has been enabled either through an element or auto-config, then it
// is used if no openID login page
// has been set.
if (this.formLoginPage != null && this.openIDLoginPage != null) {
this.pc.getReaderContext().error(
"Only one login-page can be defined, either for OpenID or form-login, " + "but not both.",
this.pc.extractSource(openIDLoginElt));
}
if (this.formFilterId != null && this.openIDLoginPage == null) {
// gh-6802
// If form login was enabled through element and Oauth2 login was enabled from
// element then use form login
// element then use form login (gh-6802)
if (formLoginElt != null && this.oauth2LoginEntryPoint != null) {
return this.formEntryPoint;
}
@ -941,22 +846,18 @@ final class AuthenticationConfigBuilder {
return this.formEntryPoint;
}
}
// Otherwise use OpenID if enabled
if (this.openIDFilterId != null) {
return this.openIDEntryPoint;
}
// If X.509 or JEE have been enabled, use the preauth entry point.
if (this.preAuthEntryPoint != null) {
return this.preAuthEntryPoint;
}
// OAuth2 entry point will not be null if only 1 client registration
if (this.oauth2LoginEntryPoint != null) {
return this.oauth2LoginEntryPoint;
}
this.pc.getReaderContext().error("No AuthenticationEntryPoint could be established. Please "
+ "make sure you have a login mechanism configured through the namespace (such as form-login) or "
+ "specify a custom AuthenticationEntryPoint with the '" + ATT_ENTRY_POINT_REF + "' attribute ",
@ -976,107 +877,83 @@ final class AuthenticationConfigBuilder {
List<OrderDecorator> getFilters() {
List<OrderDecorator> filters = new ArrayList<>();
if (this.anonymousFilter != null) {
filters.add(new OrderDecorator(this.anonymousFilter, SecurityFilters.ANONYMOUS_FILTER));
}
if (this.rememberMeFilter != null) {
filters.add(new OrderDecorator(this.rememberMeFilter, SecurityFilters.REMEMBER_ME_FILTER));
}
if (this.logoutFilter != null) {
filters.add(new OrderDecorator(this.logoutFilter, SecurityFilters.LOGOUT_FILTER));
}
if (this.x509Filter != null) {
filters.add(new OrderDecorator(this.x509Filter, SecurityFilters.X509_FILTER));
}
if (this.jeeFilter != null) {
filters.add(new OrderDecorator(this.jeeFilter, SecurityFilters.PRE_AUTH_FILTER));
}
if (this.formFilterId != null) {
filters.add(
new OrderDecorator(new RuntimeBeanReference(this.formFilterId), SecurityFilters.FORM_LOGIN_FILTER));
}
if (this.oauth2LoginFilterId != null) {
filters.add(new OrderDecorator(new RuntimeBeanReference(this.oauth2LoginFilterId),
SecurityFilters.OAUTH2_LOGIN_FILTER));
filters.add(new OrderDecorator(this.oauth2AuthorizationRequestRedirectFilter,
SecurityFilters.OAUTH2_AUTHORIZATION_REQUEST_FILTER));
}
if (this.openIDFilterId != null) {
filters.add(
new OrderDecorator(new RuntimeBeanReference(this.openIDFilterId), SecurityFilters.OPENID_FILTER));
}
if (this.loginPageGenerationFilter != null) {
filters.add(new OrderDecorator(this.loginPageGenerationFilter, SecurityFilters.LOGIN_PAGE_FILTER));
filters.add(new OrderDecorator(this.logoutPageGenerationFilter, SecurityFilters.LOGOUT_PAGE_FILTER));
}
if (this.basicFilter != null) {
filters.add(new OrderDecorator(this.basicFilter, SecurityFilters.BASIC_AUTH_FILTER));
}
if (this.bearerTokenAuthenticationFilter != null) {
filters.add(
new OrderDecorator(this.bearerTokenAuthenticationFilter, SecurityFilters.BEARER_TOKEN_AUTH_FILTER));
}
if (this.authorizationCodeGrantFilter != null) {
filters.add(new OrderDecorator(this.authorizationRequestRedirectFilter,
SecurityFilters.OAUTH2_AUTHORIZATION_REQUEST_FILTER.getOrder() + 1));
filters.add(new OrderDecorator(this.authorizationCodeGrantFilter,
SecurityFilters.OAUTH2_AUTHORIZATION_CODE_GRANT_FILTER));
}
filters.add(new OrderDecorator(this.etf, SecurityFilters.EXCEPTION_TRANSLATION_FILTER));
return filters;
}
List<BeanReference> getProviders() {
List<BeanReference> providers = new ArrayList<>();
if (this.anonymousProviderRef != null) {
providers.add(this.anonymousProviderRef);
}
if (this.rememberMeProviderRef != null) {
providers.add(this.rememberMeProviderRef);
}
if (this.openIDProviderRef != null) {
providers.add(this.openIDProviderRef);
}
if (this.x509ProviderRef != null) {
providers.add(this.x509ProviderRef);
}
if (this.jeeProviderRef != null) {
providers.add(this.jeeProviderRef);
}
if (this.oauth2LoginAuthenticationProviderRef != null) {
providers.add(this.oauth2LoginAuthenticationProviderRef);
}
if (this.oauth2LoginOidcAuthenticationProviderRef != null) {
providers.add(this.oauth2LoginOidcAuthenticationProviderRef);
}
if (this.authorizationCodeAuthenticationProviderRef != null) {
providers.add(this.authorizationCodeAuthenticationProviderRef);
}
providers.addAll(this.authenticationProviders);
return providers;
}

View File

@ -43,7 +43,6 @@ public final class ChannelAttributeFactory {
public static List<ConfigAttribute> createChannelAttributes(String requiredChannel) {
String channelConfigAttribute;
if (requiredChannel.equals(OPT_REQUIRES_HTTPS)) {
channelConfigAttribute = "REQUIRES_SECURE_CHANNEL";
}
@ -56,7 +55,6 @@ public final class ChannelAttributeFactory {
else {
throw new BeanCreationException("Unknown channel attribute " + requiredChannel);
}
return SecurityConfig.createList(channelConfigAttribute);
}

View File

@ -46,17 +46,14 @@ public class CorsBeanDefinitionParser {
if (element == null) {
return null;
}
String filterRef = element.getAttribute(ATT_REF);
if (StringUtils.hasText(filterRef)) {
return new RuntimeBeanReference(filterRef);
}
BeanMetadataElement configurationSource = getSource(element, parserContext);
if (configurationSource == null) {
throw new BeanCreationException("Could not create CorsFilter");
}
BeanDefinitionBuilder filterBldr = BeanDefinitionBuilder.rootBeanDefinition(CorsFilter.class);
filterBldr.addConstructorArgValue(configurationSource);
return filterBldr.getBeanDefinition();
@ -67,12 +64,10 @@ public class CorsBeanDefinitionParser {
if (StringUtils.hasText(configurationSourceRef)) {
return new RuntimeBeanReference(configurationSourceRef);
}
boolean mvcPresent = ClassUtils.isPresent(HANDLER_MAPPING_INTROSPECTOR, getClass().getClassLoader());
if (!mvcPresent) {
return null;
}
return new RootBeanDefinition(HandlerMappingIntrospectorFactoryBean.class);
}

View File

@ -92,14 +92,11 @@ public class CsrfBeanDefinitionParser implements BeanDefinitionParser {
pc.registerBeanComponent(componentDefinition);
}
}
if (element != null) {
this.csrfRepositoryRef = element.getAttribute(ATT_REPOSITORY);
this.requestMatcherRef = element.getAttribute(ATT_MATCHER);
}
if (!StringUtils.hasText(this.csrfRepositoryRef)) {
RootBeanDefinition csrfTokenRepository = new RootBeanDefinition(HttpSessionCsrfTokenRepository.class);
BeanDefinitionBuilder lazyTokenRepository = BeanDefinitionBuilder
.rootBeanDefinition(LazyCsrfTokenRepository.class);
@ -108,14 +105,11 @@ public class CsrfBeanDefinitionParser implements BeanDefinitionParser {
pc.registerBeanComponent(
new BeanComponentDefinition(lazyTokenRepository.getBeanDefinition(), this.csrfRepositoryRef));
}
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(CsrfFilter.class);
builder.addConstructorArgReference(this.csrfRepositoryRef);
if (StringUtils.hasText(this.requestMatcherRef)) {
builder.addPropertyReference("requireCsrfProtectionMatcher", this.requestMatcherRef);
}
this.csrfFilter = builder.getBeanDefinition();
return this.csrfFilter;
}
@ -155,12 +149,10 @@ public class CsrfBeanDefinitionParser implements BeanDefinitionParser {
.rootBeanDefinition(InvalidSessionAccessDeniedHandler.class);
invalidSessionHandlerBldr.addConstructorArgValue(invalidSessionStrategy);
handlers.put(MissingCsrfTokenException.class, invalidSessionHandlerBldr.getBeanDefinition());
BeanDefinitionBuilder deniedBldr = BeanDefinitionBuilder
.rootBeanDefinition(DelegatingAccessDeniedHandler.class);
deniedBldr.addConstructorArgValue(handlers);
deniedBldr.addConstructorArgValue(defaultDeniedHandler);
return deniedBldr.getBeanDefinition();
}
@ -180,13 +172,9 @@ public class CsrfBeanDefinitionParser implements BeanDefinitionParser {
void setIgnoreCsrfRequestMatchers(List<BeanDefinition> requestMatchers) {
if (!requestMatchers.isEmpty()) {
BeanMetadataElement requestMatcher;
if (StringUtils.hasText(this.requestMatcherRef)) {
requestMatcher = new RuntimeBeanReference(this.requestMatcherRef);
}
else {
requestMatcher = new RootBeanDefinition(DefaultRequiresCsrfMatcher.class);
}
BeanMetadataElement requestMatcher = (!StringUtils.hasText(this.requestMatcherRef))
? new RootBeanDefinition(DefaultRequiresCsrfMatcher.class)
: new RuntimeBeanReference(this.requestMatcherRef);
BeanDefinitionBuilder and = BeanDefinitionBuilder.rootBeanDefinition(AndRequestMatcher.class);
BeanDefinitionBuilder negated = BeanDefinitionBuilder.rootBeanDefinition(NegatedRequestMatcher.class);
BeanDefinitionBuilder or = BeanDefinitionBuilder.rootBeanDefinition(OrRequestMatcher.class);

View File

@ -58,7 +58,6 @@ public class DefaultFilterChainValidator implements FilterChainProxy.FilterChain
checkLoginPageIsntProtected(fcp, filterChain.getFilters());
checkFilterStack(filterChain.getFilters());
}
checkPathOrder(new ArrayList<>(fcp.getFilterChains()));
checkForDuplicateMatchers(new ArrayList<>(fcp.getFilterChains()));
}
@ -66,7 +65,6 @@ public class DefaultFilterChainValidator implements FilterChainProxy.FilterChain
private void checkPathOrder(List<SecurityFilterChain> filterChains) {
// Check that the universal pattern is listed at the end, if at all
Iterator<SecurityFilterChain> chains = filterChains.iterator();
while (chains.hasNext()) {
RequestMatcher matcher = ((DefaultSecurityFilterChain) chains.next()).getRequestMatcher();
if (AnyRequestMatcher.INSTANCE.equals(matcher) && chains.hasNext()) {
@ -78,10 +76,8 @@ public class DefaultFilterChainValidator implements FilterChainProxy.FilterChain
}
private void checkForDuplicateMatchers(List<SecurityFilterChain> chains) {
while (chains.size() > 1) {
DefaultSecurityFilterChain chain = (DefaultSecurityFilterChain) chains.remove(0);
for (SecurityFilterChain test : chains) {
if (chain.getRequestMatcher().equals(((DefaultSecurityFilterChain) test).getRequestMatcher())) {
throw new IllegalArgumentException("The FilterChainProxy contains two filter chains using the"
@ -99,7 +95,6 @@ public class DefaultFilterChainValidator implements FilterChainProxy.FilterChain
return (F) f;
}
}
return null;
}
@ -140,16 +135,13 @@ public class DefaultFilterChainValidator implements FilterChainProxy.FilterChain
*/
private void checkLoginPageIsntProtected(FilterChainProxy fcp, List<Filter> filterStack) {
ExceptionTranslationFilter etf = getFilter(ExceptionTranslationFilter.class, filterStack);
if (etf == null || !(etf.getAuthenticationEntryPoint() instanceof LoginUrlAuthenticationEntryPoint)) {
return;
}
String loginPage = ((LoginUrlAuthenticationEntryPoint) etf.getAuthenticationEntryPoint()).getLoginFormUrl();
this.logger.info("Checking whether login URL '" + loginPage + "' is accessible with your configuration");
FilterInvocation loginRequest = new FilterInvocation(loginPage, "POST");
List<Filter> filters = null;
try {
filters = fcp.getFilters(loginPage);
}
@ -159,22 +151,17 @@ public class DefaultFilterChainValidator implements FilterChainProxy.FilterChain
// by the dummy request used when creating the filter invocation.
this.logger.info("Failed to obtain filter chain information for the login page. Unable to complete check.");
}
if (filters == null || filters.isEmpty()) {
this.logger.debug("Filter chain is empty for the login page");
return;
}
if (getFilter(DefaultLoginPageGeneratingFilter.class, filters) != null) {
this.logger.debug("Default generated login page is in use");
return;
}
FilterSecurityInterceptor fsi = getFilter(FilterSecurityInterceptor.class, filters);
FilterInvocationSecurityMetadataSource fids = fsi.getSecurityMetadataSource();
Collection<ConfigAttribute> attributes = fids.getAttributes(loginRequest);
if (attributes == null) {
this.logger.debug("No access attributes defined for login page URL");
if (fsi.isRejectPublicInvocations()) {
@ -183,14 +170,12 @@ public class DefaultFilterChainValidator implements FilterChainProxy.FilterChain
}
return;
}
AnonymousAuthenticationFilter anonPF = getFilter(AnonymousAuthenticationFilter.class, filters);
if (anonPF == null) {
this.logger.warn("The login page is being protected by the filter chain, but you don't appear to have"
+ " anonymous authentication enabled. This is almost certainly an error.");
return;
}
// Simulate an anonymous access with the supplied attributes.
AnonymousAuthenticationToken token = new AnonymousAuthenticationToken("key", anonPF.getPrincipal(),
anonPF.getAuthorities());
@ -198,18 +183,16 @@ public class DefaultFilterChainValidator implements FilterChainProxy.FilterChain
fsi.getAccessDecisionManager().decide(token, loginRequest, attributes);
}
catch (AccessDeniedException ex) {
this.logger
.warn("Anonymous access to the login page doesn't appear to be enabled. This is almost certainly "
+ "an error. Please check your configuration allows unauthenticated access to the configured "
+ "login page. (Simulated access was rejected: " + ex + ")");
this.logger.warn("Anonymous access to the login page doesn't appear to be enabled. "
+ "This is almost certainly an error. Please check your configuration allows unauthenticated "
+ "access to the configured login page. (Simulated access was rejected: " + ex + ")");
}
catch (Exception ex) {
// May happen legitimately if a filter-chain request matcher requires more
// request data than that provided
// by the dummy request used when creating the filter invocation. See SEC-1878
this.logger.info(
"Unable to check access to the login page to determine if anonymous access is allowed. This might be an error, but can happen under normal circumstances.",
ex);
this.logger.info("Unable to check access to the login page to determine if anonymous access is allowed. "
+ "This might be an error, but can happen under normal circumstances.", ex);
}
}

View File

@ -43,9 +43,7 @@ public class FilterChainBeanDefinitionParser implements BeanDefinitionParser {
String path = elt.getAttribute(HttpSecurityBeanDefinitionParser.ATT_PATH_PATTERN);
String requestMatcher = elt.getAttribute(ATT_REQUEST_MATCHER_REF);
String filters = elt.getAttribute(HttpSecurityBeanDefinitionParser.ATT_FILTERS);
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(DefaultSecurityFilterChain.class);
if (StringUtils.hasText(path)) {
Assert.isTrue(!StringUtils.hasText(requestMatcher), "");
builder.addConstructorArgValue(matcherType.createMatcher(pc, path, null));
@ -54,21 +52,17 @@ public class FilterChainBeanDefinitionParser implements BeanDefinitionParser {
Assert.isTrue(StringUtils.hasText(requestMatcher), "");
builder.addConstructorArgReference(requestMatcher);
}
if (filters.equals(HttpSecurityBeanDefinitionParser.OPT_FILTERS_NONE)) {
builder.addConstructorArgValue(Collections.EMPTY_LIST);
}
else {
String[] filterBeanNames = StringUtils.tokenizeToStringArray(filters, ",");
ManagedList<RuntimeBeanReference> filterChain = new ManagedList<>(filterBeanNames.length);
for (String name : filterBeanNames) {
filterChain.add(new RuntimeBeanReference(name));
}
builder.addConstructorArgValue(filterChain);
}
return builder.getBeanDefinition();
}

View File

@ -45,48 +45,36 @@ public class FilterChainMapBeanDefinitionDecorator implements BeanDefinitionDeco
@SuppressWarnings("unchecked")
public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder holder, ParserContext parserContext) {
BeanDefinition filterChainProxy = holder.getBeanDefinition();
ManagedList<BeanMetadataElement> securityFilterChains = new ManagedList<>();
Element elt = (Element) node;
MatcherType matcherType = MatcherType.fromElement(elt);
List<Element> filterChainElts = DomUtils.getChildElementsByTagName(elt, Elements.FILTER_CHAIN);
for (Element chain : filterChainElts) {
String path = chain.getAttribute(HttpSecurityBeanDefinitionParser.ATT_PATH_PATTERN);
String filters = chain.getAttribute(HttpSecurityBeanDefinitionParser.ATT_FILTERS);
if (!StringUtils.hasText(path)) {
parserContext.getReaderContext().error(
"The attribute '" + HttpSecurityBeanDefinitionParser.ATT_PATH_PATTERN + "' must not be empty",
elt);
}
if (!StringUtils.hasText(filters)) {
parserContext.getReaderContext().error(
"The attribute '" + HttpSecurityBeanDefinitionParser.ATT_FILTERS + "'must not be empty", elt);
}
BeanDefinition matcher = matcherType.createMatcher(parserContext, path, null);
if (filters.equals(HttpSecurityBeanDefinitionParser.OPT_FILTERS_NONE)) {
securityFilterChains.add(createSecurityFilterChain(matcher, new ManagedList(0)));
}
else {
String[] filterBeanNames = StringUtils.tokenizeToStringArray(filters, ",");
ManagedList filterChain = new ManagedList(filterBeanNames.length);
for (String name : filterBeanNames) {
filterChain.add(new RuntimeBeanReference(name));
}
securityFilterChains.add(createSecurityFilterChain(matcher, filterChain));
}
}
filterChainProxy.getConstructorArgumentValues().addGenericArgumentValue(securityFilterChains);
return holder;
}

View File

@ -64,35 +64,28 @@ public class FilterInvocationSecurityMetadataSourceParser implements BeanDefinit
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
List<Element> interceptUrls = DomUtils.getChildElementsByTagName(element, Elements.INTERCEPT_URL);
// Check for attributes that aren't allowed in this context
for (Element elt : interceptUrls) {
if (StringUtils.hasLength(elt.getAttribute(HttpSecurityBeanDefinitionParser.ATT_REQUIRES_CHANNEL))) {
parserContext.getReaderContext().error("The attribute '"
+ HttpSecurityBeanDefinitionParser.ATT_REQUIRES_CHANNEL + "' isn't allowed here.", elt);
}
if (StringUtils.hasLength(elt.getAttribute(HttpSecurityBeanDefinitionParser.ATT_FILTERS))) {
parserContext.getReaderContext().error(
"The attribute '" + HttpSecurityBeanDefinitionParser.ATT_FILTERS + "' isn't allowed here.",
elt);
}
if (StringUtils.hasLength(elt.getAttribute(ATT_SERVLET_PATH))) {
parserContext.getReaderContext().error("The attribute '" + ATT_SERVLET_PATH + "' isn't allowed here.",
elt);
}
}
BeanDefinition mds = createSecurityMetadataSource(interceptUrls, false, element, parserContext);
String id = element.getAttribute(AbstractBeanDefinitionParser.ID_ATTRIBUTE);
if (StringUtils.hasText(id)) {
parserContext.registerComponent(new BeanComponentDefinition(mds, id));
parserContext.getRegistry().registerBeanDefinition(id, mds);
}
return mds;
}
@ -100,24 +93,20 @@ public class FilterInvocationSecurityMetadataSourceParser implements BeanDefinit
Element httpElt, ParserContext pc) {
MatcherType matcherType = MatcherType.fromElement(httpElt);
boolean useExpressions = isUseExpressions(httpElt);
ManagedMap<BeanMetadataElement, BeanDefinition> requestToAttributesMap = parseInterceptUrlsForFilterInvocationRequestMap(
matcherType, interceptUrls, useExpressions, addAllAuth, pc);
BeanDefinitionBuilder fidsBuilder;
if (useExpressions) {
Element expressionHandlerElt = DomUtils.getChildElementByTagName(httpElt, Elements.EXPRESSION_HANDLER);
String expressionHandlerRef = (expressionHandlerElt != null) ? expressionHandlerElt.getAttribute("ref")
: null;
if (StringUtils.hasText(expressionHandlerRef)) {
logger.info(
"Using bean '" + expressionHandlerRef + "' as web SecurityExpressionHandler implementation");
logger.info("Using bean '" + expressionHandlerRef + "' as web "
+ "SecurityExpressionHandler implementation");
}
else {
expressionHandlerRef = registerDefaultExpressionHandler(pc);
}
fidsBuilder = BeanDefinitionBuilder
.rootBeanDefinition(ExpressionBasedFilterInvocationSecurityMetadataSource.class);
fidsBuilder.addConstructorArgValue(requestToAttributesMap);
@ -127,9 +116,7 @@ public class FilterInvocationSecurityMetadataSourceParser implements BeanDefinit
fidsBuilder = BeanDefinitionBuilder.rootBeanDefinition(DefaultFilterInvocationSecurityMetadataSource.class);
fidsBuilder.addConstructorArgValue(requestToAttributesMap);
}
fidsBuilder.getRawBeanDefinition().setSource(pc.extractSource(httpElt));
return (RootBeanDefinition) fidsBuilder.getBeanDefinition();
}
@ -138,7 +125,6 @@ public class FilterInvocationSecurityMetadataSourceParser implements BeanDefinit
DefaultWebSecurityExpressionHandlerBeanFactory.class);
String expressionHandlerRef = pc.getReaderContext().generateBeanName(expressionHandler);
pc.registerBeanComponent(new BeanComponentDefinition(expressionHandler, expressionHandlerRef));
return expressionHandlerRef;
}
@ -150,28 +136,22 @@ public class FilterInvocationSecurityMetadataSourceParser implements BeanDefinit
private static ManagedMap<BeanMetadataElement, BeanDefinition> parseInterceptUrlsForFilterInvocationRequestMap(
MatcherType matcherType, List<Element> urlElts, boolean useExpressions, boolean addAuthenticatedAll,
ParserContext parserContext) {
ManagedMap<BeanMetadataElement, BeanDefinition> filterInvocationDefinitionMap = new ManagedMap<>();
for (Element urlElt : urlElts) {
String access = urlElt.getAttribute(ATT_ACCESS);
if (!StringUtils.hasText(access)) {
continue;
}
String path = urlElt.getAttribute(ATT_PATTERN);
String matcherRef = urlElt.getAttribute(HttpSecurityBeanDefinitionParser.ATT_REQUEST_MATCHER_REF);
boolean hasMatcherRef = StringUtils.hasText(matcherRef);
if (!hasMatcherRef && !StringUtils.hasText(path)) {
parserContext.getReaderContext().error("path attribute cannot be empty or null", urlElt);
}
String method = urlElt.getAttribute(ATT_HTTP_METHOD);
if (!StringUtils.hasText(method)) {
method = null;
}
String servletPath = urlElt.getAttribute(ATT_SERVLET_PATH);
if (!StringUtils.hasText(servletPath)) {
servletPath = null;
@ -181,11 +161,9 @@ public class FilterInvocationSecurityMetadataSourceParser implements BeanDefinit
ATT_SERVLET_PATH + " is not applicable for request-matcher: '" + matcherType.name() + "'",
urlElt);
}
BeanMetadataElement matcher = hasMatcherRef ? new RuntimeBeanReference(matcherRef)
: matcherType.createMatcher(parserContext, path, method, servletPath);
BeanDefinitionBuilder attributeBuilder = BeanDefinitionBuilder.rootBeanDefinition(SecurityConfig.class);
if (useExpressions) {
logger.info("Creating access control expression attribute '" + access + "' for " + path);
// The single expression will be parsed later by the
@ -198,23 +176,18 @@ public class FilterInvocationSecurityMetadataSourceParser implements BeanDefinit
attributeBuilder.addConstructorArgValue(access);
attributeBuilder.setFactoryMethod("createListFromCommaDelimitedString");
}
if (filterInvocationDefinitionMap.containsKey(matcher)) {
logger.warn("Duplicate URL defined: " + path + ". The original attribute values will be overwritten");
}
filterInvocationDefinitionMap.put(matcher, attributeBuilder.getBeanDefinition());
}
if (addAuthenticatedAll && filterInvocationDefinitionMap.isEmpty()) {
BeanDefinition matcher = matcherType.createMatcher(parserContext, "/**", null);
BeanDefinitionBuilder attributeBuilder = BeanDefinitionBuilder.rootBeanDefinition(SecurityConfig.class);
attributeBuilder.addConstructorArgValue(new String[] { "authenticated" });
attributeBuilder.setFactoryMethod("createList");
filterInvocationDefinitionMap.put(matcher, attributeBuilder.getBeanDefinition());
}
return filterInvocationDefinitionMap;
}

View File

@ -123,9 +123,7 @@ public class FormLoginBeanDefinitionParser {
String authDetailsSourceRef = null;
String authenticationFailureForwardUrl = null;
String authenticationSuccessForwardUrl = null;
Object source = null;
if (elt != null) {
source = pc.extractSource(elt);
loginUrl = elt.getAttribute(ATT_LOGIN_URL);
@ -143,7 +141,6 @@ public class FormLoginBeanDefinitionParser {
WebConfigUtils.validateHttpRedirect(authenticationFailureForwardUrl, pc, source);
authenticationSuccessForwardUrl = elt.getAttribute(ATT_FORM_LOGIN_AUTHENTICATION_SUCCESS_FORWARD_URL);
WebConfigUtils.validateHttpRedirect(authenticationSuccessForwardUrl, pc, source);
if (!StringUtils.hasText(this.loginPage)) {
this.loginPage = null;
}
@ -151,20 +148,16 @@ public class FormLoginBeanDefinitionParser {
usernameParameter = elt.getAttribute(ATT_USERNAME_PARAMETER);
passwordParameter = elt.getAttribute(ATT_PASSWORD_PARAMETER);
}
this.filterBean = createFilterBean(loginUrl, defaultTargetUrl, alwaysUseDefault, this.loginPage,
authenticationFailureUrl, successHandlerRef, failureHandlerRef, authDetailsSourceRef,
authenticationFailureForwardUrl, authenticationSuccessForwardUrl);
if (StringUtils.hasText(usernameParameter)) {
this.filterBean.getPropertyValues().addPropertyValue("usernameParameter", usernameParameter);
}
if (StringUtils.hasText(passwordParameter)) {
this.filterBean.getPropertyValues().addPropertyValue("passwordParameter", passwordParameter);
}
this.filterBean.setSource(source);
BeanDefinitionBuilder entryPointBuilder = BeanDefinitionBuilder
.rootBeanDefinition(LoginUrlAuthenticationEntryPoint.class);
entryPointBuilder.getRawBeanDefinition().setSource(source);
@ -172,7 +165,6 @@ public class FormLoginBeanDefinitionParser {
entryPointBuilder.addPropertyValue("portMapper", this.portMapper);
entryPointBuilder.addPropertyValue("portResolver", this.portResolver);
this.entryPointBean = (RootBeanDefinition) entryPointBuilder.getBeanDefinition();
return null;
}
@ -180,24 +172,18 @@ public class FormLoginBeanDefinitionParser {
String loginPage, String authenticationFailureUrl, String successHandlerRef, String failureHandlerRef,
String authDetailsSourceRef, String authenticationFailureForwardUrl,
String authenticationSuccessForwardUrl) {
BeanDefinitionBuilder filterBuilder = BeanDefinitionBuilder.rootBeanDefinition(this.filterClassName);
if (!StringUtils.hasText(loginUrl)) {
loginUrl = this.defaultLoginProcessingUrl;
}
this.loginProcessingUrl = loginUrl;
BeanDefinitionBuilder matcherBuilder = BeanDefinitionBuilder
.rootBeanDefinition("org.springframework.security.web.util.matcher.AntPathRequestMatcher");
matcherBuilder.addConstructorArgValue(loginUrl);
if (this.loginMethod != null) {
matcherBuilder.addConstructorArgValue("POST");
}
filterBuilder.addPropertyValue("requiresAuthenticationRequestMatcher", matcherBuilder.getBeanDefinition());
if (StringUtils.hasText(successHandlerRef)) {
filterBuilder.addPropertyReference("authenticationSuccessHandler", successHandlerRef);
}
@ -218,15 +204,12 @@ public class FormLoginBeanDefinitionParser {
StringUtils.hasText(defaultTargetUrl) ? defaultTargetUrl : DEF_FORM_LOGIN_TARGET_URL);
filterBuilder.addPropertyValue("authenticationSuccessHandler", successHandler.getBeanDefinition());
}
if (StringUtils.hasText(authDetailsSourceRef)) {
filterBuilder.addPropertyReference("authenticationDetailsSource", authDetailsSourceRef);
}
if (this.sessionStrategy != null) {
filterBuilder.addPropertyValue("sessionAuthenticationStrategy", this.sessionStrategy);
}
if (StringUtils.hasText(failureHandlerRef)) {
filterBuilder.addPropertyReference("authenticationFailureHandler", failureHandlerRef);
}
@ -252,7 +235,6 @@ public class FormLoginBeanDefinitionParser {
failureHandler.addPropertyValue("allowSessionCreation", this.allowSessionCreation);
filterBuilder.addPropertyValue("authenticationFailureHandler", failureHandler.getBeanDefinition());
}
return (RootBeanDefinition) filterBuilder.getBeanDefinition();
}

View File

@ -37,7 +37,6 @@ final class GrantedAuthorityDefaultsParserUtils {
RootBeanDefinition beanFactoryDefinition = new RootBeanDefinition(beanFactoryClass);
String beanFactoryRef = pc.getReaderContext().generateBeanName(beanFactoryDefinition);
pc.getRegistry().registerBeanDefinition(beanFactoryRef, beanFactoryDefinition);
RootBeanDefinition bean = new RootBeanDefinition();
bean.setFactoryBeanName(beanFactoryRef);
bean.setFactoryMethodName("getBean");

View File

@ -41,9 +41,11 @@ class HandlerMappingIntrospectorFactoryBean
@Override
public HandlerMappingIntrospector getObject() {
if (!this.context.containsBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME)) {
throw new NoSuchBeanDefinitionException(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME, "A Bean named "
+ HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME + " of type " + HandlerMappingIntrospector.class.getName()
+ " is required to use MvcRequestMatcher. Please ensure Spring Security & Spring MVC are configured in a shared ApplicationContext.");
throw new NoSuchBeanDefinitionException(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME,
"A Bean named " + HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME + " of type "
+ HandlerMappingIntrospector.class.getName()
+ " is required to use MvcRequestMatcher. Please ensure Spring Security & Spring "
+ "MVC are configured in a shared ApplicationContext.");
}
return this.context.getBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME, HandlerMappingIntrospector.class);
}

View File

@ -125,32 +125,22 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
this.headerWriters = new ManagedList<>();
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(HeaderWriterFilter.class);
boolean disabled = element != null && "true".equals(resolveAttribute(parserContext, element, "disabled"));
boolean defaultsDisabled = element != null
&& "true".equals(resolveAttribute(parserContext, element, "defaults-disabled"));
boolean addIfNotPresent = element == null || !disabled && !defaultsDisabled;
parseCacheControlElement(addIfNotPresent, element);
parseHstsElement(addIfNotPresent, element, parserContext);
parseXssElement(addIfNotPresent, element, parserContext);
parseFrameOptionsElement(addIfNotPresent, element, parserContext);
parseContentTypeOptionsElement(addIfNotPresent, element);
parseHpkpElement(element == null || !disabled, element, parserContext);
parseContentSecurityPolicyElement(disabled, element, parserContext);
parseReferrerPolicyElement(element, parserContext);
parseFeaturePolicyElement(element, parserContext);
parseHeaderElements(element);
boolean noWriters = this.headerWriters.isEmpty();
if (disabled && !noWriters) {
parserContext.getReaderContext().error("Cannot specify <headers disabled=\"true\"> with child elements.",
@ -159,13 +149,11 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
else if (noWriters) {
return null;
}
builder.addConstructorArgValue(this.headerWriters);
return builder.getBeanDefinition();
}
/**
*
* Resolve the placeholder for a given attribute on a element.
* @param pc
* @param element
@ -233,7 +221,6 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
}
headersWriter.addPropertyValue("preload", preload);
}
if (disabled) {
return;
}
@ -253,59 +240,45 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
private void addHpkp(boolean addIfNotPresent, Element hpkpElement, ParserContext context) {
if (hpkpElement != null) {
boolean disabled = "true".equals(getAttribute(hpkpElement, ATT_DISABLED, "false"));
if (disabled) {
return;
}
BeanDefinitionBuilder headersWriter = BeanDefinitionBuilder.genericBeanDefinition(HpkpHeaderWriter.class);
Element pinsElement = DomUtils.getChildElementByTagName(hpkpElement, PINS_ELEMENT);
if (pinsElement != null) {
List<Element> pinElements = DomUtils.getChildElements(pinsElement);
Map<String, String> pins = new LinkedHashMap<>();
for (Element pinElement : pinElements) {
String hash = pinElement.getAttribute(ATT_ALGORITHM);
if (!StringUtils.hasText(hash)) {
hash = "sha256";
}
Node pinValueNode = pinElement.getFirstChild();
if (pinValueNode == null) {
context.getReaderContext().warning("Missing value for pin entry.", hpkpElement);
continue;
}
String fingerprint = pinElement.getFirstChild().getTextContent();
pins.put(fingerprint, hash);
}
headersWriter.addPropertyValue("pins", pins);
}
String includeSubDomains = hpkpElement.getAttribute(ATT_INCLUDE_SUBDOMAINS);
if (StringUtils.hasText(includeSubDomains)) {
headersWriter.addPropertyValue("includeSubDomains", includeSubDomains);
}
String maxAgeSeconds = hpkpElement.getAttribute(ATT_MAX_AGE_SECONDS);
if (StringUtils.hasText(maxAgeSeconds)) {
headersWriter.addPropertyValue("maxAgeInSeconds", maxAgeSeconds);
}
String reportOnly = hpkpElement.getAttribute(ATT_REPORT_ONLY);
if (StringUtils.hasText(reportOnly)) {
headersWriter.addPropertyValue("reportOnly", reportOnly);
}
String reportUri = hpkpElement.getAttribute(ATT_REPORT_URI);
if (StringUtils.hasText(reportUri)) {
headersWriter.addPropertyValue("reportUri", reportUri);
}
if (addIfNotPresent) {
this.headerWriters.add(headersWriter.getBeanDefinition());
}
@ -323,7 +296,6 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
private void addContentSecurityPolicy(Element contentSecurityPolicyElement, ParserContext context) {
BeanDefinitionBuilder headersWriter = BeanDefinitionBuilder
.genericBeanDefinition(ContentSecurityPolicyHeaderWriter.class);
String policyDirectives = contentSecurityPolicyElement.getAttribute(ATT_POLICY_DIRECTIVES);
if (!StringUtils.hasText(policyDirectives)) {
context.getReaderContext().error(ATT_POLICY_DIRECTIVES + " requires a 'value' to be set.",
@ -332,12 +304,10 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
else {
headersWriter.addConstructorArgValue(policyDirectives);
}
String reportOnly = contentSecurityPolicyElement.getAttribute(ATT_REPORT_ONLY);
if (StringUtils.hasText(reportOnly)) {
headersWriter.addPropertyValue("reportOnly", reportOnly);
}
this.headerWriters.add(headersWriter.getBeanDefinition());
}
@ -352,7 +322,6 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
private void addReferrerPolicy(Element referrerPolicyElement, ParserContext context) {
BeanDefinitionBuilder headersWriter = BeanDefinitionBuilder
.genericBeanDefinition(ReferrerPolicyHeaderWriter.class);
String policy = referrerPolicyElement.getAttribute(ATT_POLICY);
if (StringUtils.hasLength(policy)) {
headersWriter.addConstructorArgValue(ReferrerPolicy.get(policy));
@ -371,7 +340,6 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
private void addFeaturePolicy(Element featurePolicyElement, ParserContext context) {
BeanDefinitionBuilder headersWriter = BeanDefinitionBuilder
.genericBeanDefinition(FeaturePolicyHeaderWriter.class);
String policyDirectives = featurePolicyElement.getAttribute(ATT_POLICY_DIRECTIVES);
if (!StringUtils.hasText(policyDirectives)) {
context.getReaderContext().error(ATT_POLICY_DIRECTIVES + " requires a 'value' to be set.",
@ -380,7 +348,6 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
else {
headersWriter.addConstructorArgValue(policyDirectives);
}
this.headerWriters.add(headersWriter.getBeanDefinition());
}
@ -508,7 +475,6 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(XXssProtectionHeaderWriter.class);
if (xssElt != null) {
boolean disabled = "true".equals(getAttribute(xssElt, ATT_DISABLED, "false"));
String enabled = xssElt.getAttribute(ATT_ENABLED);
if (StringUtils.hasText(enabled)) {
if (disabled) {
@ -516,7 +482,6 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
}
builder.addPropertyValue("enabled", enabled);
}
String block = xssElt.getAttribute(ATT_BLOCK);
if (StringUtils.hasText(block)) {
if (disabled) {
@ -524,7 +489,6 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
}
builder.addPropertyValue("block", block);
}
if (disabled) {
return;
}
@ -542,9 +506,7 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
if (StringUtils.hasText(value)) {
return value;
}
else {
return defaultValue;
}
return defaultValue;
}
}

View File

@ -71,6 +71,7 @@ import org.springframework.security.web.session.SessionManagementFilter;
import org.springframework.security.web.session.SimpleRedirectInvalidSessionStrategy;
import org.springframework.security.web.session.SimpleRedirectSessionInformationExpiredStrategy;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
@ -113,6 +114,22 @@ class HttpConfigurationBuilder {
private static final String ATT_REF = "ref";
private static final String ATT_EXPIRY_URL = "expired-url";
private static final String ATT_EXPIRED_SESSION_STRATEGY_REF = "expired-session-strategy-ref";
private static final String ATT_SESSION_REGISTRY_ALIAS = "session-registry-alias";
private static final String ATT_SESSION_REGISTRY_REF = "session-registry-ref";
private static final String ATT_SERVLET_API_PROVISION = "servlet-api-provision";
private static final String DEF_SERVLET_API_PROVISION = "true";
private static final String ATT_JAAS_API_PROVISION = "jaas-api-provision";
private static final String DEF_JAAS_API_PROVISION = "false";
private final Element httpElt;
private final ParserContext pc;
@ -178,25 +195,10 @@ class HttpConfigurationBuilder {
this.portResolver = portResolver;
this.matcherType = MatcherType.fromElement(element);
this.interceptUrls = DomUtils.getChildElementsByTagName(element, Elements.INTERCEPT_URL);
for (Element urlElt : this.interceptUrls) {
if (StringUtils.hasText(urlElt.getAttribute(HttpSecurityBeanDefinitionParser.ATT_FILTERS))) {
pc.getReaderContext()
.error("The use of \"filters='none'\" is no longer supported. Please define a"
+ " separate <http> element for the pattern you want to exclude and use the attribute"
+ " \"security='none'\".", pc.extractSource(urlElt));
}
}
validateInterceptUrls(pc);
String createSession = element.getAttribute(ATT_CREATE_SESSION);
if (StringUtils.hasText(createSession)) {
this.sessionPolicy = createPolicy(createSession);
}
else {
this.sessionPolicy = SessionCreationPolicy.IF_REQUIRED;
}
this.sessionPolicy = !StringUtils.hasText(createSession) ? SessionCreationPolicy.IF_REQUIRED
: createPolicy(createSession);
createCsrfFilter();
createSecurityContextPersistenceFilter();
createSessionManagementFilters();
@ -210,20 +212,30 @@ class HttpConfigurationBuilder {
createCorsFilter();
}
private void validateInterceptUrls(ParserContext pc) {
for (Element element : this.interceptUrls) {
if (StringUtils.hasText(element.getAttribute(HttpSecurityBeanDefinitionParser.ATT_FILTERS))) {
String message = "The use of \"filters='none'\" is no longer supported. Please define a"
+ " separate <http> element for the pattern you want to exclude and use the attribute"
+ " \"security='none'\".";
pc.getReaderContext().error(message, pc.extractSource(element));
}
}
}
private SessionCreationPolicy createPolicy(String createSession) {
if ("ifRequired".equals(createSession)) {
return SessionCreationPolicy.IF_REQUIRED;
}
else if ("always".equals(createSession)) {
if ("always".equals(createSession)) {
return SessionCreationPolicy.ALWAYS;
}
else if ("never".equals(createSession)) {
if ("never".equals(createSession)) {
return SessionCreationPolicy.NEVER;
}
else if ("stateless".equals(createSession)) {
if ("stateless".equals(createSession)) {
return SessionCreationPolicy.STATELESS;
}
throw new IllegalStateException(
"Cannot convert " + createSession + " to " + SessionCreationPolicy.class.getName());
}
@ -265,13 +277,11 @@ class HttpConfigurationBuilder {
private void createSecurityContextPersistenceFilter() {
BeanDefinitionBuilder scpf = BeanDefinitionBuilder.rootBeanDefinition(SecurityContextPersistenceFilter.class);
String repoRef = this.httpElt.getAttribute(ATT_SECURITY_CONTEXT_REPOSITORY);
String disableUrlRewriting = this.httpElt.getAttribute(ATT_DISABLE_URL_REWRITING);
if (!StringUtils.hasText(disableUrlRewriting)) {
disableUrlRewriting = "true";
}
if (StringUtils.hasText(repoRef)) {
if (this.sessionPolicy == SessionCreationPolicy.ALWAYS) {
scpf.addPropertyValue("forceEagerSessionCreation", Boolean.TRUE);
@ -297,12 +307,10 @@ class HttpConfigurationBuilder {
contextRepo.addPropertyValue("allowSessionCreation", Boolean.TRUE);
scpf.addPropertyValue("forceEagerSessionCreation", Boolean.FALSE);
}
if ("true".equals(disableUrlRewriting)) {
contextRepo.addPropertyValue("disableUrlRewriting", Boolean.TRUE);
}
}
BeanDefinition repoBean = contextRepo.getBeanDefinition();
repoRef = this.pc.getReaderContext().generateBeanName(repoBean);
this.pc.registerBeanComponent(new BeanComponentDefinition(repoBean, repoRef));
@ -317,13 +325,11 @@ class HttpConfigurationBuilder {
private void createSessionManagementFilters() {
Element sessionMgmtElt = DomUtils.getChildElementByTagName(this.httpElt, Elements.SESSION_MANAGEMENT);
Element sessionCtrlElt = null;
String sessionFixationAttribute = null;
String invalidSessionUrl = null;
String invalidSessionStrategyRef = null;
String sessionAuthStratRef = null;
String errorUrl = null;
boolean sessionControlEnabled = false;
if (sessionMgmtElt != null) {
if (this.sessionPolicy == SessionCreationPolicy.STATELESS) {
@ -335,18 +341,15 @@ class HttpConfigurationBuilder {
sessionFixationAttribute = sessionMgmtElt.getAttribute(ATT_SESSION_FIXATION_PROTECTION);
invalidSessionUrl = sessionMgmtElt.getAttribute(ATT_INVALID_SESSION_URL);
invalidSessionStrategyRef = sessionMgmtElt.getAttribute(ATT_INVALID_SESSION_STRATEGY_REF);
sessionAuthStratRef = sessionMgmtElt.getAttribute(ATT_SESSION_AUTH_STRATEGY_REF);
errorUrl = sessionMgmtElt.getAttribute(ATT_SESSION_AUTH_ERROR_URL);
sessionCtrlElt = DomUtils.getChildElementByTagName(sessionMgmtElt, Elements.CONCURRENT_SESSIONS);
sessionControlEnabled = sessionCtrlElt != null;
if (StringUtils.hasText(invalidSessionUrl) && StringUtils.hasText(invalidSessionStrategyRef)) {
this.pc.getReaderContext()
.error(ATT_INVALID_SESSION_URL + " attribute cannot be used in combination with" + " the "
+ ATT_INVALID_SESSION_STRATEGY_REF + " attribute.", sessionMgmtElt);
}
if (sessionControlEnabled) {
if (StringUtils.hasText(sessionAuthStratRef)) {
this.pc.getReaderContext()
@ -370,33 +373,25 @@ class HttpConfigurationBuilder {
// SEC-1424: do nothing
return;
}
boolean sessionFixationProtectionRequired = !sessionFixationAttribute
.equals(OPT_SESSION_FIXATION_NO_PROTECTION);
ManagedList<BeanMetadataElement> delegateSessionStrategies = new ManagedList<>();
BeanDefinitionBuilder concurrentSessionStrategy;
BeanDefinitionBuilder sessionFixationStrategy = null;
BeanDefinitionBuilder registerSessionStrategy;
if (this.csrfAuthStrategy != null) {
delegateSessionStrategies.add(this.csrfAuthStrategy);
}
if (sessionControlEnabled) {
assert this.sessionRegistryRef != null;
Assert.state(this.sessionRegistryRef != null, "No sessionRegistryRef found");
concurrentSessionStrategy = BeanDefinitionBuilder
.rootBeanDefinition(ConcurrentSessionControlAuthenticationStrategy.class);
concurrentSessionStrategy.addConstructorArgValue(this.sessionRegistryRef);
String maxSessions = sessionCtrlElt.getAttribute("max-sessions");
if (StringUtils.hasText(maxSessions)) {
concurrentSessionStrategy.addPropertyValue("maximumSessions", maxSessions);
}
String exceptionIfMaximumExceeded = sessionCtrlElt.getAttribute("error-if-maximum-exceeded");
if (StringUtils.hasText(exceptionIfMaximumExceeded)) {
concurrentSessionStrategy.addPropertyValue("exceptionIfMaximumExceeded", exceptionIfMaximumExceeded);
}
@ -414,23 +409,19 @@ class HttpConfigurationBuilder {
}
delegateSessionStrategies.add(sessionFixationStrategy.getBeanDefinition());
}
if (StringUtils.hasText(sessionAuthStratRef)) {
delegateSessionStrategies.add(new RuntimeBeanReference(sessionAuthStratRef));
}
if (sessionControlEnabled) {
registerSessionStrategy = BeanDefinitionBuilder
.rootBeanDefinition(RegisterSessionAuthenticationStrategy.class);
registerSessionStrategy.addConstructorArgValue(this.sessionRegistryRef);
delegateSessionStrategies.add(registerSessionStrategy.getBeanDefinition());
}
if (delegateSessionStrategies.isEmpty()) {
this.sfpf = null;
return;
}
BeanDefinitionBuilder sessionMgmtFilter = BeanDefinitionBuilder
.rootBeanDefinition(SessionManagementFilter.class);
RootBeanDefinition failureHandler = new RootBeanDefinition(SimpleUrlAuthenticationFailureHandler.class);
@ -439,15 +430,12 @@ class HttpConfigurationBuilder {
}
sessionMgmtFilter.addPropertyValue("authenticationFailureHandler", failureHandler);
sessionMgmtFilter.addConstructorArgValue(this.contextRepoRef);
if (!StringUtils.hasText(sessionAuthStratRef) && sessionFixationStrategy != null && !useChangeSessionId) {
if (sessionFixationProtectionRequired) {
sessionFixationStrategy.addPropertyValue("migrateSessionAttributes",
sessionFixationAttribute.equals(OPT_SESSION_FIXATION_MIGRATE_SESSION));
}
}
if (!delegateSessionStrategies.isEmpty()) {
BeanDefinitionBuilder sessionStrategy = BeanDefinitionBuilder
.rootBeanDefinition(CompositeSessionAuthenticationStrategy.class);
@ -455,9 +443,7 @@ class HttpConfigurationBuilder {
sessionStrategy.addConstructorArgValue(delegateSessionStrategies);
sessionAuthStratRef = this.pc.getReaderContext().generateBeanName(strategyBean);
this.pc.registerBeanComponent(new BeanComponentDefinition(strategyBean, sessionAuthStratRef));
}
if (StringUtils.hasText(invalidSessionUrl)) {
BeanDefinitionBuilder invalidSessionBldr = BeanDefinitionBuilder
.rootBeanDefinition(SimpleRedirectInvalidSessionStrategy.class);
@ -468,55 +454,39 @@ class HttpConfigurationBuilder {
else if (StringUtils.hasText(invalidSessionStrategyRef)) {
sessionMgmtFilter.addPropertyReference("invalidSessionStrategy", invalidSessionStrategyRef);
}
sessionMgmtFilter.addConstructorArgReference(sessionAuthStratRef);
this.sfpf = (RootBeanDefinition) sessionMgmtFilter.getBeanDefinition();
this.sessionStrategyRef = new RuntimeBeanReference(sessionAuthStratRef);
}
private void createConcurrencyControlFilterAndSessionRegistry(Element element) {
final String ATT_EXPIRY_URL = "expired-url";
final String ATT_EXPIRED_SESSION_STRATEGY_REF = "expired-session-strategy-ref";
final String ATT_SESSION_REGISTRY_ALIAS = "session-registry-alias";
final String ATT_SESSION_REGISTRY_REF = "session-registry-ref";
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(),
this.pc.extractSource(element));
this.pc.pushContainingComponent(compositeDef);
BeanDefinitionRegistry beanRegistry = this.pc.getRegistry();
String sessionRegistryId = element.getAttribute(ATT_SESSION_REGISTRY_REF);
if (!StringUtils.hasText(sessionRegistryId)) {
// Register an internal SessionRegistryImpl if no external reference supplied.
RootBeanDefinition sessionRegistry = new RootBeanDefinition(SessionRegistryImpl.class);
sessionRegistryId = this.pc.getReaderContext().registerWithGeneratedName(sessionRegistry);
this.pc.registerComponent(new BeanComponentDefinition(sessionRegistry, sessionRegistryId));
}
String registryAlias = element.getAttribute(ATT_SESSION_REGISTRY_ALIAS);
if (StringUtils.hasText(registryAlias)) {
beanRegistry.registerAlias(sessionRegistryId, registryAlias);
}
BeanDefinitionBuilder filterBuilder = BeanDefinitionBuilder.rootBeanDefinition(ConcurrentSessionFilter.class);
filterBuilder.addConstructorArgReference(sessionRegistryId);
Object source = this.pc.extractSource(element);
filterBuilder.getRawBeanDefinition().setSource(source);
filterBuilder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
String expiryUrl = element.getAttribute(ATT_EXPIRY_URL);
String expiredSessionStrategyRef = element.getAttribute(ATT_EXPIRED_SESSION_STRATEGY_REF);
if (StringUtils.hasText(expiryUrl) && StringUtils.hasText(expiredSessionStrategyRef)) {
this.pc.getReaderContext().error(
"Cannot use 'expired-url' attribute and 'expired-session-strategy-ref'" + " attribute together.",
source);
}
if (StringUtils.hasText(expiryUrl)) {
BeanDefinitionBuilder expiredSessionBldr = BeanDefinitionBuilder
.rootBeanDefinition(SimpleRedirectSessionInformationExpiredStrategy.class);
@ -526,9 +496,7 @@ class HttpConfigurationBuilder {
else if (StringUtils.hasText(expiredSessionStrategyRef)) {
filterBuilder.addConstructorArgReference(expiredSessionStrategyRef);
}
this.pc.popAndRegisterContainingComponent();
this.concurrentSessionFilter = filterBuilder.getBeanDefinition();
this.sessionRegistryRef = new RuntimeBeanReference(sessionRegistryId);
}
@ -542,14 +510,10 @@ class HttpConfigurationBuilder {
// Adds the servlet-api integration filter if required
private void createServletApiFilter(BeanReference authenticationManager) {
final String ATT_SERVLET_API_PROVISION = "servlet-api-provision";
final String DEF_SERVLET_API_PROVISION = "true";
String provideServletApi = this.httpElt.getAttribute(ATT_SERVLET_API_PROVISION);
if (!StringUtils.hasText(provideServletApi)) {
provideServletApi = DEF_SERVLET_API_PROVISION;
}
if ("true".equals(provideServletApi)) {
this.servApiFilter = GrantedAuthorityDefaultsParserUtils.registerWithDefaultRolePrefix(this.pc,
SecurityContextHolderAwareRequestFilterBeanFactory.class);
@ -559,14 +523,10 @@ class HttpConfigurationBuilder {
// Adds the jaas-api integration filter if required
private void createJaasApiFilter() {
final String ATT_JAAS_API_PROVISION = "jaas-api-provision";
final String DEF_JAAS_API_PROVISION = "false";
String provideJaasApi = this.httpElt.getAttribute(ATT_JAAS_API_PROVISION);
if (!StringUtils.hasText(provideJaasApi)) {
provideJaasApi = DEF_JAAS_API_PROVISION;
}
if ("true".equals(provideJaasApi)) {
this.jaasApiFilter = new RootBeanDefinition(JaasApiIntegrationFilter.class);
}
@ -574,18 +534,13 @@ class HttpConfigurationBuilder {
private void createChannelProcessingFilter() {
ManagedMap<BeanMetadataElement, BeanDefinition> channelRequestMap = parseInterceptUrlsForChannelSecurity();
if (channelRequestMap.isEmpty()) {
return;
}
RootBeanDefinition channelFilter = new RootBeanDefinition(ChannelProcessingFilter.class);
BeanDefinitionBuilder metadataSourceBldr = BeanDefinitionBuilder
.rootBeanDefinition(DefaultFilterInvocationSecurityMetadataSource.class);
metadataSourceBldr.addConstructorArgValue(channelRequestMap);
// metadataSourceBldr.addPropertyValue("stripQueryStringFromUrls", matcher
// instanceof AntUrlPathMatcher);
channelFilter.getPropertyValues().addPropertyValue("securityMetadataSource",
metadataSourceBldr.getBeanDefinition());
RootBeanDefinition channelDecisionManager = new RootBeanDefinition(ChannelDecisionManagerImpl.class);
@ -593,7 +548,6 @@ class HttpConfigurationBuilder {
RootBeanDefinition secureChannelProcessor = new RootBeanDefinition(SecureChannelProcessor.class);
RootBeanDefinition retryWithHttp = new RootBeanDefinition(RetryWithHttpEntryPoint.class);
RootBeanDefinition retryWithHttps = new RootBeanDefinition(RetryWithHttpsEntryPoint.class);
retryWithHttp.getPropertyValues().addPropertyValue("portMapper", this.portMapper);
retryWithHttp.getPropertyValues().addPropertyValue("portResolver", this.portResolver);
retryWithHttps.getPropertyValues().addPropertyValue("portMapper", this.portMapper);
@ -604,7 +558,6 @@ class HttpConfigurationBuilder {
channelProcessors.add(secureChannelProcessor);
channelProcessors.add(inSecureChannelProcessor);
channelDecisionManager.getPropertyValues().addPropertyValue("channelProcessors", channelProcessors);
String id = this.pc.getReaderContext().registerWithGeneratedName(channelDecisionManager);
channelFilter.getPropertyValues().addPropertyValue("channelDecisionManager", new RuntimeBeanReference(id));
this.cpf = channelFilter;
@ -616,45 +569,35 @@ class HttpConfigurationBuilder {
* path.
*/
private ManagedMap<BeanMetadataElement, BeanDefinition> parseInterceptUrlsForChannelSecurity() {
ManagedMap<BeanMetadataElement, BeanDefinition> channelRequestMap = new ManagedMap<>();
for (Element urlElt : this.interceptUrls) {
String path = urlElt.getAttribute(HttpSecurityBeanDefinitionParser.ATT_PATH_PATTERN);
String method = urlElt.getAttribute(HttpSecurityBeanDefinitionParser.ATT_HTTP_METHOD);
String matcherRef = urlElt.getAttribute(HttpSecurityBeanDefinitionParser.ATT_REQUEST_MATCHER_REF);
boolean hasMatcherRef = StringUtils.hasText(matcherRef);
if (!hasMatcherRef && !StringUtils.hasText(path)) {
this.pc.getReaderContext().error("pattern attribute cannot be empty or null", urlElt);
}
String requiredChannel = urlElt.getAttribute(HttpSecurityBeanDefinitionParser.ATT_REQUIRES_CHANNEL);
if (StringUtils.hasText(requiredChannel)) {
BeanMetadataElement matcher = hasMatcherRef ? new RuntimeBeanReference(matcherRef)
: this.matcherType.createMatcher(this.pc, path, method);
RootBeanDefinition channelAttributes = new RootBeanDefinition(ChannelAttributeFactory.class);
channelAttributes.getConstructorArgumentValues().addGenericArgumentValue(requiredChannel);
channelAttributes.setFactoryMethodName("createChannelAttributes");
channelRequestMap.put(matcher, channelAttributes);
}
}
return channelRequestMap;
}
private void createRequestCacheFilter() {
Element requestCacheElt = DomUtils.getChildElementByTagName(this.httpElt, Elements.REQUEST_CACHE);
if (requestCacheElt != null) {
this.requestCache = new RuntimeBeanReference(requestCacheElt.getAttribute(ATT_REF));
}
else {
BeanDefinitionBuilder requestCacheBldr;
if (this.sessionPolicy == SessionCreationPolicy.STATELESS) {
requestCacheBldr = BeanDefinitionBuilder.rootBeanDefinition(NullRequestCache.class);
}
@ -671,14 +614,11 @@ class HttpConfigurationBuilder {
requestCacheBldr.addPropertyValue("requestMatcher", requestCacheMatcherBldr.getBeanDefinition());
}
}
BeanDefinition bean = requestCacheBldr.getBeanDefinition();
String id = this.pc.getReaderContext().generateBeanName(bean);
this.pc.registerBeanComponent(new BeanComponentDefinition(bean, id));
this.requestCache = new RuntimeBeanReference(id);
}
this.requestCacheAwareFilter = new RootBeanDefinition(RequestCacheAwareFilter.class);
this.requestCacheAwareFilter.getConstructorArgumentValues().addGenericArgumentValue(this.requestCache);
}
@ -687,18 +627,14 @@ class HttpConfigurationBuilder {
boolean useExpressions = FilterInvocationSecurityMetadataSourceParser.isUseExpressions(this.httpElt);
RootBeanDefinition securityMds = FilterInvocationSecurityMetadataSourceParser
.createSecurityMetadataSource(this.interceptUrls, this.addAllAuth, this.httpElt, this.pc);
RootBeanDefinition accessDecisionMgr;
ManagedList<BeanDefinition> voters = new ManagedList<>(2);
if (useExpressions) {
BeanDefinitionBuilder expressionVoter = BeanDefinitionBuilder.rootBeanDefinition(WebExpressionVoter.class);
// Read the expression handler from the FISMS
RuntimeBeanReference expressionHandler = (RuntimeBeanReference) securityMds.getConstructorArgumentValues()
.getArgumentValue(1, RuntimeBeanReference.class).getValue();
expressionVoter.addPropertyValue("expressionHandler", expressionHandler);
voters.add(expressionVoter.getBeanDefinition());
}
else {
@ -709,37 +645,28 @@ class HttpConfigurationBuilder {
accessDecisionMgr = new RootBeanDefinition(AffirmativeBased.class);
accessDecisionMgr.getConstructorArgumentValues().addGenericArgumentValue(voters);
accessDecisionMgr.setSource(this.pc.extractSource(this.httpElt));
// Set up the access manager reference for http
String accessManagerId = this.httpElt.getAttribute(ATT_ACCESS_MGR);
if (!StringUtils.hasText(accessManagerId)) {
accessManagerId = this.pc.getReaderContext().generateBeanName(accessDecisionMgr);
this.pc.registerBeanComponent(new BeanComponentDefinition(accessDecisionMgr, accessManagerId));
}
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(FilterSecurityInterceptor.class);
builder.addPropertyReference("accessDecisionManager", accessManagerId);
builder.addPropertyValue("authenticationManager", authManager);
if ("false".equals(this.httpElt.getAttribute(ATT_ONCE_PER_REQUEST))) {
builder.addPropertyValue("observeOncePerRequest", Boolean.FALSE);
}
builder.addPropertyValue("securityMetadataSource", securityMds);
BeanDefinition fsiBean = builder.getBeanDefinition();
String fsiId = this.pc.getReaderContext().generateBeanName(fsiBean);
this.pc.registerBeanComponent(new BeanComponentDefinition(fsiBean, fsiId));
// Create and register a DefaultWebInvocationPrivilegeEvaluator for use with
// taglibs etc.
BeanDefinition wipe = new RootBeanDefinition(DefaultWebInvocationPrivilegeEvaluator.class);
wipe.getConstructorArgumentValues().addGenericArgumentValue(new RuntimeBeanReference(fsiId));
this.pc.registerBeanComponent(
new BeanComponentDefinition(wipe, this.pc.getReaderContext().generateBeanName(wipe)));
this.fsi = new RuntimeBeanReference(fsiId);
}
@ -758,12 +685,10 @@ class HttpConfigurationBuilder {
Element elmt = DomUtils.getChildElementByTagName(this.httpElt, Elements.CSRF);
this.csrfParser = new CsrfBeanDefinitionParser();
this.csrfFilter = this.csrfParser.parse(elmt, this.pc);
if (this.csrfFilter == null) {
this.csrfParser = null;
return;
}
this.csrfAuthStrategy = this.csrfParser.getCsrfAuthenticationStrategy();
this.csrfLogoutHandler = this.csrfParser.getCsrfLogoutHandler();
}
@ -786,51 +711,38 @@ class HttpConfigurationBuilder {
List<OrderDecorator> getFilters() {
List<OrderDecorator> filters = new ArrayList<>();
if (this.cpf != null) {
filters.add(new OrderDecorator(this.cpf, SecurityFilters.CHANNEL_FILTER));
}
if (this.concurrentSessionFilter != null) {
filters.add(new OrderDecorator(this.concurrentSessionFilter, SecurityFilters.CONCURRENT_SESSION_FILTER));
}
if (this.webAsyncManagerFilter != null) {
filters.add(new OrderDecorator(this.webAsyncManagerFilter, SecurityFilters.WEB_ASYNC_MANAGER_FILTER));
}
filters.add(new OrderDecorator(this.securityContextPersistenceFilter, SecurityFilters.SECURITY_CONTEXT_FILTER));
if (this.servApiFilter != null) {
filters.add(new OrderDecorator(this.servApiFilter, SecurityFilters.SERVLET_API_SUPPORT_FILTER));
}
if (this.jaasApiFilter != null) {
filters.add(new OrderDecorator(this.jaasApiFilter, SecurityFilters.JAAS_API_SUPPORT_FILTER));
}
if (this.sfpf != null) {
filters.add(new OrderDecorator(this.sfpf, SecurityFilters.SESSION_MANAGEMENT_FILTER));
}
filters.add(new OrderDecorator(this.fsi, SecurityFilters.FILTER_SECURITY_INTERCEPTOR));
if (this.sessionPolicy != SessionCreationPolicy.STATELESS) {
filters.add(new OrderDecorator(this.requestCacheAwareFilter, SecurityFilters.REQUEST_CACHE_FILTER));
}
if (this.corsFilter != null) {
filters.add(new OrderDecorator(this.corsFilter, SecurityFilters.CORS_FILTER));
}
if (this.addHeadersFilter != null) {
filters.add(new OrderDecorator(this.addHeadersFilter, SecurityFilters.HEADERS_FILTER));
}
if (this.csrfFilter != null) {
filters.add(new OrderDecorator(this.csrfFilter, SecurityFilters.CSRF_FILTER));
}
return filters;
}

View File

@ -36,16 +36,13 @@ public class HttpFirewallBeanDefinitionParser implements BeanDefinitionParser {
@Override
public BeanDefinition parse(Element element, ParserContext pc) {
String ref = element.getAttribute("ref");
if (!StringUtils.hasText(ref)) {
pc.getReaderContext().error("ref attribute is required", pc.extractSource(element));
}
// Ensure the FCP is registered.
HttpSecurityBeanDefinitionParser.registerFilterChainProxyIfNecessary(pc, pc.extractSource(element));
BeanDefinition filterChainProxy = pc.getRegistry().getBeanDefinition(BeanIds.FILTER_CHAIN_PROXY);
filterChainProxy.getPropertyValues().addPropertyValue("firewall", new RuntimeBeanReference(ref));
return null;
}

View File

@ -69,11 +69,15 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
private static final Log logger = LogFactory.getLog(HttpSecurityBeanDefinitionParser.class);
private static final String ATT_AUTHENTICATION_MANAGER_REF = "authentication-manager-ref";
static final String ATT_REQUEST_MATCHER_REF = "request-matcher-ref";
static final String ATT_PATH_PATTERN = "pattern";
static final String ATT_HTTP_METHOD = "method";
static final String ATT_FILTERS = "filters";
static final String OPT_FILTERS_NONE = "none";
static final String ATT_REQUIRES_CHANNEL = "requires-channel";
@ -84,6 +88,12 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
private static final String OPT_SECURITY_NONE = "none";
private static final String ATT_AFTER = "after";
private static final String ATT_BEFORE = "before";
private static final String ATT_POSITION = "position";
public HttpSecurityBeanDefinitionParser() {
}
@ -102,16 +112,12 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(),
pc.extractSource(element));
pc.pushContainingComponent(compositeDef);
registerFilterChainProxyIfNecessary(pc, pc.extractSource(element));
// Obtain the filter chains and add the new chain to it
BeanDefinition listFactoryBean = pc.getRegistry().getBeanDefinition(BeanIds.FILTER_CHAINS);
List<BeanReference> filterChains = (List<BeanReference>) listFactoryBean.getPropertyValues()
.getPropertyValue("sourceList").getValue();
filterChains.add(createFilterChain(element, pc));
pc.popAndRegisterContainingComponent();
return null;
}
@ -121,76 +127,62 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
*/
private BeanReference createFilterChain(Element element, ParserContext pc) {
boolean secured = !OPT_SECURITY_NONE.equals(element.getAttribute(ATT_SECURED));
if (!secured) {
if (!StringUtils.hasText(element.getAttribute(ATT_PATH_PATTERN))
&& !StringUtils.hasText(ATT_REQUEST_MATCHER_REF)) {
pc.getReaderContext()
.error("The '" + ATT_SECURED + "' attribute must be used in combination with" + " the '"
+ ATT_PATH_PATTERN + "' or '" + ATT_REQUEST_MATCHER_REF + "' attributes.",
pc.extractSource(element));
}
for (int n = 0; n < element.getChildNodes().getLength(); n++) {
if (element.getChildNodes().item(n) instanceof Element) {
validateSecuredFilterChainElement(element, pc);
for (int i = 0; i < element.getChildNodes().getLength(); i++) {
if (element.getChildNodes().item(i) instanceof Element) {
pc.getReaderContext().error("If you are using <http> to define an unsecured pattern, "
+ "it cannot contain child elements.", pc.extractSource(element));
}
}
return createSecurityFilterChainBean(element, pc, Collections.emptyList());
}
final BeanReference portMapper = createPortMapper(element, pc);
final BeanReference portResolver = createPortResolver(portMapper, pc);
BeanReference portMapper = createPortMapper(element, pc);
BeanReference portResolver = createPortResolver(portMapper, pc);
ManagedList<BeanReference> authenticationProviders = new ManagedList<>();
BeanReference authenticationManager = createAuthenticationManager(element, pc, authenticationProviders);
boolean forceAutoConfig = isDefaultHttpConfig(element);
HttpConfigurationBuilder httpBldr = new HttpConfigurationBuilder(element, forceAutoConfig, pc, portMapper,
portResolver, authenticationManager);
AuthenticationConfigBuilder authBldr = new AuthenticationConfigBuilder(element, forceAutoConfig, pc,
httpBldr.getSessionCreationPolicy(), httpBldr.getRequestCache(), authenticationManager,
httpBldr.getSessionStrategy(), portMapper, portResolver, httpBldr.getCsrfLogoutHandler());
httpBldr.setLogoutHandlers(authBldr.getLogoutHandlers());
httpBldr.setEntryPoint(authBldr.getEntryPointBean());
httpBldr.setAccessDeniedHandler(authBldr.getAccessDeniedHandlerBean());
httpBldr.setCsrfIgnoreRequestMatchers(authBldr.getCsrfIgnoreRequestMatchers());
authenticationProviders.addAll(authBldr.getProviders());
List<OrderDecorator> unorderedFilterChain = new ArrayList<>();
unorderedFilterChain.addAll(httpBldr.getFilters());
unorderedFilterChain.addAll(authBldr.getFilters());
unorderedFilterChain.addAll(buildCustomFilterList(element, pc));
unorderedFilterChain.sort(new OrderComparator());
checkFilterChainOrder(unorderedFilterChain, pc, pc.extractSource(element));
// The list of filter beans
List<BeanMetadataElement> filterChain = new ManagedList<>();
for (OrderDecorator od : unorderedFilterChain) {
filterChain.add(od.bean);
}
return createSecurityFilterChainBean(element, pc, filterChain);
}
private void validateSecuredFilterChainElement(Element element, ParserContext pc) {
if (!StringUtils.hasText(element.getAttribute(ATT_PATH_PATTERN))
&& !StringUtils.hasText(ATT_REQUEST_MATCHER_REF)) {
String message = "The '" + ATT_SECURED + "' attribute must be used in combination with" + " the '"
+ ATT_PATH_PATTERN + "' or '" + ATT_REQUEST_MATCHER_REF + "' attributes.";
pc.getReaderContext().error(message, pc.extractSource(element));
}
}
private static boolean isDefaultHttpConfig(Element httpElt) {
return httpElt.getChildNodes().getLength() == 0 && httpElt.getAttributes().getLength() == 0;
}
private BeanReference createSecurityFilterChainBean(Element element, ParserContext pc, List<?> filterChain) {
BeanMetadataElement filterChainMatcher;
String requestMatcherRef = element.getAttribute(ATT_REQUEST_MATCHER_REF);
String filterChainPattern = element.getAttribute(ATT_PATH_PATTERN);
if (StringUtils.hasText(requestMatcherRef)) {
if (StringUtils.hasText(filterChainPattern)) {
pc.getReaderContext().error(
@ -206,14 +198,11 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
else {
filterChainMatcher = new RootBeanDefinition(AnyRequestMatcher.class);
}
BeanDefinitionBuilder filterChainBldr = BeanDefinitionBuilder
.rootBeanDefinition(DefaultSecurityFilterChain.class);
filterChainBldr.addConstructorArgValue(filterChainMatcher);
filterChainBldr.addConstructorArgValue(filterChain);
BeanDefinition filterChainBean = filterChainBldr.getBeanDefinition();
String id = element.getAttribute("name");
if (!StringUtils.hasText(id)) {
id = element.getAttribute("id");
@ -221,9 +210,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
id = pc.getReaderContext().generateBeanName(filterChainBean);
}
}
pc.registerBeanComponent(new BeanComponentDefinition(filterChainBean, id));
return new RuntimeBeanReference(id);
}
@ -234,7 +221,6 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
.parse(DomUtils.getChildElementByTagName(elt, Elements.PORT_MAPPINGS), pc);
String portMapperName = pc.getReaderContext().generateBeanName(portMapper);
pc.registerBeanComponent(new BeanComponentDefinition(portMapper, portMapperName));
return new RuntimeBeanReference(portMapperName);
}
@ -259,7 +245,6 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
String parentMgrRef = element.getAttribute(ATT_AUTHENTICATION_MANAGER_REF);
BeanDefinitionBuilder authManager = BeanDefinitionBuilder.rootBeanDefinition(ProviderManager.class);
authManager.addConstructorArgValue(authenticationProviders);
if (StringUtils.hasText(parentMgrRef)) {
RuntimeBeanReference parentAuthManager = new RuntimeBeanReference(parentMgrRef);
authManager.addConstructorArgValue(parentAuthManager);
@ -268,7 +253,6 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
clearCredentials.getPropertyValues().addPropertyValue("targetObject", parentAuthManager);
clearCredentials.getPropertyValues().addPropertyValue("targetMethod",
"isEraseCredentialsAfterAuthentication");
authManager.addPropertyValue("eraseCredentialsAfterAuthentication", clearCredentials);
}
else {
@ -280,11 +264,9 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
clearCredentials.getPropertyValues().addPropertyValue("targetObject", new RuntimeBeanReference(amfbId));
clearCredentials.getPropertyValues().addPropertyValue("targetMethod",
"isEraseCredentialsAfterAuthentication");
authManager.addConstructorArgValue(new RuntimeBeanReference(amfbId));
authManager.addPropertyValue("eraseCredentialsAfterAuthentication", clearCredentials);
}
// gh-6009
authManager.addPropertyValue("authenticationEventPublisher",
new RootBeanDefinition(DefaultAuthenticationEventPublisher.class));
@ -292,16 +274,13 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
BeanDefinition authMgrBean = authManager.getBeanDefinition();
String id = pc.getReaderContext().generateBeanName(authMgrBean);
pc.registerBeanComponent(new BeanComponentDefinition(authMgrBean, id));
return new RuntimeBeanReference(id);
}
private void checkFilterChainOrder(List<OrderDecorator> filters, ParserContext pc, Object source) {
logger.info("Checking sorted filter chain: " + filters);
for (int i = 0; i < filters.size(); i++) {
OrderDecorator filter = filters.get(i);
if (i > 0) {
OrderDecorator previous = filters.get(i - 1);
if (filter.getOrder() == previous.getOrder()) {
@ -320,29 +299,19 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
List<OrderDecorator> buildCustomFilterList(Element element, ParserContext pc) {
List<Element> customFilterElts = DomUtils.getChildElementsByTagName(element, Elements.CUSTOM_FILTER);
List<OrderDecorator> customFilters = new ArrayList<>();
final String ATT_AFTER = "after";
final String ATT_BEFORE = "before";
final String ATT_POSITION = "position";
for (Element elt : customFilterElts) {
String after = elt.getAttribute(ATT_AFTER);
String before = elt.getAttribute(ATT_BEFORE);
String position = elt.getAttribute(ATT_POSITION);
String ref = elt.getAttribute(ATT_REF);
if (!StringUtils.hasText(ref)) {
pc.getReaderContext().error("The '" + ATT_REF + "' attribute must be supplied", pc.extractSource(elt));
}
RuntimeBeanReference bean = new RuntimeBeanReference(ref);
if (WebConfigUtils.countNonEmpty(new String[] { after, before, position }) != 1) {
pc.getReaderContext().error("A single '" + ATT_AFTER + "', '" + ATT_BEFORE + "', or '" + ATT_POSITION
+ "' attribute must be supplied", pc.extractSource(elt));
}
if (StringUtils.hasText(position)) {
customFilters.add(new OrderDecorator(bean, SecurityFilters.valueOf(position)));
}
@ -365,7 +334,6 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
}
}
}
return customFilters;
}
@ -379,7 +347,6 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
BeanDefinition listFactoryBean = new RootBeanDefinition(ListFactoryBean.class);
listFactoryBean.getPropertyValues().add("sourceList", new ManagedList());
pc.registerBeanComponent(new BeanComponentDefinition(listFactoryBean, BeanIds.FILTER_CHAINS));
BeanDefinitionBuilder fcpBldr = BeanDefinitionBuilder.rootBeanDefinition(FilterChainProxy.class);
fcpBldr.getRawBeanDefinition().setSource(source);
fcpBldr.addConstructorArgReference(BeanIds.FILTER_CHAINS);
@ -387,7 +354,6 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
BeanDefinition fcpBean = fcpBldr.getBeanDefinition();
pc.registerBeanComponent(new BeanComponentDefinition(fcpBean, BeanIds.FILTER_CHAIN_PROXY));
registry.registerAlias(BeanIds.FILTER_CHAIN_PROXY, BeanIds.SPRING_SECURITY_FILTER_CHAIN);
BeanDefinitionBuilder requestRejected = BeanDefinitionBuilder
.rootBeanDefinition(RequestRejectedHandlerPostProcessor.class);
requestRejected.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);

View File

@ -44,8 +44,11 @@ class LogoutBeanDefinitionParser implements BeanDefinitionParser {
static final String ATT_INVALIDATE_SESSION = "invalidate-session";
static final String ATT_LOGOUT_URL = "logout-url";
static final String DEF_LOGOUT_URL = "/logout";
static final String ATT_LOGOUT_HANDLER = "success-handler-ref";
static final String ATT_DELETE_COOKIES = "delete-cookies";
final String rememberMeServices;
@ -72,9 +75,7 @@ class LogoutBeanDefinitionParser implements BeanDefinitionParser {
String logoutSuccessUrl = null;
String invalidateSession = null;
String deleteCookies = null;
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(LogoutFilter.class);
if (element != null) {
Object source = pc.extractSource(element);
builder.getRawBeanDefinition().setSource(source);
@ -86,13 +87,10 @@ class LogoutBeanDefinitionParser implements BeanDefinitionParser {
invalidateSession = element.getAttribute(ATT_INVALIDATE_SESSION);
deleteCookies = element.getAttribute(ATT_DELETE_COOKIES);
}
if (!StringUtils.hasText(logoutUrl)) {
logoutUrl = DEF_LOGOUT_URL;
}
builder.addPropertyValue("logoutRequestMatcher", getLogoutRequestMatcher(logoutUrl));
if (StringUtils.hasText(successHandlerRef)) {
if (StringUtils.hasText(logoutSuccessUrl)) {
pc.getReaderContext().error(
@ -108,26 +106,20 @@ class LogoutBeanDefinitionParser implements BeanDefinitionParser {
}
builder.addConstructorArgValue(logoutSuccessUrl);
}
BeanDefinition sclh = new RootBeanDefinition(SecurityContextLogoutHandler.class);
sclh.getPropertyValues().addPropertyValue("invalidateHttpSession", !"false".equals(invalidateSession));
this.logoutHandlers.add(sclh);
if (this.rememberMeServices != null) {
this.logoutHandlers.add(new RuntimeBeanReference(this.rememberMeServices));
}
if (StringUtils.hasText(deleteCookies)) {
BeanDefinition cookieDeleter = new RootBeanDefinition(CookieClearingLogoutHandler.class);
String[] names = StringUtils.tokenizeToStringArray(deleteCookies, ",");
cookieDeleter.getConstructorArgumentValues().addGenericArgumentValue(names);
this.logoutHandlers.add(cookieDeleter);
}
this.logoutHandlers.add(new RootBeanDefinition(LogoutSuccessEventPublishingLogoutHandler.class));
builder.addConstructorArgValue(this.logoutHandlers);
return builder.getBeanDefinition();
}
@ -138,7 +130,6 @@ class LogoutBeanDefinitionParser implements BeanDefinitionParser {
if (this.csrfEnabled) {
matcherBuilder.addConstructorArgValue("POST");
}
return matcherBuilder.getBeanDefinition();
}

View File

@ -58,13 +58,10 @@ public enum MatcherType {
if (("/**".equals(path) || "**".equals(path)) && method == null) {
return new RootBeanDefinition(AnyRequestMatcher.class);
}
BeanDefinitionBuilder matcherBldr = BeanDefinitionBuilder.rootBeanDefinition(this.type);
if (this == mvc) {
matcherBldr.addConstructorArgValue(new RootBeanDefinition(HandlerMappingIntrospectorFactoryBean.class));
}
matcherBldr.addConstructorArgValue(path);
if (this == mvc) {
matcherBldr.addPropertyValue("method", method);
@ -73,11 +70,9 @@ public enum MatcherType {
else {
matcherBldr.addConstructorArgValue(method);
}
if (this == ciRegex) {
matcherBldr.addConstructorArgValue(true);
}
return matcherBldr.getBeanDefinition();
}

View File

@ -66,7 +66,6 @@ final class OAuth2ClientBeanDefinitionParser implements BeanDefinitionParser {
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
Element authorizationCodeGrantElt = DomUtils.getChildElementByTagName(element, ELT_AUTHORIZATION_CODE_GRANT);
BeanMetadataElement clientRegistrationRepository = OAuth2ClientBeanDefinitionParserUtils
.getClientRegistrationRepository(element);
BeanMetadataElement authorizedClientRepository = OAuth2ClientBeanDefinitionParserUtils
@ -80,7 +79,6 @@ final class OAuth2ClientBeanDefinitionParser implements BeanDefinitionParser {
}
BeanMetadataElement authorizationRequestRepository = getAuthorizationRequestRepository(
authorizationCodeGrantElt);
BeanDefinitionBuilder authorizationRequestRedirectFilterBuilder = BeanDefinitionBuilder
.rootBeanDefinition(OAuth2AuthorizationRequestRedirectFilter.class);
String authorizationRequestResolverRef = (authorizationCodeGrantElt != null)
@ -94,7 +92,6 @@ final class OAuth2ClientBeanDefinitionParser implements BeanDefinitionParser {
this.authorizationRequestRedirectFilter = authorizationRequestRedirectFilterBuilder
.addPropertyValue("authorizationRequestRepository", authorizationRequestRepository)
.addPropertyValue("requestCache", this.requestCache).getBeanDefinition();
this.authorizationCodeGrantFilter = BeanDefinitionBuilder
.rootBeanDefinition(OAuth2AuthorizationCodeGrantFilter.class)
.addConstructorArgValue(clientRegistrationRepository).addConstructorArgValue(authorizedClientRepository)
@ -102,7 +99,6 @@ final class OAuth2ClientBeanDefinitionParser implements BeanDefinitionParser {
.addPropertyValue("authorizationRequestRepository", authorizationRequestRepository).getBeanDefinition();
BeanMetadataElement accessTokenResponseClient = getAccessTokenResponseClient(authorizationCodeGrantElt);
this.authorizationCodeAuthenticationProvider = BeanDefinitionBuilder
.rootBeanDefinition(OAuth2AuthorizationCodeAuthenticationProvider.class)
.addConstructorArgValue(accessTokenResponseClient).getBeanDefinition();
@ -111,33 +107,25 @@ final class OAuth2ClientBeanDefinitionParser implements BeanDefinitionParser {
}
private BeanMetadataElement getAuthorizationRequestRepository(Element element) {
BeanMetadataElement authorizationRequestRepository;
String authorizationRequestRepositoryRef = (element != null)
? element.getAttribute(ATT_AUTHORIZATION_REQUEST_REPOSITORY_REF) : null;
if (!StringUtils.isEmpty(authorizationRequestRepositoryRef)) {
authorizationRequestRepository = new RuntimeBeanReference(authorizationRequestRepositoryRef);
return new RuntimeBeanReference(authorizationRequestRepositoryRef);
}
else {
authorizationRequestRepository = BeanDefinitionBuilder.rootBeanDefinition(
"org.springframework.security.oauth2.client.web.HttpSessionOAuth2AuthorizationRequestRepository")
.getBeanDefinition();
}
return authorizationRequestRepository;
return BeanDefinitionBuilder.rootBeanDefinition(
"org.springframework.security.oauth2.client.web.HttpSessionOAuth2AuthorizationRequestRepository")
.getBeanDefinition();
}
private BeanMetadataElement getAccessTokenResponseClient(Element element) {
BeanMetadataElement accessTokenResponseClient;
String accessTokenResponseClientRef = (element != null)
? element.getAttribute(ATT_ACCESS_TOKEN_RESPONSE_CLIENT_REF) : null;
if (!StringUtils.isEmpty(accessTokenResponseClientRef)) {
accessTokenResponseClient = new RuntimeBeanReference(accessTokenResponseClientRef);
return new RuntimeBeanReference(accessTokenResponseClientRef);
}
else {
accessTokenResponseClient = BeanDefinitionBuilder.rootBeanDefinition(
"org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient")
.getBeanDefinition();
}
return accessTokenResponseClient;
return BeanDefinitionBuilder.rootBeanDefinition(
"org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient")
.getBeanDefinition();
}
BeanDefinition getDefaultAuthorizedClientRepository() {

View File

@ -41,15 +41,11 @@ final class OAuth2ClientBeanDefinitionParserUtils {
}
static BeanMetadataElement getClientRegistrationRepository(Element element) {
BeanMetadataElement clientRegistrationRepository;
String clientRegistrationRepositoryRef = element.getAttribute(ATT_CLIENT_REGISTRATION_REPOSITORY_REF);
if (!StringUtils.isEmpty(clientRegistrationRepositoryRef)) {
clientRegistrationRepository = new RuntimeBeanReference(clientRegistrationRepositoryRef);
return new RuntimeBeanReference(clientRegistrationRepositoryRef);
}
else {
clientRegistrationRepository = new RuntimeBeanReference(ClientRegistrationRepository.class);
}
return clientRegistrationRepository;
return new RuntimeBeanReference(ClientRegistrationRepository.class);
}
static BeanMetadataElement getAuthorizedClientRepository(Element element) {

View File

@ -50,11 +50,9 @@ final class OAuth2ClientWebMvcSecurityPostProcessor implements BeanDefinitionReg
(ListableBeanFactory) this.beanFactory, ClientRegistrationRepository.class, false, false);
String[] authorizedClientRepositoryBeanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
(ListableBeanFactory) this.beanFactory, OAuth2AuthorizedClientRepository.class, false, false);
if (clientRegistrationRepositoryBeanNames.length != 1 || authorizedClientRepositoryBeanNames.length != 1) {
return;
}
for (String beanName : registry.getBeanDefinitionNames()) {
BeanDefinition beanDefinition = registry.getBeanDefinition(beanName);
if (RequestMappingHandlerAdapter.class.getName().equals(beanDefinition.getBeanClassName())) {
@ -64,10 +62,8 @@ final class OAuth2ClientWebMvcSecurityPostProcessor implements BeanDefinitionReg
if (currentArgumentResolvers != null) {
argumentResolvers.addAll((ManagedList<?>) currentArgumentResolvers.getValue());
}
String[] authorizedClientManagerBeanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
(ListableBeanFactory) this.beanFactory, OAuth2AuthorizedClientManager.class, false, false);
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder
.genericBeanDefinition(OAuth2AuthorizedClientArgumentResolver.class);
if (authorizedClientManagerBeanNames.length == 1) {

View File

@ -144,7 +144,6 @@ final class OAuth2LoginBeanDefinitionParser implements BeanDefinitionParser {
String oauth2LoginBeanConfigId = parserContext.getReaderContext().generateBeanName(oauth2LoginBeanConfig);
parserContext
.registerBeanComponent(new BeanComponentDefinition(oauth2LoginBeanConfig, oauth2LoginBeanConfigId));
// configure filter
BeanMetadataElement clientRegistrationRepository = OAuth2ClientBeanDefinitionParserUtils
.getClientRegistrationRepository(element);
@ -160,17 +159,14 @@ final class OAuth2LoginBeanDefinitionParser implements BeanDefinitionParser {
BeanMetadataElement accessTokenResponseClient = getAccessTokenResponseClient(element);
BeanMetadataElement oauth2UserService = getOAuth2UserService(element);
BeanMetadataElement authorizationRequestRepository = getAuthorizationRequestRepository(element);
BeanDefinitionBuilder oauth2LoginAuthenticationFilterBuilder = BeanDefinitionBuilder
.rootBeanDefinition(OAuth2LoginAuthenticationFilter.class)
.addConstructorArgValue(clientRegistrationRepository).addConstructorArgValue(authorizedClientRepository)
.addPropertyValue("authorizationRequestRepository", authorizationRequestRepository);
if (this.sessionStrategy != null) {
oauth2LoginAuthenticationFilterBuilder.addPropertyValue("sessionAuthenticationStrategy",
this.sessionStrategy);
}
Object source = parserContext.extractSource(element);
String loginProcessingUrl = element.getAttribute(ATT_LOGIN_PROCESSING_URL);
if (!StringUtils.isEmpty(loginProcessingUrl)) {
@ -181,25 +177,19 @@ final class OAuth2LoginBeanDefinitionParser implements BeanDefinitionParser {
oauth2LoginAuthenticationFilterBuilder
.addConstructorArgValue(OAuth2LoginAuthenticationFilter.DEFAULT_FILTER_PROCESSES_URI);
}
BeanDefinitionBuilder oauth2LoginAuthenticationProviderBuilder = BeanDefinitionBuilder
.rootBeanDefinition(OAuth2LoginAuthenticationProvider.class)
.addConstructorArgValue(accessTokenResponseClient).addConstructorArgValue(oauth2UserService);
String userAuthoritiesMapperRef = element.getAttribute(ATT_USER_AUTHORITIES_MAPPER_REF);
if (!StringUtils.isEmpty(userAuthoritiesMapperRef)) {
oauth2LoginAuthenticationProviderBuilder.addPropertyReference("authoritiesMapper",
userAuthoritiesMapperRef);
}
this.oauth2LoginAuthenticationProvider = oauth2LoginAuthenticationProviderBuilder.getBeanDefinition();
this.oauth2LoginOidcAuthenticationProvider = getOidcAuthProvider(element, accessTokenResponseClient,
userAuthoritiesMapperRef);
BeanDefinitionBuilder oauth2AuthorizationRequestRedirectFilterBuilder = BeanDefinitionBuilder
.rootBeanDefinition(OAuth2AuthorizationRequestRedirectFilter.class);
String authorizationRequestResolverRef = element.getAttribute(ATT_AUTHORIZATION_REQUEST_RESOLVER_REF);
if (!StringUtils.isEmpty(authorizationRequestResolverRef)) {
oauth2AuthorizationRequestRedirectFilterBuilder.addConstructorArgReference(authorizationRequestResolverRef);
@ -207,13 +197,11 @@ final class OAuth2LoginBeanDefinitionParser implements BeanDefinitionParser {
else {
oauth2AuthorizationRequestRedirectFilterBuilder.addConstructorArgValue(clientRegistrationRepository);
}
oauth2AuthorizationRequestRedirectFilterBuilder
.addPropertyValue("authorizationRequestRepository", authorizationRequestRepository)
.addPropertyValue("requestCache", this.requestCache);
this.oauth2AuthorizationRequestRedirectFilter = oauth2AuthorizationRequestRedirectFilterBuilder
.getBeanDefinition();
String authenticationSuccessHandlerRef = element.getAttribute(ATT_AUTHENTICATION_SUCCESS_HANDLER_REF);
if (!StringUtils.isEmpty(authenticationSuccessHandlerRef)) {
oauth2LoginAuthenticationFilterBuilder.addPropertyReference("authenticationSuccessHandler",
@ -226,7 +214,6 @@ final class OAuth2LoginBeanDefinitionParser implements BeanDefinitionParser {
oauth2LoginAuthenticationFilterBuilder.addPropertyValue("authenticationSuccessHandler",
successHandlerBuilder.getBeanDefinition());
}
String loginPage = element.getAttribute(ATT_LOGIN_PAGE);
if (!StringUtils.isEmpty(loginPage)) {
WebConfigUtils.validateHttpRedirect(loginPage, parserContext, source);
@ -244,7 +231,6 @@ final class OAuth2LoginBeanDefinitionParser implements BeanDefinitionParser {
.getBeanDefinition();
}
}
String authenticationFailureHandlerRef = element.getAttribute(ATT_AUTHENTICATION_FAILURE_HANDLER_REF);
if (!StringUtils.isEmpty(authenticationFailureHandlerRef)) {
oauth2LoginAuthenticationFilterBuilder.addPropertyReference("authenticationFailureHandler",
@ -259,95 +245,71 @@ final class OAuth2LoginBeanDefinitionParser implements BeanDefinitionParser {
oauth2LoginAuthenticationFilterBuilder.addPropertyValue("authenticationFailureHandler",
failureHandlerBuilder.getBeanDefinition());
}
// prepare loginlinks
this.oauth2LoginLinks = BeanDefinitionBuilder.rootBeanDefinition(Map.class)
.setFactoryMethodOnBean("getLoginLinks", oauth2LoginBeanConfigId).getBeanDefinition();
return oauth2LoginAuthenticationFilterBuilder.getBeanDefinition();
}
private BeanMetadataElement getAuthorizationRequestRepository(Element element) {
BeanMetadataElement authorizationRequestRepository;
String authorizationRequestRepositoryRef = element.getAttribute(ATT_AUTHORIZATION_REQUEST_REPOSITORY_REF);
if (!StringUtils.isEmpty(authorizationRequestRepositoryRef)) {
authorizationRequestRepository = new RuntimeBeanReference(authorizationRequestRepositoryRef);
return new RuntimeBeanReference(authorizationRequestRepositoryRef);
}
else {
authorizationRequestRepository = BeanDefinitionBuilder.rootBeanDefinition(
"org.springframework.security.oauth2.client.web.HttpSessionOAuth2AuthorizationRequestRepository")
.getBeanDefinition();
}
return authorizationRequestRepository;
return BeanDefinitionBuilder.rootBeanDefinition(
"org.springframework.security.oauth2.client.web.HttpSessionOAuth2AuthorizationRequestRepository")
.getBeanDefinition();
}
private BeanDefinition getOidcAuthProvider(Element element, BeanMetadataElement accessTokenResponseClient,
String userAuthoritiesMapperRef) {
boolean oidcAuthenticationProviderEnabled = ClassUtils
.isPresent("org.springframework.security.oauth2.jwt.JwtDecoder", this.getClass().getClassLoader());
if (!oidcAuthenticationProviderEnabled) {
return BeanDefinitionBuilder.rootBeanDefinition(OidcAuthenticationRequestChecker.class).getBeanDefinition();
}
BeanMetadataElement oidcUserService = getOidcUserService(element);
BeanDefinitionBuilder oidcAuthProviderBuilder = BeanDefinitionBuilder.rootBeanDefinition(
"org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider")
.addConstructorArgValue(accessTokenResponseClient).addConstructorArgValue(oidcUserService);
if (!StringUtils.isEmpty(userAuthoritiesMapperRef)) {
oidcAuthProviderBuilder.addPropertyReference("authoritiesMapper", userAuthoritiesMapperRef);
}
String jwtDecoderFactoryRef = element.getAttribute(ATT_JWT_DECODER_FACTORY_REF);
if (!StringUtils.isEmpty(jwtDecoderFactoryRef)) {
oidcAuthProviderBuilder.addPropertyReference("jwtDecoderFactory", jwtDecoderFactoryRef);
}
return oidcAuthProviderBuilder.getBeanDefinition();
}
private BeanMetadataElement getOidcUserService(Element element) {
BeanMetadataElement oidcUserService;
String oidcUserServiceRef = element.getAttribute(ATT_OIDC_USER_SERVICE_REF);
if (!StringUtils.isEmpty(oidcUserServiceRef)) {
oidcUserService = new RuntimeBeanReference(oidcUserServiceRef);
return new RuntimeBeanReference(oidcUserServiceRef);
}
else {
oidcUserService = BeanDefinitionBuilder
.rootBeanDefinition("org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService")
.getBeanDefinition();
}
return oidcUserService;
return BeanDefinitionBuilder
.rootBeanDefinition("org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService")
.getBeanDefinition();
}
private BeanMetadataElement getOAuth2UserService(Element element) {
BeanMetadataElement oauth2UserService;
String oauth2UserServiceRef = element.getAttribute(ATT_USER_SERVICE_REF);
if (!StringUtils.isEmpty(oauth2UserServiceRef)) {
oauth2UserService = new RuntimeBeanReference(oauth2UserServiceRef);
return new RuntimeBeanReference(oauth2UserServiceRef);
}
else {
oauth2UserService = BeanDefinitionBuilder
.rootBeanDefinition("org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService")
.getBeanDefinition();
}
return oauth2UserService;
return BeanDefinitionBuilder
.rootBeanDefinition("org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService")
.getBeanDefinition();
}
private BeanMetadataElement getAccessTokenResponseClient(Element element) {
BeanMetadataElement accessTokenResponseClient;
String accessTokenResponseClientRef = element.getAttribute(ATT_ACCESS_TOKEN_RESPONSE_CLIENT_REF);
if (!StringUtils.isEmpty(accessTokenResponseClientRef)) {
accessTokenResponseClient = new RuntimeBeanReference(accessTokenResponseClientRef);
return new RuntimeBeanReference(accessTokenResponseClientRef);
}
else {
accessTokenResponseClient = BeanDefinitionBuilder.rootBeanDefinition(
"org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient")
.getBeanDefinition();
}
return accessTokenResponseClient;
return BeanDefinitionBuilder.rootBeanDefinition(
"org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient")
.getBeanDefinition();
}
BeanDefinition getDefaultAuthorizedClientRepository() {
@ -386,10 +348,8 @@ final class OAuth2LoginBeanDefinitionParser implements BeanDefinitionParser {
RequestMatcher defaultEntryPointMatcher = this.getAuthenticationEntryPointMatcher();
RequestMatcher defaultLoginPageMatcher = new AndRequestMatcher(
new OrRequestMatcher(loginPageMatcher, faviconMatcher), defaultEntryPointMatcher);
RequestMatcher notXRequestedWith = new NegatedRequestMatcher(
new RequestHeaderRequestMatcher("X-Requested-With", "XMLHttpRequest"));
Element clientRegElt = clientRegList.get(0);
entryPoints = new LinkedHashMap<>();
entryPoints.put(
@ -417,22 +377,19 @@ final class OAuth2LoginBeanDefinitionParser implements BeanDefinitionParser {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
OAuth2LoginAuthenticationToken authorizationCodeAuthentication = (OAuth2LoginAuthenticationToken) authentication;
// Section 3.1.2.1 Authentication Request -
// https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
// scope
// REQUIRED. OpenID Connect requests MUST contain the "openid" scope value.
if (authorizationCodeAuthentication.getAuthorizationExchange().getAuthorizationRequest().getScopes()
if (!authorizationCodeAuthentication.getAuthorizationExchange().getAuthorizationRequest().getScopes()
.contains(OidcScopes.OPENID)) {
OAuth2Error oauth2Error = new OAuth2Error("oidc_provider_not_configured",
"An OpenID Connect Authentication Provider has not been configured. "
+ "Check to ensure you include the dependency 'spring-security-oauth2-jose'.",
null);
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
return null;
}
return null;
// Section 3.1.2.1 Authentication Request -
// https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest scope
// REQUIRED. OpenID Connect requests MUST contain the "openid" scope
// value.
OAuth2Error oauth2Error = new OAuth2Error("oidc_provider_not_configured",
"An OpenID Connect Authentication Provider has not been configured. "
+ "Check to ensure you include the dependency 'spring-security-oauth2-jose'.",
null);
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
}
@Override
@ -466,13 +423,11 @@ final class OAuth2LoginBeanDefinitionParser implements BeanDefinitionParser {
if (clientRegistrations == null) {
return Collections.emptyMap();
}
String authorizationRequestBaseUri = DEFAULT_AUTHORIZATION_REQUEST_BASE_URI;
Map<String, String> loginUrlToClientName = new HashMap<>();
clientRegistrations.forEach((registration) -> loginUrlToClientName.put(
authorizationRequestBaseUri + "/" + registration.getRegistrationId(),
registration.getClientName()));
return loginUrlToClientName;
}

View File

@ -62,10 +62,13 @@ import org.springframework.util.xml.DomUtils;
final class OAuth2ResourceServerBeanDefinitionParser implements BeanDefinitionParser {
static final String AUTHENTICATION_MANAGER_RESOLVER_REF = "authentication-manager-resolver-ref";
static final String BEARER_TOKEN_RESOLVER_REF = "bearer-token-resolver-ref";
static final String ENTRY_POINT_REF = "entry-point-ref";
static final String BEARER_TOKEN_RESOLVER = "bearerTokenResolver";
static final String AUTHENTICATION_ENTRY_POINT = "authenticationEntryPoint";
private final BeanReference authenticationManager;
@ -105,34 +108,27 @@ final class OAuth2ResourceServerBeanDefinitionParser implements BeanDefinitionPa
public BeanDefinition parse(Element oauth2ResourceServer, ParserContext pc) {
Element jwt = DomUtils.getChildElementByTagName(oauth2ResourceServer, Elements.JWT);
Element opaqueToken = DomUtils.getChildElementByTagName(oauth2ResourceServer, Elements.OPAQUE_TOKEN);
validateConfiguration(oauth2ResourceServer, jwt, opaqueToken, pc);
if (jwt != null) {
BeanDefinition jwtAuthenticationProvider = new JwtBeanDefinitionParser().parse(jwt, pc);
this.authenticationProviders.add(new RuntimeBeanReference(
pc.getReaderContext().registerWithGeneratedName(jwtAuthenticationProvider)));
}
if (opaqueToken != null) {
BeanDefinition opaqueTokenAuthenticationProvider = new OpaqueTokenBeanDefinitionParser().parse(opaqueToken,
pc);
this.authenticationProviders.add(new RuntimeBeanReference(
pc.getReaderContext().registerWithGeneratedName(opaqueTokenAuthenticationProvider)));
}
BeanMetadataElement bearerTokenResolver = getBearerTokenResolver(oauth2ResourceServer);
BeanDefinitionBuilder requestMatcherBuilder = BeanDefinitionBuilder
.rootBeanDefinition(BearerTokenRequestMatcher.class);
requestMatcherBuilder.addConstructorArgValue(bearerTokenResolver);
BeanDefinition requestMatcher = requestMatcherBuilder.getBeanDefinition();
BeanMetadataElement authenticationEntryPoint = getEntryPoint(oauth2ResourceServer);
this.entryPoints.put(requestMatcher, authenticationEntryPoint);
this.deniedHandlers.put(requestMatcher, this.accessDeniedHandler);
this.ignoreCsrfRequestMatchers.add(requestMatcher);
BeanDefinitionBuilder filterBuilder = BeanDefinitionBuilder
.rootBeanDefinition(BearerTokenAuthenticationFilter.class);
BeanMetadataElement authenticationManagerResolver = getAuthenticationManagerResolver(oauth2ResourceServer);
@ -145,22 +141,19 @@ final class OAuth2ResourceServerBeanDefinitionParser implements BeanDefinitionPa
void validateConfiguration(Element oauth2ResourceServer, Element jwt, Element opaqueToken, ParserContext pc) {
if (!oauth2ResourceServer.hasAttribute(AUTHENTICATION_MANAGER_RESOLVER_REF)) {
if (jwt == null && opaqueToken == null) {
pc.getReaderContext()
.error("Didn't find authentication-manager-resolver-ref, <jwt>, or <opaque-token>. "
+ "Please select one.", oauth2ResourceServer);
pc.getReaderContext().error("Didn't find authentication-manager-resolver-ref, "
+ "<jwt>, or <opaque-token>. " + "Please select one.", oauth2ResourceServer);
}
return;
}
if (jwt != null) {
pc.getReaderContext().error(
"Found <jwt> as well as authentication-manager-resolver-ref. " + "Please select just one.",
"Found <jwt> as well as authentication-manager-resolver-ref. Please select just one.",
oauth2ResourceServer);
}
if (opaqueToken != null) {
pc.getReaderContext().error(
"Found <opaque-token> as well as authentication-manager-resolver-ref. " + "Please select just one.",
"Found <opaque-token> as well as authentication-manager-resolver-ref. Please select just one.",
oauth2ResourceServer);
}
}
@ -181,9 +174,7 @@ final class OAuth2ResourceServerBeanDefinitionParser implements BeanDefinitionPa
if (StringUtils.isEmpty(bearerTokenResolverRef)) {
return new RootBeanDefinition(DefaultBearerTokenResolver.class);
}
else {
return new RuntimeBeanReference(bearerTokenResolverRef);
}
return new RuntimeBeanReference(bearerTokenResolverRef);
}
BeanMetadataElement getEntryPoint(Element element) {
@ -191,34 +182,35 @@ final class OAuth2ResourceServerBeanDefinitionParser implements BeanDefinitionPa
if (StringUtils.isEmpty(entryPointRef)) {
return this.authenticationEntryPoint;
}
else {
return new RuntimeBeanReference(entryPointRef);
}
return new RuntimeBeanReference(entryPointRef);
}
static final class JwtBeanDefinitionParser implements BeanDefinitionParser {
static final String DECODER_REF = "decoder-ref";
static final String JWK_SET_URI = "jwk-set-uri";
static final String JWT_AUTHENTICATION_CONVERTER_REF = "jwt-authentication-converter-ref";
static final String JWT_AUTHENTICATION_CONVERTER = "jwtAuthenticationConverter";
JwtBeanDefinitionParser() {
}
@Override
public BeanDefinition parse(Element element, ParserContext pc) {
validateConfiguration(element, pc);
BeanDefinitionBuilder jwtProviderBuilder = BeanDefinitionBuilder
.rootBeanDefinition(JwtAuthenticationProvider.class);
jwtProviderBuilder.addConstructorArgValue(getDecoder(element));
jwtProviderBuilder.addPropertyValue(JWT_AUTHENTICATION_CONVERTER, getJwtAuthenticationConverter(element));
return jwtProviderBuilder.getBeanDefinition();
}
void validateConfiguration(Element element, ParserContext pc) {
boolean usesDecoder = element.hasAttribute(DECODER_REF);
boolean usesJwkSetUri = element.hasAttribute(JWK_SET_URI);
if (usesDecoder == usesJwkSetUri) {
pc.getReaderContext().error("Please specify either decoder-ref or jwk-set-uri.", element);
}
@ -229,7 +221,6 @@ final class OAuth2ResourceServerBeanDefinitionParser implements BeanDefinitionPa
if (!StringUtils.isEmpty(decoderRef)) {
return new RuntimeBeanReference(decoderRef);
}
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.rootBeanDefinition(NimbusJwtDecoderJwkSetUriFactoryBean.class);
builder.addConstructorArgValue(element.getAttribute(JWK_SET_URI));
@ -238,14 +229,8 @@ final class OAuth2ResourceServerBeanDefinitionParser implements BeanDefinitionPa
Object getJwtAuthenticationConverter(Element element) {
String jwtDecoderRef = element.getAttribute(JWT_AUTHENTICATION_CONVERTER_REF);
if (!StringUtils.isEmpty(jwtDecoderRef)) {
return new RuntimeBeanReference(jwtDecoderRef);
}
return new JwtAuthenticationConverter();
}
JwtBeanDefinitionParser() {
return (!StringUtils.isEmpty(jwtDecoderRef)) ? new RuntimeBeanReference(jwtDecoderRef)
: new JwtAuthenticationConverter();
}
}
@ -253,19 +238,23 @@ final class OAuth2ResourceServerBeanDefinitionParser implements BeanDefinitionPa
static final class OpaqueTokenBeanDefinitionParser implements BeanDefinitionParser {
static final String INTROSPECTOR_REF = "introspector-ref";
static final String INTROSPECTION_URI = "introspection-uri";
static final String CLIENT_ID = "client-id";
static final String CLIENT_SECRET = "client-secret";
OpaqueTokenBeanDefinitionParser() {
}
@Override
public BeanDefinition parse(Element element, ParserContext pc) {
validateConfiguration(element, pc);
BeanMetadataElement introspector = getIntrospector(element);
BeanDefinitionBuilder opaqueTokenProviderBuilder = BeanDefinitionBuilder
.rootBeanDefinition(OpaqueTokenAuthenticationProvider.class);
opaqueTokenProviderBuilder.addConstructorArgValue(introspector);
return opaqueTokenProviderBuilder.getBeanDefinition();
}
@ -273,13 +262,11 @@ final class OAuth2ResourceServerBeanDefinitionParser implements BeanDefinitionPa
boolean usesIntrospector = element.hasAttribute(INTROSPECTOR_REF);
boolean usesEndpoint = element.hasAttribute(INTROSPECTION_URI) || element.hasAttribute(CLIENT_ID)
|| element.hasAttribute(CLIENT_SECRET);
if (usesIntrospector == usesEndpoint) {
pc.getReaderContext().error("Please specify either introspector-ref or all of "
+ "introspection-uri, client-id, and client-secret.", element);
return;
}
if (usesEndpoint) {
if (!(element.hasAttribute(INTROSPECTION_URI) && element.hasAttribute(CLIENT_ID)
&& element.hasAttribute(CLIENT_SECRET))) {
@ -294,23 +281,17 @@ final class OAuth2ResourceServerBeanDefinitionParser implements BeanDefinitionPa
if (!StringUtils.isEmpty(introspectorRef)) {
return new RuntimeBeanReference(introspectorRef);
}
String introspectionUri = element.getAttribute(INTROSPECTION_URI);
String clientId = element.getAttribute(CLIENT_ID);
String clientSecret = element.getAttribute(CLIENT_SECRET);
BeanDefinitionBuilder introspectorBuilder = BeanDefinitionBuilder
.rootBeanDefinition(NimbusOpaqueTokenIntrospector.class);
introspectorBuilder.addConstructorArgValue(introspectionUri);
introspectorBuilder.addConstructorArgValue(clientId);
introspectorBuilder.addConstructorArgValue(clientSecret);
return introspectorBuilder.getBeanDefinition();
}
OpaqueTokenBeanDefinitionParser() {
}
}
static final class StaticAuthenticationManagerResolver

View File

@ -48,33 +48,25 @@ class PortMappingsBeanDefinitionParser implements BeanDefinitionParser {
public BeanDefinition parse(Element element, ParserContext parserContext) {
RootBeanDefinition portMapper = new RootBeanDefinition(PortMapperImpl.class);
portMapper.setSource(parserContext.extractSource(element));
if (element != null) {
List<Element> mappingElts = DomUtils.getChildElementsByTagName(element, Elements.PORT_MAPPING);
if (mappingElts.isEmpty()) {
parserContext.getReaderContext().error("No port-mapping child elements specified", element);
}
Map mappings = new ManagedMap();
for (Element elt : mappingElts) {
String httpPort = elt.getAttribute(ATT_HTTP_PORT);
String httpsPort = elt.getAttribute(ATT_HTTPS_PORT);
if (!StringUtils.hasText(httpPort)) {
parserContext.getReaderContext().error("No http port supplied in port mapping", elt);
}
if (!StringUtils.hasText(httpsPort)) {
parserContext.getReaderContext().error("No https port supplied in port mapping", elt);
}
mappings.put(httpPort, httpsPort);
}
portMapper.getPropertyValues().addPropertyValue("portMappings", mappings);
}
return portMapper;
}

View File

@ -45,14 +45,23 @@ import org.springframework.util.StringUtils;
class RememberMeBeanDefinitionParser implements BeanDefinitionParser {
static final String ATT_DATA_SOURCE = "data-source-ref";
static final String ATT_SERVICES_REF = "services-ref";
static final String ATT_SERVICES_ALIAS = "services-alias";
static final String ATT_TOKEN_REPOSITORY = "token-repository-ref";
static final String ATT_USER_SERVICE_REF = "user-service-ref";
static final String ATT_SUCCESS_HANDLER_REF = "authentication-success-handler-ref";
static final String ATT_TOKEN_VALIDITY = "token-validity-seconds";
static final String ATT_SECURE_COOKIE = "use-secure-cookie";
static final String ATT_FORM_REMEMBERME_PARAMETER = "remember-me-parameter";
static final String ATT_REMEMBERME_COOKIE = "remember-me-cookie";
protected final Log logger = LogFactory.getLog(getClass());
@ -73,7 +82,6 @@ class RememberMeBeanDefinitionParser implements BeanDefinitionParser {
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(),
pc.extractSource(element));
pc.pushContainingComponent(compositeDef);
String tokenRepository = element.getAttribute(ATT_TOKEN_REPOSITORY);
String dataSource = element.getAttribute(ATT_DATA_SOURCE);
String userServiceRef = element.getAttribute(ATT_USER_SERVICE_REF);
@ -84,9 +92,7 @@ class RememberMeBeanDefinitionParser implements BeanDefinitionParser {
String remembermeParameter = element.getAttribute(ATT_FORM_REMEMBERME_PARAMETER);
String remembermeCookie = element.getAttribute(ATT_REMEMBERME_COOKIE);
Object source = pc.extractSource(element);
RootBeanDefinition services = null;
boolean dataSourceSet = StringUtils.hasText(dataSource);
boolean tokenRepoSet = StringUtils.hasText(tokenRepository);
boolean servicesRefSet = StringUtils.hasText(rememberMeServicesRef);
@ -95,7 +101,6 @@ class RememberMeBeanDefinitionParser implements BeanDefinitionParser {
boolean tokenValiditySet = StringUtils.hasText(tokenValiditySeconds);
boolean remembermeParameterSet = StringUtils.hasText(remembermeParameter);
boolean remembermeCookieSet = StringUtils.hasText(remembermeCookie);
if (servicesRefSet && (dataSourceSet || tokenRepoSet || userServiceSet || tokenValiditySet || useSecureCookieSet
|| remembermeParameterSet || remembermeCookieSet)) {
pc.getReaderContext()
@ -104,18 +109,14 @@ class RememberMeBeanDefinitionParser implements BeanDefinitionParser {
+ ATT_SECURE_COOKIE + ", " + ATT_FORM_REMEMBERME_PARAMETER + " or " + ATT_REMEMBERME_COOKIE,
source);
}
if (dataSourceSet && tokenRepoSet) {
pc.getReaderContext().error("Specify " + ATT_TOKEN_REPOSITORY + " or " + ATT_DATA_SOURCE + " but not both",
source);
}
boolean isPersistent = dataSourceSet | tokenRepoSet;
if (isPersistent) {
Object tokenRepo;
services = new RootBeanDefinition(PersistentTokenBasedRememberMeServices.class);
if (tokenRepoSet) {
tokenRepo = new RuntimeBeanReference(tokenRepository);
}
@ -129,24 +130,19 @@ class RememberMeBeanDefinitionParser implements BeanDefinitionParser {
else if (!servicesRefSet) {
services = new RootBeanDefinition(TokenBasedRememberMeServices.class);
}
String servicesName;
if (services != null) {
RootBeanDefinition uds = new RootBeanDefinition();
uds.setFactoryBeanName(BeanIds.USER_DETAILS_SERVICE_FACTORY);
uds.setFactoryMethodName("cachingUserDetailsService");
uds.getConstructorArgumentValues().addGenericArgumentValue(userServiceRef);
services.getConstructorArgumentValues().addGenericArgumentValue(this.key);
services.getConstructorArgumentValues().addGenericArgumentValue(uds);
// tokenRepo is already added if it is a
// PersistentTokenBasedRememberMeServices
if (useSecureCookieSet) {
services.getPropertyValues().addPropertyValue("useSecureCookie", Boolean.valueOf(useSecureCookie));
}
if (tokenValiditySet) {
boolean isTokenValidityNegative = tokenValiditySeconds.startsWith("-");
if (isTokenValidityNegative && isPersistent) {
@ -155,15 +151,12 @@ class RememberMeBeanDefinitionParser implements BeanDefinitionParser {
}
services.getPropertyValues().addPropertyValue("tokenValiditySeconds", tokenValiditySeconds);
}
if (remembermeParameterSet) {
services.getPropertyValues().addPropertyValue("parameter", remembermeParameter);
}
if (remembermeCookieSet) {
services.getPropertyValues().addPropertyValue("cookieName", remembermeCookie);
}
services.setSource(source);
servicesName = pc.getReaderContext().generateBeanName(services);
pc.registerBeanComponent(new BeanComponentDefinition(services, servicesName));
@ -171,25 +164,18 @@ class RememberMeBeanDefinitionParser implements BeanDefinitionParser {
else {
servicesName = rememberMeServicesRef;
}
if (StringUtils.hasText(element.getAttribute(ATT_SERVICES_ALIAS))) {
pc.getRegistry().registerAlias(servicesName, element.getAttribute(ATT_SERVICES_ALIAS));
}
this.rememberMeServicesId = servicesName;
BeanDefinitionBuilder filter = BeanDefinitionBuilder.rootBeanDefinition(RememberMeAuthenticationFilter.class);
filter.getRawBeanDefinition().setSource(source);
if (StringUtils.hasText(successHandlerRef)) {
filter.addPropertyReference("authenticationSuccessHandler", successHandlerRef);
}
filter.addConstructorArgValue(this.authenticationManager);
filter.addConstructorArgReference(servicesName);
pc.popAndRegisterContainingComponent();
return filter.getBeanDefinition();
}

View File

@ -28,15 +28,22 @@ import org.springframework.security.core.context.SecurityContext;
*/
public enum SessionCreationPolicy {
/** Always create an {@link HttpSession} */
/**
* Always create an {@link HttpSession}
*/
ALWAYS,
/**
* Spring Security will never create an {@link HttpSession}, but will use the
* {@link HttpSession} if it already exists
*/
NEVER,
/** Spring Security will only create an {@link HttpSession} if required */
/**
* Spring Security will only create an {@link HttpSession} if required
*/
IF_REQUIRED,
/**
* Spring Security will never create an {@link HttpSession} and it will never use it
* to obtain the {@link SecurityContext}

View File

@ -46,7 +46,6 @@ public class UserDetailsServiceFactoryBean implements ApplicationContextAware {
if (!StringUtils.hasText(id)) {
return getUserDetailsService();
}
return (UserDetailsService) this.beanFactory.getBean(id);
}
@ -56,21 +55,17 @@ public class UserDetailsServiceFactoryBean implements ApplicationContextAware {
}
// Overwrite with the caching version if available
String cachingId = id + AbstractUserDetailsServiceBeanDefinitionParser.CACHING_SUFFIX;
if (this.beanFactory.containsBeanDefinition(cachingId)) {
return (UserDetailsService) this.beanFactory.getBean(cachingId);
}
return (UserDetailsService) this.beanFactory.getBean(id);
}
@SuppressWarnings("unchecked")
AuthenticationUserDetailsService authenticationUserDetailsService(String name) {
UserDetailsService uds;
if (!StringUtils.hasText(name)) {
Map<String, ?> beans = getBeansOfType(AuthenticationUserDetailsService.class);
if (!beans.isEmpty()) {
if (beans.size() > 1) {
throw new ApplicationContextException("More than one AuthenticationUserDetailsService registered."
@ -78,18 +73,15 @@ public class UserDetailsServiceFactoryBean implements ApplicationContextAware {
}
return (AuthenticationUserDetailsService) beans.values().toArray()[0];
}
uds = getUserDetailsService();
}
else {
Object bean = this.beanFactory.getBean(name);
if (bean instanceof AuthenticationUserDetailsService) {
return (AuthenticationUserDetailsService) bean;
}
else if (bean instanceof UserDetailsService) {
uds = cachingUserDetailsService(name);
if (uds == null) {
uds = (UserDetailsService) bean;
}
@ -99,7 +91,6 @@ public class UserDetailsServiceFactoryBean implements ApplicationContextAware {
"Bean '" + name + "' must be a UserDetailsService or an" + " AuthenticationUserDetailsService");
}
}
return new UserDetailsByNameServiceWrapper(uds);
}
@ -110,20 +101,16 @@ public class UserDetailsServiceFactoryBean implements ApplicationContextAware {
*/
private UserDetailsService getUserDetailsService() {
Map<String, ?> beans = getBeansOfType(CachingUserDetailsService.class);
if (beans.size() == 0) {
beans = getBeansOfType(UserDetailsService.class);
}
if (beans.size() == 0) {
throw new ApplicationContextException("No UserDetailsService registered.");
}
else if (beans.size() > 1) {
if (beans.size() > 1) {
throw new ApplicationContextException("More than one UserDetailsService registered. Please "
+ "use a specific Id reference in <remember-me/> <openid-login/> or <x509 /> elements.");
}
return (UserDetailsService) beans.values().toArray()[0];
}
@ -134,7 +121,6 @@ public class UserDetailsServiceFactoryBean implements ApplicationContextAware {
private Map<String, ?> getBeansOfType(Class<?> type) {
Map<String, ?> beans = this.beanFactory.getBeansOfType(type);
// Check ancestor bean factories if they exist and the current one has none of the
// required type
BeanFactory parent = this.beanFactory.getParentBeanFactory();
@ -149,7 +135,6 @@ public class UserDetailsServiceFactoryBean implements ApplicationContextAware {
break;
}
}
return beans;
}

View File

@ -50,37 +50,34 @@ public class ContextSourceSettingPostProcessor implements BeanFactoryPostProcess
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory bf) throws BeansException {
Class<?> contextSourceClass;
try {
contextSourceClass = ClassUtils.forName(REQUIRED_CONTEXT_SOURCE_CLASS_NAME,
ClassUtils.getDefaultClassLoader());
}
catch (ClassNotFoundException ex) {
throw new ApplicationContextException("Couldn't locate: " + REQUIRED_CONTEXT_SOURCE_CLASS_NAME + ". "
+ " If you are using LDAP with Spring Security, please ensure that you include the spring-ldap "
+ "jar file in your application", ex);
}
Class<?> contextSourceClass = getContextSourceClass();
String[] sources = bf.getBeanNamesForType(contextSourceClass, false, false);
if (sources.length == 0) {
throw new ApplicationContextException("No BaseLdapPathContextSource instances found. Have you "
+ "added an <" + Elements.LDAP_SERVER + " /> element to your application context? If you have "
+ "declared an explicit bean, do not use lazy-init");
}
if (!bf.containsBean(BeanIds.CONTEXT_SOURCE) && this.defaultNameRequired) {
if (sources.length > 1) {
throw new ApplicationContextException("More than one BaseLdapPathContextSource instance found. "
+ "Please specify a specific server id using the 'server-ref' attribute when configuring your <"
+ Elements.LDAP_PROVIDER + "> " + "or <" + Elements.LDAP_USER_SERVICE + ">.");
}
bf.registerAlias(sources[0], BeanIds.CONTEXT_SOURCE);
}
}
private Class<?> getContextSourceClass() throws LinkageError {
try {
return ClassUtils.forName(REQUIRED_CONTEXT_SOURCE_CLASS_NAME, ClassUtils.getDefaultClassLoader());
}
catch (ClassNotFoundException ex) {
throw new ApplicationContextException("Couldn't locate: " + REQUIRED_CONTEXT_SOURCE_CLASS_NAME + ". "
+ " If you are using LDAP with Spring Security, please ensure that you include the spring-ldap "
+ "jar file in your application", ex);
}
}
public void setDefaultNameRequired(boolean defaultNameRequired) {
this.defaultNameRequired = defaultNameRequired;
}

View File

@ -49,19 +49,18 @@ public class LdapProviderBeanDefinitionParser implements BeanDefinitionParser {
private static final String DEF_USER_SEARCH_FILTER = "uid={0}";
static final String PROVIDER_CLASS = "org.springframework.security.ldap.authentication.LdapAuthenticationProvider";
static final String BIND_AUTH_CLASS = "org.springframework.security.ldap.authentication.BindAuthenticator";
static final String PASSWD_AUTH_CLASS = "org.springframework.security.ldap.authentication.PasswordComparisonAuthenticator";
@Override
public BeanDefinition parse(Element elt, ParserContext parserContext) {
RuntimeBeanReference contextSource = LdapUserServiceBeanDefinitionParser.parseServerReference(elt,
parserContext);
BeanDefinition searchBean = LdapUserServiceBeanDefinitionParser.parseSearchBean(elt, parserContext);
String userDnPattern = elt.getAttribute(ATT_USER_DN_PATTERN);
String[] userDnPatternArray = new String[0];
if (StringUtils.hasText(userDnPattern)) {
userDnPatternArray = new String[] { userDnPattern };
// TODO: Validate the pattern and make sure it is a valid DN.
@ -77,22 +76,17 @@ public class LdapProviderBeanDefinitionParser implements BeanDefinitionParser {
searchBeanBuilder.addConstructorArgValue(contextSource);
searchBean = searchBeanBuilder.getBeanDefinition();
}
BeanDefinitionBuilder authenticatorBuilder = BeanDefinitionBuilder.rootBeanDefinition(BIND_AUTH_CLASS);
Element passwordCompareElt = DomUtils.getChildElementByTagName(elt, Elements.LDAP_PASSWORD_COMPARE);
if (passwordCompareElt != null) {
authenticatorBuilder = BeanDefinitionBuilder.rootBeanDefinition(PASSWD_AUTH_CLASS);
String passwordAttribute = passwordCompareElt.getAttribute(ATT_USER_PASSWORD);
if (StringUtils.hasText(passwordAttribute)) {
authenticatorBuilder.addPropertyValue("passwordAttributeName", passwordAttribute);
}
Element passwordEncoderElement = DomUtils.getChildElementByTagName(passwordCompareElt,
Elements.PASSWORD_ENCODER);
String hash = passwordCompareElt.getAttribute(ATT_HASH);
if (passwordEncoderElement != null) {
if (StringUtils.hasText(hash)) {
parserContext.getReaderContext().warning(
@ -107,21 +101,17 @@ public class LdapProviderBeanDefinitionParser implements BeanDefinitionParser {
PasswordEncoderParser.createPasswordEncoderBeanDefinition(hash, false));
}
}
authenticatorBuilder.addConstructorArgValue(contextSource);
authenticatorBuilder.addPropertyValue("userDnPatterns", userDnPatternArray);
if (searchBean != null) {
authenticatorBuilder.addPropertyValue("userSearch", searchBean);
}
BeanDefinitionBuilder ldapProvider = BeanDefinitionBuilder.rootBeanDefinition(PROVIDER_CLASS);
ldapProvider.addConstructorArgValue(authenticatorBuilder.getBeanDefinition());
ldapProvider.addConstructorArgValue(
LdapUserServiceBeanDefinitionParser.parseAuthoritiesPopulator(elt, parserContext));
ldapProvider.addPropertyValue("userDetailsContextMapper",
LdapUserServiceBeanDefinitionParser.parseUserDetailsClassOrUserMapperRef(elt, parserContext));
return ldapProvider.getBeanDefinition();
}

View File

@ -89,9 +89,7 @@ public class LdapServerBeanDefinitionParser implements BeanDefinitionParser {
@Override
public BeanDefinition parse(Element elt, ParserContext parserContext) {
String url = elt.getAttribute(ATT_URL);
RootBeanDefinition contextSource;
if (!StringUtils.hasText(url)) {
contextSource = createEmbeddedServer(elt, parserContext);
}
@ -100,28 +98,20 @@ public class LdapServerBeanDefinitionParser implements BeanDefinitionParser {
contextSource.setBeanClassName(CONTEXT_SOURCE_CLASS);
contextSource.getConstructorArgumentValues().addIndexedArgumentValue(0, url);
}
contextSource.setSource(parserContext.extractSource(elt));
String managerDn = elt.getAttribute(ATT_PRINCIPAL);
String managerPassword = elt.getAttribute(ATT_PASSWORD);
if (StringUtils.hasText(managerDn)) {
if (!StringUtils.hasText(managerPassword)) {
parserContext.getReaderContext()
.error("You must specify the " + ATT_PASSWORD + " if you supply a " + managerDn, elt);
}
contextSource.getPropertyValues().addPropertyValue("userDn", managerDn);
contextSource.getPropertyValues().addPropertyValue("password", managerPassword);
}
String id = elt.getAttribute(AbstractBeanDefinitionParser.ID_ATTRIBUTE);
String contextSourceId = StringUtils.hasText(id) ? id : BeanIds.CONTEXT_SOURCE;
parserContext.getRegistry().registerBeanDefinition(contextSourceId, contextSource);
return null;
}
@ -136,52 +126,40 @@ public class LdapServerBeanDefinitionParser implements BeanDefinitionParser {
*/
private RootBeanDefinition createEmbeddedServer(Element element, ParserContext parserContext) {
Object source = parserContext.extractSource(element);
String suffix = element.getAttribute(ATT_ROOT_SUFFIX);
if (!StringUtils.hasText(suffix)) {
suffix = OPT_DEFAULT_ROOT_SUFFIX;
}
BeanDefinitionBuilder contextSource = BeanDefinitionBuilder.rootBeanDefinition(CONTEXT_SOURCE_CLASS);
contextSource.addConstructorArgValue(suffix);
contextSource.addPropertyValue("userDn", "uid=admin,ou=system");
contextSource.addPropertyValue("password", "secret");
BeanDefinition embeddedLdapServerConfigBean = BeanDefinitionBuilder
.rootBeanDefinition(EmbeddedLdapServerConfigBean.class).getBeanDefinition();
String embeddedLdapServerConfigBeanName = parserContext.getReaderContext()
.generateBeanName(embeddedLdapServerConfigBean);
parserContext.registerBeanComponent(
new BeanComponentDefinition(embeddedLdapServerConfigBean, embeddedLdapServerConfigBeanName));
contextSource.setFactoryMethodOnBean("createEmbeddedContextSource", embeddedLdapServerConfigBeanName);
String mode = element.getAttribute("mode");
RootBeanDefinition ldapContainer = getRootBeanDefinition(mode);
ldapContainer.setSource(source);
ldapContainer.getConstructorArgumentValues().addGenericArgumentValue(suffix);
String ldifs = element.getAttribute(ATT_LDIF_FILE);
if (!StringUtils.hasText(ldifs)) {
ldifs = OPT_DEFAULT_LDIF_FILE;
}
ldapContainer.getConstructorArgumentValues().addGenericArgumentValue(ldifs);
ldapContainer.getPropertyValues().addPropertyValue("port", getPort(element));
if (parserContext.getRegistry().containsBeanDefinition(BeanIds.EMBEDDED_APACHE_DS)
|| parserContext.getRegistry().containsBeanDefinition(BeanIds.EMBEDDED_UNBOUNDID)) {
parserContext.getReaderContext().error("Only one embedded server bean is allowed per application context",
element);
}
String beanId = resolveBeanId(mode);
if (beanId != null) {
parserContext.getRegistry().registerBeanDefinition(beanId, ldapContainer);
}
return (RootBeanDefinition) contextSource.getBeanDefinition();
}
@ -189,7 +167,7 @@ public class LdapServerBeanDefinitionParser implements BeanDefinitionParser {
if (isApacheDsEnabled(mode)) {
return new RootBeanDefinition(APACHEDS_CONTAINER_CLASSNAME, null, null);
}
else if (isUnboundidEnabled(mode)) {
if (isUnboundidEnabled(mode)) {
return new RootBeanDefinition(UNBOUNDID_CONTAINER_CLASSNAME, null, null);
}
throw new IllegalStateException("Embedded LDAP server is not provided");
@ -199,7 +177,7 @@ public class LdapServerBeanDefinitionParser implements BeanDefinitionParser {
if (isApacheDsEnabled(mode)) {
return BeanIds.EMBEDDED_APACHE_DS;
}
else if (isUnboundidEnabled(mode)) {
if (isUnboundidEnabled(mode)) {
return BeanIds.EMBEDDED_UNBOUNDID;
}
return null;
@ -238,22 +216,21 @@ public class LdapServerBeanDefinitionParser implements BeanDefinitionParser {
@SuppressWarnings("unused")
private DefaultSpringSecurityContextSource createEmbeddedContextSource(String suffix) {
int port;
int port = getPort();
String providerUrl = "ldap://127.0.0.1:" + port + "/" + suffix;
return new DefaultSpringSecurityContextSource(providerUrl);
}
private int getPort() {
if (ClassUtils.isPresent(APACHEDS_CLASSNAME, getClass().getClassLoader())) {
ApacheDSContainer apacheDSContainer = this.applicationContext.getBean(ApacheDSContainer.class);
port = apacheDSContainer.getLocalPort();
return apacheDSContainer.getLocalPort();
}
else if (ClassUtils.isPresent(UNBOUNID_CLASSNAME, getClass().getClassLoader())) {
if (ClassUtils.isPresent(UNBOUNID_CLASSNAME, getClass().getClassLoader())) {
UnboundIdContainer unboundIdContainer = this.applicationContext.getBean(UnboundIdContainer.class);
port = unboundIdContainer.getPort();
return unboundIdContainer.getPort();
}
else {
throw new IllegalStateException("Embedded LDAP server is not provided");
}
String providerUrl = "ldap://127.0.0.1:" + port + "/" + suffix;
return new DefaultSpringSecurityContextSource(providerUrl);
throw new IllegalStateException("Embedded LDAP server is not provided");
}
}

View File

@ -54,9 +54,13 @@ public class LdapUserServiceBeanDefinitionParser extends AbstractUserDetailsServ
public static final String DEF_GROUP_SEARCH_BASE = "";
static final String ATT_ROLE_PREFIX = "role-prefix";
static final String ATT_USER_CLASS = "user-details-class";
static final String ATT_USER_CONTEXT_MAPPER_REF = "user-context-mapper-ref";
static final String OPT_PERSON = "person";
static final String OPT_INETORGPERSON = "inetOrgPerson";
public static final String LDAP_SEARCH_CLASS = "org.springframework.security.ldap.search.FilterBasedLdapUserSearch";
@ -76,11 +80,9 @@ public class LdapUserServiceBeanDefinitionParser extends AbstractUserDetailsServ
@Override
protected void doParse(Element elt, ParserContext parserContext, BeanDefinitionBuilder builder) {
if (!StringUtils.hasText(elt.getAttribute(ATT_USER_SEARCH_FILTER))) {
parserContext.getReaderContext().error("User search filter must be supplied", elt);
}
builder.addConstructorArgValue(parseSearchBean(elt, parserContext));
builder.getRawBeanDefinition().setSource(parserContext.extractSource(elt));
builder.addConstructorArgValue(parseAuthoritiesPopulator(elt, parserContext));
@ -91,7 +93,6 @@ public class LdapUserServiceBeanDefinitionParser extends AbstractUserDetailsServ
String userSearchFilter = elt.getAttribute(ATT_USER_SEARCH_FILTER);
String userSearchBase = elt.getAttribute(ATT_USER_SEARCH_BASE);
Object source = parserContext.extractSource(elt);
if (StringUtils.hasText(userSearchBase)) {
if (!StringUtils.hasText(userSearchFilter)) {
parserContext.getReaderContext()
@ -101,33 +102,27 @@ public class LdapUserServiceBeanDefinitionParser extends AbstractUserDetailsServ
else {
userSearchBase = DEF_USER_SEARCH_BASE;
}
if (!StringUtils.hasText(userSearchFilter)) {
return null;
}
BeanDefinitionBuilder searchBuilder = BeanDefinitionBuilder.rootBeanDefinition(LDAP_SEARCH_CLASS);
searchBuilder.getRawBeanDefinition().setSource(source);
searchBuilder.addConstructorArgValue(userSearchBase);
searchBuilder.addConstructorArgValue(userSearchFilter);
searchBuilder.addConstructorArgValue(parseServerReference(elt, parserContext));
return (RootBeanDefinition) searchBuilder.getBeanDefinition();
}
static RuntimeBeanReference parseServerReference(Element elt, ParserContext parserContext) {
String server = elt.getAttribute(ATT_SERVER);
boolean requiresDefaultName = false;
if (!StringUtils.hasText(server)) {
server = BeanIds.CONTEXT_SOURCE;
requiresDefaultName = true;
}
RuntimeBeanReference contextSource = new RuntimeBeanReference(server);
contextSource.setSource(parserContext.extractSource(elt));
registerPostProcessorIfNecessary(parserContext.getRegistry(), requiresDefaultName);
return contextSource;
}
@ -139,7 +134,6 @@ public class LdapUserServiceBeanDefinitionParser extends AbstractUserDetailsServ
}
return;
}
BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(ContextSourceSettingPostProcessor.class);
bdb.addPropertyValue("defaultNameRequired", defaultNameRequired);
registry.registerBeanDefinition(BeanIds.CONTEXT_SOURCE_SETTING_POST_PROCESSOR, bdb.getBeanDefinition());
@ -148,65 +142,54 @@ public class LdapUserServiceBeanDefinitionParser extends AbstractUserDetailsServ
static BeanMetadataElement parseUserDetailsClassOrUserMapperRef(Element elt, ParserContext parserContext) {
String userDetailsClass = elt.getAttribute(ATT_USER_CLASS);
String userMapperRef = elt.getAttribute(ATT_USER_CONTEXT_MAPPER_REF);
if (StringUtils.hasText(userDetailsClass) && StringUtils.hasText(userMapperRef)) {
parserContext.getReaderContext().error("Attributes " + ATT_USER_CLASS + " and "
+ ATT_USER_CONTEXT_MAPPER_REF + " cannot be used together.", parserContext.extractSource(elt));
}
if (StringUtils.hasText(userMapperRef)) {
return new RuntimeBeanReference(userMapperRef);
}
RootBeanDefinition mapper;
if (OPT_PERSON.equals(userDetailsClass)) {
mapper = new RootBeanDefinition(PERSON_MAPPER_CLASS, null, null);
}
else if (OPT_INETORGPERSON.equals(userDetailsClass)) {
mapper = new RootBeanDefinition(INET_ORG_PERSON_MAPPER_CLASS, null, null);
}
else {
mapper = new RootBeanDefinition(LDAP_USER_MAPPER_CLASS, null, null);
}
RootBeanDefinition mapper = getMapper(userDetailsClass);
mapper.setSource(parserContext.extractSource(elt));
return mapper;
}
private static RootBeanDefinition getMapper(String userDetailsClass) {
if (OPT_PERSON.equals(userDetailsClass)) {
return new RootBeanDefinition(PERSON_MAPPER_CLASS, null, null);
}
if (OPT_INETORGPERSON.equals(userDetailsClass)) {
return new RootBeanDefinition(INET_ORG_PERSON_MAPPER_CLASS, null, null);
}
return new RootBeanDefinition(LDAP_USER_MAPPER_CLASS, null, null);
}
static RootBeanDefinition parseAuthoritiesPopulator(Element elt, ParserContext parserContext) {
String groupSearchFilter = elt.getAttribute(ATT_GROUP_SEARCH_FILTER);
String groupSearchBase = elt.getAttribute(ATT_GROUP_SEARCH_BASE);
String groupRoleAttribute = elt.getAttribute(ATT_GROUP_ROLE_ATTRIBUTE);
String rolePrefix = elt.getAttribute(ATT_ROLE_PREFIX);
if (!StringUtils.hasText(groupSearchFilter)) {
groupSearchFilter = DEF_GROUP_SEARCH_FILTER;
}
if (!StringUtils.hasText(groupSearchBase)) {
groupSearchBase = DEF_GROUP_SEARCH_BASE;
}
BeanDefinitionBuilder populator = BeanDefinitionBuilder.rootBeanDefinition(LDAP_AUTHORITIES_POPULATOR_CLASS);
populator.getRawBeanDefinition().setSource(parserContext.extractSource(elt));
populator.addConstructorArgValue(parseServerReference(elt, parserContext));
populator.addConstructorArgValue(groupSearchBase);
populator.addPropertyValue("groupSearchFilter", groupSearchFilter);
populator.addPropertyValue("searchSubtree", Boolean.TRUE);
if (StringUtils.hasText(rolePrefix)) {
if ("none".equals(rolePrefix)) {
rolePrefix = "";
}
populator.addPropertyValue("rolePrefix", rolePrefix);
}
if (StringUtils.hasLength(groupRoleAttribute)) {
populator.addPropertyValue("groupRoleAttribute", groupRoleAttribute);
}
return (RootBeanDefinition) populator.getBeanDefinition();
}

View File

@ -48,6 +48,7 @@ import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.log.LogMessage;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.access.annotation.Jsr250MethodSecurityMetadataSource;
@ -122,36 +123,28 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(),
pc.extractSource(element));
pc.pushContainingComponent(compositeDef);
Object source = pc.extractSource(element);
// The list of method metadata delegates
ManagedList<BeanMetadataElement> delegates = new ManagedList<>();
boolean jsr250Enabled = "enabled".equals(element.getAttribute(ATT_USE_JSR250));
boolean useSecured = "enabled".equals(element.getAttribute(ATT_USE_SECURED));
boolean prePostAnnotationsEnabled = "enabled".equals(element.getAttribute(ATT_USE_PREPOST));
boolean useAspectJ = "aspectj".equals(element.getAttribute(ATT_MODE));
BeanDefinition preInvocationVoter = null;
ManagedList<BeanMetadataElement> afterInvocationProviders = new ManagedList<>();
// Check for an external SecurityMetadataSource, which takes priority over other
// sources
String metaDataSourceId = element.getAttribute(ATT_META_DATA_SOURCE_REF);
if (StringUtils.hasText(metaDataSourceId)) {
delegates.add(new RuntimeBeanReference(metaDataSourceId));
}
if (prePostAnnotationsEnabled) {
Element prePostElt = DomUtils.getChildElementByTagName(element, Elements.INVOCATION_HANDLING);
Element expressionHandlerElt = DomUtils.getChildElementByTagName(element, Elements.EXPRESSION_HANDLER);
if (prePostElt != null && expressionHandlerElt != null) {
pc.getReaderContext().error(Elements.INVOCATION_HANDLING + " and " + Elements.EXPRESSION_HANDLER
+ " cannot be used together ", source);
}
BeanDefinitionBuilder preInvocationVoterBldr = BeanDefinitionBuilder
.rootBeanDefinition(PreInvocationAuthorizationAdviceVoter.class);
// After-invocation provider to handle post-invocation filtering and
@ -161,7 +154,6 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
// The metadata source for the security interceptor
BeanDefinitionBuilder mds = BeanDefinitionBuilder
.rootBeanDefinition(PrePostAnnotationSecurityMetadataSource.class);
if (prePostElt != null) {
// Customized override of expression handling system
String attributeFactoryRef = DomUtils
@ -171,7 +163,6 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
.getAttribute("ref");
String postAdviceRef = DomUtils.getChildElementByTagName(prePostElt, Elements.POST_INVOCATION_ADVICE)
.getAttribute("ref");
mds.addConstructorArgReference(attributeFactoryRef);
preInvocationVoterBldr.addConstructorArgReference(preAdviceRef);
afterInvocationBldr.addConstructorArgReference(postAdviceRef);
@ -180,80 +171,65 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
// The default expression-based system
String expressionHandlerRef = (expressionHandlerElt != null) ? expressionHandlerElt.getAttribute("ref")
: null;
if (StringUtils.hasText(expressionHandlerRef)) {
this.logger.info(
"Using bean '" + expressionHandlerRef + "' as method ExpressionHandler implementation");
this.logger.info(LogMessage.format("Using bean '%s' as method ExpressionHandler implementation",
expressionHandlerRef));
RootBeanDefinition lazyInitPP = new RootBeanDefinition(
LazyInitBeanDefinitionRegistryPostProcessor.class);
lazyInitPP.getConstructorArgumentValues().addGenericArgumentValue(expressionHandlerRef);
pc.getReaderContext().registerWithGeneratedName(lazyInitPP);
BeanDefinitionBuilder lazyMethodSecurityExpressionHandlerBldr = BeanDefinitionBuilder
.rootBeanDefinition(LazyInitTargetSource.class);
lazyMethodSecurityExpressionHandlerBldr.addPropertyValue("targetBeanName", expressionHandlerRef);
BeanDefinitionBuilder expressionHandlerProxyBldr = BeanDefinitionBuilder
.rootBeanDefinition(ProxyFactoryBean.class);
expressionHandlerProxyBldr.addPropertyValue("targetSource",
lazyMethodSecurityExpressionHandlerBldr.getBeanDefinition());
expressionHandlerProxyBldr.addPropertyValue("proxyInterfaces",
MethodSecurityExpressionHandler.class);
expressionHandlerRef = pc.getReaderContext()
.generateBeanName(expressionHandlerProxyBldr.getBeanDefinition());
pc.registerBeanComponent(new BeanComponentDefinition(expressionHandlerProxyBldr.getBeanDefinition(),
expressionHandlerRef));
}
else {
RootBeanDefinition expressionHandler = registerWithDefaultRolePrefix(pc,
DefaultMethodSecurityExpressionHandlerBeanFactory.class);
expressionHandlerRef = pc.getReaderContext().generateBeanName(expressionHandler);
pc.registerBeanComponent(new BeanComponentDefinition(expressionHandler, expressionHandlerRef));
this.logger.info(
"Expressions were enabled for method security but no SecurityExpressionHandler was configured. "
+ "All hasPermission() expressions will evaluate to false.");
this.logger.info("Expressions were enabled for method security but no SecurityExpressionHandler "
+ "was configured. All hasPermission() expressions will evaluate to false.");
}
BeanDefinitionBuilder expressionPreAdviceBldr = BeanDefinitionBuilder
.rootBeanDefinition(ExpressionBasedPreInvocationAdvice.class);
expressionPreAdviceBldr.addPropertyReference("expressionHandler", expressionHandlerRef);
preInvocationVoterBldr.addConstructorArgValue(expressionPreAdviceBldr.getBeanDefinition());
BeanDefinitionBuilder expressionPostAdviceBldr = BeanDefinitionBuilder
.rootBeanDefinition(ExpressionBasedPostInvocationAdvice.class);
expressionPostAdviceBldr.addConstructorArgReference(expressionHandlerRef);
afterInvocationBldr.addConstructorArgValue(expressionPostAdviceBldr.getBeanDefinition());
BeanDefinitionBuilder annotationInvocationFactory = BeanDefinitionBuilder
.rootBeanDefinition(ExpressionBasedAnnotationAttributeFactory.class);
annotationInvocationFactory.addConstructorArgReference(expressionHandlerRef);
mds.addConstructorArgValue(annotationInvocationFactory.getBeanDefinition());
}
preInvocationVoter = preInvocationVoterBldr.getBeanDefinition();
afterInvocationProviders.add(afterInvocationBldr.getBeanDefinition());
delegates.add(mds.getBeanDefinition());
}
if (useSecured) {
delegates.add(BeanDefinitionBuilder.rootBeanDefinition(SecuredAnnotationSecurityMetadataSource.class)
.getBeanDefinition());
}
if (jsr250Enabled) {
RootBeanDefinition jsrMetadataSource = registerWithDefaultRolePrefix(pc,
Jsr250MethodSecurityMetadataSourceBeanFactory.class);
delegates.add(jsrMetadataSource);
}
// Now create a Map<String, ConfigAttribute> for each <protect-pointcut>
// sub-element
Map<String, List<ConfigAttribute>> pointcutMap = parseProtectPointcuts(pc,
DomUtils.getChildElementsByTagName(element, Elements.PROTECT_POINTCUT));
if (pointcutMap.size() > 0) {
if (useAspectJ) {
pc.getReaderContext().error("You can't use AspectJ mode with protect-pointcut definitions", source);
@ -262,34 +238,25 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
BeanDefinition mapBasedMetadataSource = new RootBeanDefinition(MapBasedMethodSecurityMetadataSource.class);
BeanReference ref = new RuntimeBeanReference(
pc.getReaderContext().generateBeanName(mapBasedMetadataSource));
delegates.add(ref);
pc.registerBeanComponent(new BeanComponentDefinition(mapBasedMetadataSource, ref.getBeanName()));
registerProtectPointcutPostProcessor(pc, pointcutMap, ref, source);
}
BeanReference metadataSource = registerDelegatingMethodSecurityMetadataSource(pc, delegates, source);
// Check for additional after-invocation-providers..
List<Element> afterInvocationElts = DomUtils.getChildElementsByTagName(element,
Elements.AFTER_INVOCATION_PROVIDER);
for (Element elt : afterInvocationElts) {
afterInvocationProviders.add(new RuntimeBeanReference(elt.getAttribute(ATT_REF)));
}
String accessManagerId = element.getAttribute(ATT_ACCESS_MGR);
if (!StringUtils.hasText(accessManagerId)) {
accessManagerId = registerAccessManager(pc, jsr250Enabled, preInvocationVoter);
}
String authMgrRef = element.getAttribute(ATT_AUTHENTICATION_MANAGER_REF);
String runAsManagerId = element.getAttribute(ATT_RUN_AS_MGR);
BeanReference interceptor = registerMethodSecurityInterceptor(pc, authMgrRef, accessManagerId, runAsManagerId,
metadataSource, afterInvocationProviders, source, useAspectJ);
if (useAspectJ) {
BeanDefinitionBuilder aspect = BeanDefinitionBuilder.rootBeanDefinition(
"org.springframework.security.access.intercept.aspectj.aspect.AnnotationSecurityAspect");
@ -303,9 +270,7 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
registerAdvisor(pc, interceptor, metadataSource, source, element.getAttribute(ATT_ADVICE_ORDER));
AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(pc, element);
}
pc.popAndRegisterContainingComponent();
return null;
}
@ -316,26 +281,20 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
private String registerAccessManager(ParserContext pc, boolean jsr250Enabled, BeanDefinition expressionVoter) {
BeanDefinitionBuilder accessMgrBuilder = BeanDefinitionBuilder.rootBeanDefinition(AffirmativeBased.class);
ManagedList voters = new ManagedList(4);
if (expressionVoter != null) {
voters.add(expressionVoter);
}
voters.add(new RootBeanDefinition(RoleVoter.class));
voters.add(new RootBeanDefinition(AuthenticatedVoter.class));
if (jsr250Enabled) {
voters.add(new RootBeanDefinition(Jsr250Voter.class));
}
accessMgrBuilder.addConstructorArgValue(voters);
BeanDefinition accessManager = accessMgrBuilder.getBeanDefinition();
String id = pc.getReaderContext().generateBeanName(accessManager);
pc.registerBeanComponent(new BeanComponentDefinition(accessManager, id));
return id;
}
@ -346,7 +305,6 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
DelegatingMethodSecurityMetadataSource.class);
delegatingMethodSecurityMetadataSource.setSource(source);
delegatingMethodSecurityMetadataSource.getConstructorArgumentValues().addGenericArgumentValue(delegates);
String id = pc.getReaderContext().generateBeanName(delegatingMethodSecurityMetadataSource);
pc.registerBeanComponent(new BeanComponentDefinition(delegatingMethodSecurityMetadataSource, id));
@ -367,31 +325,24 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
private Map<String, List<ConfigAttribute>> parseProtectPointcuts(ParserContext parserContext,
List<Element> protectPointcutElts) {
Map<String, List<ConfigAttribute>> pointcutMap = new LinkedHashMap<>();
for (Element childElt : protectPointcutElts) {
String accessConfig = childElt.getAttribute(ATT_ACCESS);
String expression = childElt.getAttribute(ATT_EXPRESSION);
if (!StringUtils.hasText(accessConfig)) {
parserContext.getReaderContext().error("Access configuration required",
parserContext.extractSource(childElt));
}
if (!StringUtils.hasText(expression)) {
parserContext.getReaderContext().error("Pointcut expression required",
parserContext.extractSource(childElt));
}
String[] attributeTokens = StringUtils.commaDelimitedListToStringArray(accessConfig);
List<ConfigAttribute> attributes = new ArrayList<>(attributeTokens.length);
for (String token : attributeTokens) {
attributes.add(new SecurityConfig(token));
}
pointcutMap.put(expression, attributes);
}
return pointcutMap;
}
@ -406,22 +357,18 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
authMgr.getConstructorArgumentValues().addGenericArgumentValue(authMgrRef);
bldr.addPropertyValue("authenticationManager", authMgr);
bldr.addPropertyValue("securityMetadataSource", metadataSource);
if (StringUtils.hasText(runAsManagerId)) {
bldr.addPropertyReference("runAsManager", runAsManagerId);
}
if (!afterInvocationProviders.isEmpty()) {
BeanDefinition afterInvocationManager;
afterInvocationManager = new RootBeanDefinition(AfterInvocationProviderManager.class);
afterInvocationManager.getPropertyValues().addPropertyValue("providers", afterInvocationProviders);
bldr.addPropertyValue("afterInvocationManager", afterInvocationManager);
}
BeanDefinition bean = bldr.getBeanDefinition();
String id = pc.getReaderContext().generateBeanName(bean);
pc.registerBeanComponent(new BeanComponentDefinition(bean, id));
return new RuntimeBeanReference(id);
}
@ -431,11 +378,9 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
parserContext.getReaderContext().error("Duplicate <global-method-security> detected.", source);
}
RootBeanDefinition advisor = new RootBeanDefinition(MethodSecurityMetadataSourceAdvisor.class);
if (StringUtils.hasText(adviceOrder)) {
advisor.getPropertyValues().addPropertyValue("order", adviceOrder);
}
// advisor must be an infrastructure bean as Spring's
// InfrastructureAdvisorAutoProxyCreator will ignore it
// otherwise
@ -444,7 +389,6 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
advisor.getConstructorArgumentValues().addGenericArgumentValue(interceptor.getBeanName());
advisor.getConstructorArgumentValues().addGenericArgumentValue(metadataSource);
advisor.getConstructorArgumentValues().addGenericArgumentValue(metadataSource.getBeanName());
parserContext.getRegistry().registerBeanDefinition(BeanIds.METHOD_SECURITY_METADATA_SOURCE_ADVISOR, advisor);
}
@ -453,7 +397,6 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
RootBeanDefinition beanFactoryDefinition = new RootBeanDefinition(beanFactoryClass);
String beanFactoryRef = pc.getReaderContext().generateBeanName(beanFactoryDefinition);
pc.getRegistry().registerBeanDefinition(beanFactoryRef, beanFactoryDefinition);
RootBeanDefinition bean = new RootBeanDefinition();
bean.setFactoryBeanName(beanFactoryRef);
bean.setFactoryMethodName("getBean");
@ -499,7 +442,6 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
}
}
}
return this.delegate.authenticate(authentication);
}

View File

@ -52,7 +52,6 @@ public class InterceptMethodsBeanDefinitionDecorator implements BeanDefinitionDe
@Override
public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) {
MethodConfigUtils.registerDefaultMethodAccessManagerIfNecessary(parserContext);
return this.delegate.decorate(node, definition, parserContext);
}
@ -64,6 +63,7 @@ public class InterceptMethodsBeanDefinitionDecorator implements BeanDefinitionDe
extends AbstractInterceptorDrivenBeanDefinitionDecorator {
static final String ATT_METHOD = "method";
static final String ATT_ACCESS = "access";
private static final String ATT_ACCESS_MGR = "access-decision-manager-ref";
@ -73,49 +73,36 @@ public class InterceptMethodsBeanDefinitionDecorator implements BeanDefinitionDe
Element interceptMethodsElt = (Element) node;
BeanDefinitionBuilder interceptor = BeanDefinitionBuilder
.rootBeanDefinition(MethodSecurityInterceptor.class);
// Default to autowiring to pick up after invocation mgr
interceptor.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
String accessManagerId = interceptMethodsElt.getAttribute(ATT_ACCESS_MGR);
if (!StringUtils.hasText(accessManagerId)) {
accessManagerId = BeanIds.METHOD_ACCESS_MANAGER;
}
interceptor.addPropertyValue("accessDecisionManager", new RuntimeBeanReference(accessManagerId));
interceptor.addPropertyValue("authenticationManager",
new RuntimeBeanReference(BeanIds.AUTHENTICATION_MANAGER));
// Lookup parent bean information
String parentBeanClass = ((Element) node.getParentNode()).getAttribute("class");
// Parse the included methods
List<Element> methods = DomUtils.getChildElementsByTagName(interceptMethodsElt, Elements.PROTECT);
Map<String, BeanDefinition> mappings = new ManagedMap<>();
for (Element protectmethodElt : methods) {
BeanDefinitionBuilder attributeBuilder = BeanDefinitionBuilder.rootBeanDefinition(SecurityConfig.class);
attributeBuilder.setFactoryMethod("createListFromCommaDelimitedString");
attributeBuilder.addConstructorArgValue(protectmethodElt.getAttribute(ATT_ACCESS));
// Support inference of class names
String methodName = protectmethodElt.getAttribute(ATT_METHOD);
if (methodName.lastIndexOf(".") == -1) {
if (parentBeanClass != null && !"".equals(parentBeanClass)) {
methodName = parentBeanClass + "." + methodName;
}
}
mappings.put(methodName, attributeBuilder.getBeanDefinition());
}
BeanDefinition metadataSource = new RootBeanDefinition(MapBasedMethodSecurityMetadataSource.class);
metadataSource.getConstructorArgumentValues().addGenericArgumentValue(mappings);
interceptor.addPropertyValue("securityMetadataSource", metadataSource);
return interceptor.getBeanDefinition();
}

View File

@ -46,11 +46,9 @@ abstract class MethodConfigUtils {
@SuppressWarnings("unchecked")
private static RootBeanDefinition createAccessManagerBean(Class<? extends AccessDecisionVoter>... voters) {
ManagedList defaultVoters = new ManagedList(voters.length);
for (Class<? extends AccessDecisionVoter> voter : voters) {
defaultVoters.add(new RootBeanDefinition(voter));
}
BeanDefinitionBuilder accessMgrBuilder = BeanDefinitionBuilder.rootBeanDefinition(AffirmativeBased.class);
accessMgrBuilder.addConstructorArgValue(defaultVoters);
return (RootBeanDefinition) accessMgrBuilder.getBeanDefinition();

View File

@ -40,6 +40,7 @@ import org.springframework.util.xml.DomUtils;
public class MethodSecurityMetadataSourceBeanDefinitionParser extends AbstractBeanDefinitionParser {
static final String ATT_METHOD = "method";
static final String ATT_ACCESS = "access";
@Override
@ -47,17 +48,13 @@ public class MethodSecurityMetadataSourceBeanDefinitionParser extends AbstractBe
// Parse the included methods
List<Element> methods = DomUtils.getChildElementsByTagName(elt, Elements.PROTECT);
Map<String, List<ConfigAttribute>> mappings = new LinkedHashMap<>();
for (Element protectmethodElt : methods) {
String[] tokens = StringUtils.commaDelimitedListToStringArray(protectmethodElt.getAttribute(ATT_ACCESS));
String methodName = protectmethodElt.getAttribute(ATT_METHOD);
mappings.put(methodName, SecurityConfig.createList(tokens));
}
RootBeanDefinition metadataSource = new RootBeanDefinition(MapBasedMethodSecurityMetadataSource.class);
metadataSource.getConstructorArgumentValues().addGenericArgumentValue(mappings);
return metadataSource;
}

Some files were not shown because too many files have changed in this diff Show More