From acf56017145c2e1116af78151fa707433c13d708 Mon Sep 17 00:00:00 2001 From: Luke Taylor Date: Sun, 27 Jan 2008 22:45:44 +0000 Subject: [PATCH] SEC-645: Reimplementation of X509 provider and namespace implementation. --- .../security/config/BeanIds.java | 5 + .../security/config/Elements.java | 1 + .../HttpSecurityBeanDefinitionParser.java | 7 +- .../HttpSecurityConfigPostProcessor.java | 26 ++++- .../config/X509BeanDefinitionParser.java | 64 +++++++++++++ ...reAuthenticatedAuthenticationProvider.java | 1 + .../security/ui/FilterChainOrder.java | 4 +- .../X509PreAuthenticatedProcessingFilter.java | 6 +- .../security/config/spring-security-2.0.rnc | 95 +++++++++++-------- .../security/config/spring-security-2.0.xsd | 78 ++++++++++----- ...HttpSecurityBeanDefinitionParserTests.java | 12 +++ .../applicationContext-security-ns.xml | 11 ++- 12 files changed, 237 insertions(+), 73 deletions(-) create mode 100644 core/src/main/java/org/springframework/security/config/X509BeanDefinitionParser.java mode change 100755 => 100644 core/src/main/java/org/springframework/security/providers/preauth/PreAuthenticatedAuthenticationProvider.java diff --git a/core/src/main/java/org/springframework/security/config/BeanIds.java b/core/src/main/java/org/springframework/security/config/BeanIds.java index 020f90b0fa..961a7c70e8 100644 --- a/core/src/main/java/org/springframework/security/config/BeanIds.java +++ b/core/src/main/java/org/springframework/security/config/BeanIds.java @@ -2,6 +2,8 @@ package org.springframework.security.config; /** * Contains all the default Bean IDs created by the namespace support in Spring Security 2. + *

+ * These are mainly intended for internal use. * * @author Ben Alex * @version $Id$ @@ -44,4 +46,7 @@ public abstract class BeanIds { public static final String EMBEDDED_APACHE_DS = "_apacheDirectoryServerContainer"; public static final String CONTEXT_SOURCE = "_securityContextSource"; public static final String PORT_MAPPER = "_portMapper"; + public static final String X509_FILTER = "_x509ProcessingFilter"; + public static final String X509_AUTH_PROVIDER = "_x509AuthenitcationProvider"; + public static final String PRE_AUTH_ENTRY_POINT = "_preAuthenticatedProcessingFilterEntryPoint"; } diff --git a/core/src/main/java/org/springframework/security/config/Elements.java b/core/src/main/java/org/springframework/security/config/Elements.java index fad646e10b..d6319c65d7 100644 --- a/core/src/main/java/org/springframework/security/config/Elements.java +++ b/core/src/main/java/org/springframework/security/config/Elements.java @@ -31,4 +31,5 @@ abstract class Elements { public static final String PORT_MAPPING = "port-mapping"; public static final String CUSTOM_FILTER = "custom-filter"; public static final String CUSTOM_AUTH_RPOVIDER = "custom-authentication-provider"; + public static final String X509 = "x509"; } diff --git a/core/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java b/core/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java index 866b81e0f7..1a3f65f4fc 100644 --- a/core/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java +++ b/core/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java @@ -124,7 +124,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { if (useRegex) { matcher = new RegexUrlPathMatcher(); - } + } // Deal with lowercase conversion requests String lowercaseComparisons = element.getAttribute(ATT_LOWERCASE_COMPARISONS); @@ -256,6 +256,11 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { new BasicAuthenticationBeanDefinitionParser(realm).parse(basicAuthElt, parserContext); } + Element x509Elt = DomUtils.getChildElementByTagName(element, Elements.X509); + if (x509Elt != null) { + new X509BeanDefinitionParser().parse(x509Elt, parserContext); + } + registry.registerBeanDefinition(BeanIds.FILTER_CHAIN_PROXY, filterChainProxy); registry.registerBeanDefinition(BeanIds.HTTP_SESSION_CONTEXT_INTEGRATION_FILTER, httpScif); registry.registerBeanDefinition(BeanIds.EXCEPTION_TRANSLATION_FILTER, exceptionTranslationFilterBuilder.getBeanDefinition()); diff --git a/core/src/main/java/org/springframework/security/config/HttpSecurityConfigPostProcessor.java b/core/src/main/java/org/springframework/security/config/HttpSecurityConfigPostProcessor.java index b6e9fdb7e2..b1ccec7a58 100644 --- a/core/src/main/java/org/springframework/security/config/HttpSecurityConfigPostProcessor.java +++ b/core/src/main/java/org/springframework/security/config/HttpSecurityConfigPostProcessor.java @@ -11,6 +11,7 @@ import javax.servlet.Filter; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.BeansException; +import org.springframework.beans.PropertyValue; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; @@ -24,6 +25,7 @@ import org.springframework.security.ui.AuthenticationEntryPoint; import org.springframework.security.ui.basicauth.BasicProcessingFilter; import org.springframework.security.ui.rememberme.RememberMeServices; import org.springframework.security.util.FilterChainProxy; +import org.springframework.security.providers.preauth.UserDetailsByNameServiceWrapper; import org.springframework.util.Assert; /** @@ -33,12 +35,14 @@ import org.springframework.util.Assert; * @author Luke Taylor * @author Ben Alex * @version $Id$ + * @since 2.0 */ public class HttpSecurityConfigPostProcessor implements BeanFactoryPostProcessor, Ordered { private Log logger = LogFactory.getLog(getClass()); public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { injectUserDetailsServiceIntoRememberMeServices(beanFactory); + injectUserDetailsServiceIntoX509Provider(beanFactory); injectAuthenticationEntryPointIntoExceptionTranslationFilter(beanFactory); @@ -50,8 +54,28 @@ public class HttpSecurityConfigPostProcessor implements BeanFactoryPostProcessor private void injectUserDetailsServiceIntoRememberMeServices(ConfigurableListableBeanFactory beanFactory) { try { BeanDefinition rememberMeServices = beanFactory.getBeanDefinition(BeanIds.REMEMBER_ME_SERVICES); - rememberMeServices.getPropertyValues().addPropertyValue("userDetailsService", + PropertyValue pv = rememberMeServices.getPropertyValues().getPropertyValue("userDetailsService"); + + if (pv == null) { + rememberMeServices.getPropertyValues().addPropertyValue("userDetailsService", ConfigUtils.getUserDetailsService(beanFactory)); + } + } catch (NoSuchBeanDefinitionException e) { + // ignore + } + } + + private void injectUserDetailsServiceIntoX509Provider(ConfigurableListableBeanFactory beanFactory) { + try { + BeanDefinition x509AuthProvider = beanFactory.getBeanDefinition(BeanIds.X509_AUTH_PROVIDER); + PropertyValue pv = x509AuthProvider.getPropertyValues().getPropertyValue("preAuthenticatedUserDetailsService"); + + if (pv == null) { + UserDetailsByNameServiceWrapper preAuthUserService = new UserDetailsByNameServiceWrapper(); + preAuthUserService.setUserDetailsService(ConfigUtils.getUserDetailsService(beanFactory)); + x509AuthProvider.getPropertyValues().addPropertyValue("preAuthenticatedUserDetailsService", + preAuthUserService); + } } catch (NoSuchBeanDefinitionException e) { // ignore } diff --git a/core/src/main/java/org/springframework/security/config/X509BeanDefinitionParser.java b/core/src/main/java/org/springframework/security/config/X509BeanDefinitionParser.java new file mode 100644 index 0000000000..141737a616 --- /dev/null +++ b/core/src/main/java/org/springframework/security/config/X509BeanDefinitionParser.java @@ -0,0 +1,64 @@ +package org.springframework.security.config; + +import org.springframework.security.ui.preauth.PreAuthenticatedProcessingFilterEntryPoint; +import org.springframework.security.ui.preauth.x509.X509PreAuthenticatedProcessingFilter; +import org.springframework.security.ui.preauth.x509.SubjectDnX509PrincipalExtractor; +import org.springframework.security.providers.preauth.PreAuthenticatedAuthenticationProvider; +import org.springframework.security.providers.preauth.UserDetailsByNameServiceWrapper; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.RuntimeBeanReference; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.util.StringUtils; + +import org.w3c.dom.Element; + +/** + * Parses x509 element in namespace, registering an {@link X509PreAuthenticatedProcessingFilter} instance and a + * {@link PreAuthenticatedProcessingFilterEntryPoint}. + * + * @author Luke Taylor + * @version $Id$ + * @since 2.0 + */ +public class X509BeanDefinitionParser implements BeanDefinitionParser { + public static final String ATT_REGEX = "subject-principal-regex"; + public static final String ATT_USER_SERVICE_REF = "user-service-ref"; + + public BeanDefinition parse(Element element, ParserContext parserContext) { + BeanDefinitionBuilder filterBuilder = BeanDefinitionBuilder.rootBeanDefinition(X509PreAuthenticatedProcessingFilter.class); + RootBeanDefinition entryPoint = new RootBeanDefinition(PreAuthenticatedProcessingFilterEntryPoint.class); + + String regex = element.getAttribute(ATT_REGEX); + + if (StringUtils.hasText(regex)) { + SubjectDnX509PrincipalExtractor extractor = new SubjectDnX509PrincipalExtractor(); + extractor.setSubjectDnRegex(regex); + + filterBuilder.addPropertyValue("principalExtractor", extractor); + } + + BeanDefinition provider = new RootBeanDefinition(PreAuthenticatedAuthenticationProvider.class); + ConfigUtils.getRegisteredProviders(parserContext).add(provider); + parserContext.getRegistry().registerBeanDefinition(BeanIds.X509_AUTH_PROVIDER, provider); + + String userServiceRef = element.getAttribute(ATT_USER_SERVICE_REF); + + if (StringUtils.hasText(userServiceRef)) { + RuntimeBeanReference userService = new RuntimeBeanReference(userServiceRef); + BeanDefinition preAuthUserService = new RootBeanDefinition(UserDetailsByNameServiceWrapper.class); + preAuthUserService.getPropertyValues().addPropertyValue("userDetailsService", userService); + provider.getPropertyValues().addPropertyValue("preAuthenticatedUserDetailsService", preAuthUserService); + } + + parserContext.getRegistry().registerBeanDefinition(BeanIds.PRE_AUTH_ENTRY_POINT, entryPoint); + + filterBuilder.addPropertyValue("authenticationManager", new RuntimeBeanReference(BeanIds.AUTHENTICATION_MANAGER)); + + parserContext.getRegistry().registerBeanDefinition(BeanIds.X509_FILTER, filterBuilder.getBeanDefinition()); + + return null; + } +} diff --git a/core/src/main/java/org/springframework/security/providers/preauth/PreAuthenticatedAuthenticationProvider.java b/core/src/main/java/org/springframework/security/providers/preauth/PreAuthenticatedAuthenticationProvider.java old mode 100755 new mode 100644 index 748429aaee..815938cdbf --- a/core/src/main/java/org/springframework/security/providers/preauth/PreAuthenticatedAuthenticationProvider.java +++ b/core/src/main/java/org/springframework/security/providers/preauth/PreAuthenticatedAuthenticationProvider.java @@ -24,6 +24,7 @@ import org.springframework.util.Assert; * a UsernameNotFoundException. * * @author Ruud Senden + * @version $Id$ * @since 2.0 */ public class PreAuthenticatedAuthenticationProvider implements AuthenticationProvider, InitializingBean, Ordered { diff --git a/core/src/main/java/org/springframework/security/ui/FilterChainOrder.java b/core/src/main/java/org/springframework/security/ui/FilterChainOrder.java index 01ad8472e2..24bb1ae0b2 100644 --- a/core/src/main/java/org/springframework/security/ui/FilterChainOrder.java +++ b/core/src/main/java/org/springframework/security/ui/FilterChainOrder.java @@ -62,11 +62,11 @@ public abstract class FilterChainOrder { } /** Allows filters to be used by name in the XSD file without explicit reference to Java constants */ - public static Integer getOrder(String filterName) { + public static int getOrder(String filterName) { Integer order = (Integer) filterNameToOrder.get(filterName); Assert.notNull(order, "Unable to match filter name " + filterName); - return order; + return order.intValue(); } } diff --git a/core/src/main/java/org/springframework/security/ui/preauth/x509/X509PreAuthenticatedProcessingFilter.java b/core/src/main/java/org/springframework/security/ui/preauth/x509/X509PreAuthenticatedProcessingFilter.java index a047ae16d7..4324aba5cf 100644 --- a/core/src/main/java/org/springframework/security/ui/preauth/x509/X509PreAuthenticatedProcessingFilter.java +++ b/core/src/main/java/org/springframework/security/ui/preauth/x509/X509PreAuthenticatedProcessingFilter.java @@ -31,6 +31,10 @@ public class X509PreAuthenticatedProcessingFilter extends AbstractPreAuthenticat X509Certificate[] certs = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate"); if (certs != null && certs.length > 0) { + if (logger.isDebugEnabled()) { + logger.debug("X.509 client authentication certificate:" + certs[0]); + } + return certs[0]; } @@ -46,6 +50,6 @@ public class X509PreAuthenticatedProcessingFilter extends AbstractPreAuthenticat } public int getOrder() { - return FilterChainOrder.X509_FILTER; + return FilterChainOrder.X509_FILTER; } } diff --git a/core/src/main/resources/org/springframework/security/config/spring-security-2.0.rnc b/core/src/main/resources/org/springframework/security/config/spring-security-2.0.rnc index 5d2ab71f7c..c9819bbf77 100644 --- a/core/src/main/resources/org/springframework/security/config/spring-security-2.0.rnc +++ b/core/src/main/resources/org/springframework/security/config/spring-security-2.0.rnc @@ -27,9 +27,13 @@ id = ## A bean identifier, used for referring to the bean elsewhere in the context. attribute id {xsd:ID} ref = - ## Defines a reference to a Spring bean id. + ## Defines a reference to a Spring bean Id. attribute ref {xsd:string} +user-service-ref = + ## A reference to a user-service (or UserDetailsService bean) Id + attribute user-service-ref {xsd:string} + password-encoder = ## element which defines a password encoding strategy. Used by an authentication provider to convert submitted passwords to hashed versions, for example. element password-encoder {ref | (hash? & base64? & salt-source*)} @@ -88,7 +92,7 @@ protect.attlist &= annotation-driven = - ## Activates security annotation scanning. All beans registered in the Spring application context will be scanned for Spring Security annotations. Where found, the beans will automatically be proxied and security authorization applied to the methods accordingly. Please ensure you have the spring-security-tiger-XXX.jar on your classpath. + ## Activates security annotation scanning. All beans registered in the Spring application context will be scanned for Spring Security annotations. Where found, the beans will automatically be proxied and security authorization applied to the methods accordingly. Please ensure you have the spring-security-tiger-XXX.jar on your classpath. element annotation-driven {annotation-driven.attlist} annotation-driven.attlist &= ## Specifies that JSR-250 style attributes are to be used (for example "RolesAllowed" instead of "Secured"). This will require the javax.annotation.security classes on the classpath. Defaults to false. @@ -99,7 +103,7 @@ annotation-driven.attlist &= http = ## Container element for HTTP security configuration - element http {http.attlist, (intercept-url+ & form-login? & http-basic? & logout? & concurrent-session-control? & remember-me? & anonymous? & port-mappings) } + element http {http.attlist, (intercept-url+ & form-login? & x509? & http-basic? & logout? & concurrent-session-control? & remember-me? & anonymous? & port-mappings) } http.attlist &= ## Automatically registers a login form, BASIC authentication, anonymous authentication, logout services, remember-me and servlet-api-integration. If set to "true", all of these capabilities are added (although you can still customize the configuration of each by providing the respective element). If unspecified, defaults to "false". attribute auto-config {"true" | "false" }? @@ -207,48 +211,18 @@ remember-me.attlist &= (attribute key {xsd:string} | (attribute token-repository-ref {xsd:string} | attribute data-source-ref {xsd:string})) anonymous = - ## Adds support for automatically granting all anonymous web requests a particular principal identity and a corresponding granted authority. + ## Adds support for automatically granting all anonymous web requests a particular principal identity and a corresponding granted authority. element anonymous {anonymous.attlist} anonymous.attlist &= - ## The key used between the provider and filter. This generally does not need to be set. If unset, it will default to "doesNotMatter". + ## The key used between the provider and filter. This generally does not need to be set. If unset, it will default to "doesNotMatter". attribute key {xsd:string}? -anonymous.attlist &= - ## The username that should be assigned to the anonymous request. This allows the principal to be identified, which may be important for logging and auditing. if unset, defaults to "anonymousUser". +anonymous.attlist &= + ## The username that should be assigned to the anonymous request. This allows the principal to be identified, which may be important for logging and auditing. if unset, defaults to "anonymousUser". attribute username {xsd:string}? anonymous.attlist &= - ## The granted authority that should be assigned to the anonymous request. Commonly this is used to assign the anonymous request particular roles, which can subsequently be used in authorization decisions. If unset, defaults to "ROLE_ANONYMOUS". + ## The granted authority that should be assigned to the anonymous request. Commonly this is used to assign the anonymous request particular roles, which can subsequently be used in authorization decisions. If unset, defaults to "ROLE_ANONYMOUS". attribute granted-authority {xsd:string}? -authentication-provider = - ## Indicates that the contained user-service should be used as an authentication source. - element authentication-provider {ap.attlist & (user-service | jdbc-user-service) & password-encoder} -ap.attlist &= - ## Specifies a reference to a separately configured UserDetailsService from which to obtain authentication data. - attribute user-service-ref {xsd:string}? - -custom-authentication-provider = - element custom-authentication-provider {cap.attlist} -cap.attlist &= empty - -user-service = - ## Creates an in-memory UserDetailsService from a properties file or a list of "user" child elements. - element user-service {id? & (properties-file | (user*))} -properties-file = - attribute properties {xsd:string}? - -user = - ## Represents a user in the application. - element user {user.attlist, empty} -user.attlist &= - ## The username assigned to the user. - attribute name {xsd:string} -user.attlist &= - ## The password assigned to the user. This may be hashed if the corresponding authentication provider supports hashing (remember to set the "hash" attribute of the "user-service" element). - attribute password {xsd:string} -user.attlist &= - ## One of more authorities granted to the user. Separate authorities with a comma (but no space). For example, "ROLE_USER,ROLE_ADMINISTRATOR" - attribute authorities {xsd:string} - port-mappings = ## Defines the list of mappings between http and https ports for use in redirects element port-mappings {port-mappings.attlist, port-mapping+} @@ -262,11 +236,52 @@ http-port = attribute http {xsd:integer} https-port = attribute https {xsd:integer} + +x509 = + ## Adds support for X.509 client authentication. + element x509 {x509.attlist} +x509.attlist &= + ## The regular expression used to obtain the username from the certificate's subject. Defaults to matching on the common name using the pattern "CN=(.*?),". + attribute subject-principal-regex {xsd:string}? +x509.attlist &= + ## Explicitly specifies which user-service should be used to load user data for X.509 authenticated clients. If ommitted, the default user-service will be used. + user-service-ref? + +authentication-provider = + ## Indicates that the contained user-service should be used as an authentication source. + element authentication-provider {ap.attlist & (user-service | jdbc-user-service) & password-encoder} +ap.attlist &= + ## Specifies a reference to a separately configured UserDetailsService from which to obtain authentication data. + user-service-ref? + +custom-authentication-provider = + element custom-authentication-provider {cap.attlist} +cap.attlist &= empty + +user-service = + ## Creates an in-memory UserDetailsService from a properties file or a list of "user" child elements. + element user-service {id? & (properties-file | (user*))} +properties-file = + attribute properties {xsd:string}? + +user = + ## Represents a user in the application. + element user {user.attlist, empty} +user.attlist &= + ## The username assigned to the user. + attribute name {xsd:string} +user.attlist &= + ## The password assigned to the user. This may be hashed if the corresponding authentication provider supports hashing (remember to set the "hash" attribute of the "user-service" element). + attribute password {xsd:string} +user.attlist &= + ## One of more authorities granted to the user. Separate authorities with a comma (but no space). For example, "ROLE_USER,ROLE_ADMINISTRATOR" + attribute authorities {xsd:string} + jdbc-user-service = - ## Causes creation of a JDBC-based UserDetailsService. + ## Causes creation of a JDBC-based UserDetailsService. element jdbc-user-service {id? & jdbc-user-service.attlist} jdbc-user-service.attlist &= - ## The bean ID of the DataSource which provides the required tables. + ## The bean ID of the DataSource which provides the required tables. attribute data-source-ref {xsd:string} diff --git a/core/src/main/resources/org/springframework/security/config/spring-security-2.0.xsd b/core/src/main/resources/org/springframework/security/config/spring-security-2.0.xsd index 722c100115..721e68bcc0 100644 --- a/core/src/main/resources/org/springframework/security/config/spring-security-2.0.xsd +++ b/core/src/main/resources/org/springframework/security/config/spring-security-2.0.xsd @@ -66,7 +66,14 @@ - Defines a reference to a Spring bean id. + Defines a reference to a Spring bean Id. + + + + + + + A reference to a user-service (or UserDetailsService bean) Id @@ -80,7 +87,7 @@ - Defines a reference to a Spring bean id. + Defines a reference to a Spring bean Id. @@ -258,6 +265,7 @@ + @@ -539,6 +547,48 @@ + + + Defines the list of mappings between http and https ports for use in redirects + + + + + + + + + + + + + + + + + + + + + + Adds support for X.509 client authentication. + + + + + + + + + The regular expression used to obtain the username from the certificate's subject. Defaults to matching on the common name using the pattern "CN=(.*?),". + + + + + A reference to a user-service (or UserDetailsService bean) Id + + + Indicates that the contained user-service should be used as an authentication source. @@ -557,7 +607,7 @@ - Specifies a reference to a separately configured UserDetailsService from which to obtain authentication data. + A reference to a user-service (or UserDetailsService bean) Id @@ -608,28 +658,6 @@ - - - Defines the list of mappings between http and https ports for use in redirects - - - - - - - - - - - - - - - - - - - Causes creation of a JDBC-based UserDetailsService. diff --git a/core/src/test/java/org/springframework/security/config/HttpSecurityBeanDefinitionParserTests.java b/core/src/test/java/org/springframework/security/config/HttpSecurityBeanDefinitionParserTests.java index fc8f712cac..7b8ff04c32 100644 --- a/core/src/test/java/org/springframework/security/config/HttpSecurityBeanDefinitionParserTests.java +++ b/core/src/test/java/org/springframework/security/config/HttpSecurityBeanDefinitionParserTests.java @@ -6,6 +6,7 @@ import org.springframework.security.intercept.web.FilterInvocationDefinitionSour import org.springframework.security.intercept.web.FilterInvocation; import org.springframework.security.securechannel.ChannelProcessingFilter; import org.springframework.security.ui.ExceptionTranslationFilter; +import org.springframework.security.ui.preauth.x509.X509PreAuthenticatedProcessingFilter; import org.springframework.security.ui.basicauth.BasicProcessingFilter; import org.springframework.security.ui.logout.LogoutFilter; import org.springframework.security.ui.rememberme.RememberMeProcessingFilter; @@ -222,6 +223,17 @@ public class HttpSecurityBeanDefinitionParserTests { assertTrue(rememberMeServices instanceof PersistentTokenBasedRememberMeServices); } + @Test + public void x509SupportAddsFilterAtExpectedPosition() throws Exception { + setContext( + "" + + " " + + "" + AUTH_PROVIDER_XML); + List filters = getFilterChainProxy().getFilters("/someurl"); + + assertTrue(filters.get(2) instanceof X509PreAuthenticatedProcessingFilter); + } + private void setContext(String context) { appContext = new InMemoryXmlApplicationContext(context); } diff --git a/samples/tutorial/src/main/webapp/WEB-INF/applicationContext-security-ns.xml b/samples/tutorial/src/main/webapp/WEB-INF/applicationContext-security-ns.xml index 9d66912cc2..2df27f8d4f 100644 --- a/samples/tutorial/src/main/webapp/WEB-INF/applicationContext-security-ns.xml +++ b/samples/tutorial/src/main/webapp/WEB-INF/applicationContext-security-ns.xml @@ -22,8 +22,11 @@ --> - - + + @@ -33,6 +36,8 @@ +