SEC-1168: Added filter-security-metadat-source to namespace.
This commit is contained in:
parent
b50d37fa66
commit
66f7e8bcc8
|
@ -44,6 +44,8 @@ public abstract class Elements {
|
||||||
public static final String CUSTOM_AUTH_PROVIDER = "custom-authentication-provider";
|
public static final String CUSTOM_AUTH_PROVIDER = "custom-authentication-provider";
|
||||||
public static final String CUSTOM_AFTER_INVOCATION_PROVIDER = "custom-after-invocation-provider";
|
public static final String CUSTOM_AFTER_INVOCATION_PROVIDER = "custom-after-invocation-provider";
|
||||||
public static final String X509 = "x509";
|
public static final String X509 = "x509";
|
||||||
|
public static final String FILTER_SECURITY_METADATA_SOURCE = "filter-security-metadata-source";
|
||||||
|
@Deprecated
|
||||||
public static final String FILTER_INVOCATION_DEFINITION_SOURCE = "filter-invocation-definition-source";
|
public static final String FILTER_INVOCATION_DEFINITION_SOURCE = "filter-invocation-definition-source";
|
||||||
public static final String LDAP_PASSWORD_COMPARE = "password-compare";
|
public static final String LDAP_PASSWORD_COMPARE = "password-compare";
|
||||||
}
|
}
|
||||||
|
|
|
@ -409,8 +409,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
|
||||||
new DefaultFilterInvocationSecurityMetadataSource(matcher, channelRequestMap);
|
new DefaultFilterInvocationSecurityMetadataSource(matcher, channelRequestMap);
|
||||||
channelFilterInvDefSource.setStripQueryStringFromUrls(matcher instanceof AntUrlPathMatcher);
|
channelFilterInvDefSource.setStripQueryStringFromUrls(matcher instanceof AntUrlPathMatcher);
|
||||||
|
|
||||||
channelFilter.getPropertyValues().addPropertyValue("filterInvocationSecurityMetadataSource",
|
channelFilter.getPropertyValues().addPropertyValue("securityMetadataSource", channelFilterInvDefSource);
|
||||||
channelFilterInvDefSource);
|
|
||||||
RootBeanDefinition channelDecisionManager = new RootBeanDefinition(ChannelDecisionManagerImpl.class);
|
RootBeanDefinition channelDecisionManager = new RootBeanDefinition(ChannelDecisionManagerImpl.class);
|
||||||
ManagedList channelProcessors = new ManagedList(3);
|
ManagedList channelProcessors = new ManagedList(3);
|
||||||
RootBeanDefinition secureChannelProcessor = new RootBeanDefinition(SecureChannelProcessor.class);
|
RootBeanDefinition secureChannelProcessor = new RootBeanDefinition(SecureChannelProcessor.class);
|
||||||
|
|
|
@ -12,6 +12,7 @@ import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
|
||||||
*/
|
*/
|
||||||
public class SecurityNamespaceHandler extends NamespaceHandlerSupport {
|
public class SecurityNamespaceHandler extends NamespaceHandlerSupport {
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public void init() {
|
public void init() {
|
||||||
// Parsers
|
// Parsers
|
||||||
registerBeanDefinitionParser(Elements.LDAP_PROVIDER, new LdapProviderBeanDefinitionParser());
|
registerBeanDefinitionParser(Elements.LDAP_PROVIDER, new LdapProviderBeanDefinitionParser());
|
||||||
|
@ -24,12 +25,13 @@ public class SecurityNamespaceHandler extends NamespaceHandlerSupport {
|
||||||
registerBeanDefinitionParser(Elements.GLOBAL_METHOD_SECURITY, new GlobalMethodSecurityBeanDefinitionParser());
|
registerBeanDefinitionParser(Elements.GLOBAL_METHOD_SECURITY, new GlobalMethodSecurityBeanDefinitionParser());
|
||||||
registerBeanDefinitionParser(Elements.AUTHENTICATION_MANAGER, new AuthenticationManagerBeanDefinitionParser());
|
registerBeanDefinitionParser(Elements.AUTHENTICATION_MANAGER, new AuthenticationManagerBeanDefinitionParser());
|
||||||
registerBeanDefinitionParser(Elements.FILTER_INVOCATION_DEFINITION_SOURCE, new FilterInvocationSecurityMetadataSourceBeanDefinitionParser());
|
registerBeanDefinitionParser(Elements.FILTER_INVOCATION_DEFINITION_SOURCE, new FilterInvocationSecurityMetadataSourceBeanDefinitionParser());
|
||||||
|
registerBeanDefinitionParser(Elements.FILTER_SECURITY_METADATA_SOURCE, new FilterInvocationSecurityMetadataSourceBeanDefinitionParser());
|
||||||
|
|
||||||
// Decorators
|
// Decorators
|
||||||
registerBeanDefinitionDecorator(Elements.INTERCEPT_METHODS, new InterceptMethodsBeanDefinitionDecorator());
|
registerBeanDefinitionDecorator(Elements.INTERCEPT_METHODS, new InterceptMethodsBeanDefinitionDecorator());
|
||||||
registerBeanDefinitionDecorator(Elements.FILTER_CHAIN_MAP, new FilterChainMapBeanDefinitionDecorator());
|
registerBeanDefinitionDecorator(Elements.FILTER_CHAIN_MAP, new FilterChainMapBeanDefinitionDecorator());
|
||||||
registerBeanDefinitionDecorator(Elements.CUSTOM_FILTER, new OrderedFilterBeanDefinitionDecorator());
|
registerBeanDefinitionDecorator(Elements.CUSTOM_FILTER, new OrderedFilterBeanDefinitionDecorator());
|
||||||
registerBeanDefinitionDecorator(Elements.CUSTOM_AUTH_PROVIDER, new CustomAuthenticationProviderBeanDefinitionDecorator());
|
registerBeanDefinitionDecorator(Elements.CUSTOM_AUTH_PROVIDER, new CustomAuthenticationProviderBeanDefinitionDecorator());
|
||||||
registerBeanDefinitionDecorator(Elements.CUSTOM_AFTER_INVOCATION_PROVIDER, new CustomAfterInvocationProviderBeanDefinitionDecorator());
|
registerBeanDefinitionDecorator(Elements.CUSTOM_AFTER_INVOCATION_PROVIDER, new CustomAfterInvocationProviderBeanDefinitionDecorator());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -367,20 +367,24 @@ filter-chain.attlist &=
|
||||||
filter-chain.attlist &=
|
filter-chain.attlist &=
|
||||||
attribute filters {xsd:token}
|
attribute filters {xsd:token}
|
||||||
|
|
||||||
filter-invocation-definition-source =
|
filter-security-metadata-source =
|
||||||
## Used to explicitly configure a FilterInvocationDefinitionSource bean for use with a FilterSecurityInterceptor. Usually only needed if you are configuring a FilterChainProxy explicitly, rather than using the <http> element. The intercept-url elements used should only contain pattern, method and access attributes. Any others will result in a configuration error.
|
## Used to explicitly configure a FilterSecurityMetadataSource bean for use with a FilterSecurityInterceptor. Usually only needed if you are configuring a FilterChainProxy explicitly, rather than using the <http> element. The intercept-url elements used should only contain pattern, method and access attributes. Any others will result in a configuration error.
|
||||||
element filter-invocation-definition-source {fids.attlist, intercept-url+}
|
element filter-security-metadata-source {fsmds.attlist, intercept-url+}
|
||||||
fids.attlist &=
|
fsmds.attlist &=
|
||||||
use-expressions?
|
use-expressions?
|
||||||
fids.attlist &=
|
fsmds.attlist &=
|
||||||
id?
|
id?
|
||||||
fids.attlist &=
|
fsmds.attlist &=
|
||||||
## as for http element
|
## as for http element
|
||||||
attribute lowercase-comparisons {boolean}?
|
attribute lowercase-comparisons {boolean}?
|
||||||
fids.attlist &=
|
fsmds.attlist &=
|
||||||
## as for http element
|
## as for http element
|
||||||
path-type?
|
path-type?
|
||||||
|
|
||||||
|
filter-invocation-definition-source =
|
||||||
|
## Deprecated synonym for filter-security-metadata-source
|
||||||
|
element filter-invocation-definition-source {fsmds.attlist, intercept-url+}
|
||||||
|
|
||||||
http-basic =
|
http-basic =
|
||||||
## Adds support for basic authentication (this is an element to permit future expansion, such as supporting an "ignoreFailure" attribute)
|
## Adds support for basic authentication (this is an element to permit future expansion, such as supporting an "ignoreFailure" attribute)
|
||||||
element http-basic {empty}
|
element http-basic {empty}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -10,7 +10,7 @@
|
||||||
<xsl:output method="xml" indent="yes"/>
|
<xsl:output method="xml" indent="yes"/>
|
||||||
|
|
||||||
<xsl:variable name="elts-to-inline">
|
<xsl:variable name="elts-to-inline">
|
||||||
<xsl:text>,access-denied-handler,anonymous,concurrent-session-control,filter-chain,form-login,http-basic,intercept-url,logout,password-encoder,port-mappings,port-mapper,password-compare,protect,protect-pointcut,pre-post-annotation-handling,pre-invocation-advice,post-invocation-advice,invocation-attribute-factory,remember-me,salt-source,x509,</xsl:text>
|
<xsl:text>,access-denied-handler,anonymous,concurrent-session-control,user,port-mapping,openid-login,expression-handler,filter-chain,form-login,http-basic,intercept-url,logout,password-encoder,port-mappings,port-mapper,password-compare,protect,protect-pointcut,pre-post-annotation-handling,pre-invocation-advice,post-invocation-advice,invocation-attribute-factory,remember-me,salt-source,x509,</xsl:text>
|
||||||
</xsl:variable>
|
</xsl:variable>
|
||||||
|
|
||||||
<xsl:template match="xs:element">
|
<xsl:template match="xs:element">
|
||||||
|
|
|
@ -23,7 +23,7 @@ import org.w3c.dom.Element;
|
||||||
* @author Luke Taylor
|
* @author Luke Taylor
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
public class FilterInvocationSecurityMetadataSourceBeanDefinitionParserTests {
|
public class FilterSecurityMetadataSourceBeanDefinitionParserTests {
|
||||||
private AbstractXmlApplicationContext appContext;
|
private AbstractXmlApplicationContext appContext;
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
@ -46,9 +46,9 @@ public class FilterInvocationSecurityMetadataSourceBeanDefinitionParserTests {
|
||||||
@Test
|
@Test
|
||||||
public void parsingMinimalConfigurationIsSuccessful() {
|
public void parsingMinimalConfigurationIsSuccessful() {
|
||||||
setContext(
|
setContext(
|
||||||
"<filter-invocation-definition-source id='fids'>" +
|
"<filter-security-metadata-source id='fids'>" +
|
||||||
" <intercept-url pattern='/**' access='ROLE_A'/>" +
|
" <intercept-url pattern='/**' access='ROLE_A'/>" +
|
||||||
"</filter-invocation-definition-source>");
|
"</filter-security-metadata-source>");
|
||||||
DefaultFilterInvocationSecurityMetadataSource fids = (DefaultFilterInvocationSecurityMetadataSource) appContext.getBean("fids");
|
DefaultFilterInvocationSecurityMetadataSource fids = (DefaultFilterInvocationSecurityMetadataSource) appContext.getBean("fids");
|
||||||
List<? extends ConfigAttribute> cad = fids.getAttributes(createFilterInvocation("/anything", "GET"));
|
List<? extends ConfigAttribute> cad = fids.getAttributes(createFilterInvocation("/anything", "GET"));
|
||||||
assertNotNull(cad);
|
assertNotNull(cad);
|
||||||
|
@ -61,11 +61,11 @@ public class FilterInvocationSecurityMetadataSourceBeanDefinitionParserTests {
|
||||||
"<http auto-config='true'/>" +
|
"<http auto-config='true'/>" +
|
||||||
"<b:bean id='fsi' class='org.springframework.security.web.access.intercept.FilterSecurityInterceptor' autowire='byType'>" +
|
"<b:bean id='fsi' class='org.springframework.security.web.access.intercept.FilterSecurityInterceptor' autowire='byType'>" +
|
||||||
" <b:property name='securityMetadataSource'>" +
|
" <b:property name='securityMetadataSource'>" +
|
||||||
" <filter-invocation-definition-source>" +
|
" <filter-security-metadata-source>" +
|
||||||
" <intercept-url pattern='/secure/extreme/**' access='ROLE_SUPERVISOR'/>" +
|
" <intercept-url pattern='/secure/extreme/**' access='ROLE_SUPERVISOR'/>" +
|
||||||
" <intercept-url pattern='/secure/**' access='ROLE_USER'/>" +
|
" <intercept-url pattern='/secure/**' access='ROLE_USER'/>" +
|
||||||
" <intercept-url pattern='/**' access='ROLE_USER'/>" +
|
" <intercept-url pattern='/**' access='ROLE_USER'/>" +
|
||||||
" </filter-invocation-definition-source>" +
|
" </filter-security-metadata-source>" +
|
||||||
" </b:property>" +
|
" </b:property>" +
|
||||||
"</b:bean>" + ConfigTestUtils.AUTH_PROVIDER_XML);
|
"</b:bean>" + ConfigTestUtils.AUTH_PROVIDER_XML);
|
||||||
|
|
|
@ -16,10 +16,17 @@
|
||||||
|
|
||||||
<global-method-security run-as-manager-ref="myRunAsManager">
|
<global-method-security run-as-manager-ref="myRunAsManager">
|
||||||
<pre-post-annotation-handling>
|
<pre-post-annotation-handling>
|
||||||
<
|
<invocation-attribute-factory ref=""/>
|
||||||
|
<pre-invocation-advice ref=""/>
|
||||||
|
<post-invocation-advice ref=""/>
|
||||||
</pre-post-annotation-handling>
|
</pre-post-annotation-handling>
|
||||||
</global-method-security>
|
</global-method-security>
|
||||||
|
|
||||||
|
<filter-security-metadata-source>
|
||||||
|
<intercept-url pattern=""/>
|
||||||
|
</filter-security-metadata-source>
|
||||||
|
|
||||||
|
|
||||||
<http>
|
<http>
|
||||||
<access-denied-handler error-page="/go-away.html"/>
|
<access-denied-handler error-page="/go-away.html"/>
|
||||||
<intercept-url pattern="/**" access="ROLE_USER" />
|
<intercept-url pattern="/**" access="ROLE_USER" />
|
||||||
|
|
|
@ -1,47 +1,41 @@
|
||||||
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="anonymous">
|
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="anonymous">
|
||||||
|
<info>
|
||||||
<info><title>Anonymous Authentication</title></info>
|
<title>Anonymous Authentication</title>
|
||||||
|
</info>
|
||||||
|
<section xml:id="anonymous-overview">
|
||||||
<section xml:id="anonymous-overview">
|
<info>
|
||||||
<info><title>Overview</title></info>
|
<title>Overview</title>
|
||||||
|
</info>
|
||||||
<para>Particularly in the case of web request URI security, sometimes
|
<para>Particularly in the case of web request URI security, sometimes it is more convenient
|
||||||
it is more convenient to assign configuration attributes against every
|
to assign configuration attributes against every possible secure object invocation. Put
|
||||||
possible secure object invocation. Put differently, sometimes it is
|
differently, sometimes it is nice to say <literal>ROLE_SOMETHING</literal> is required
|
||||||
nice to say <literal>ROLE_SOMETHING</literal> is required by default
|
by default and only allow certain exceptions to this rule, such as for login, logout and
|
||||||
and only allow certain exceptions to this rule, such as for login,
|
home pages of an application. There are also other situations where anonymous
|
||||||
logout and home pages of an application. There are also other
|
authentication would be desired, such as when an auditing interceptor queries the
|
||||||
situations where anonymous authentication would be desired, such as
|
<classname>SecurityContextHolder</classname> to identify which principal was
|
||||||
when an auditing interceptor queries the
|
responsible for a given operation. Such classes can be authored with more robustness if
|
||||||
<classname>SecurityContextHolder</classname> to identify which principal
|
they know the <classname>SecurityContextHolder</classname> always contains an
|
||||||
was responsible for a given operation. Such classes can be authored
|
<interfacename>Authentication</interfacename> object, and never
|
||||||
with more robustness if they know the
|
<literal>null</literal>.</para>
|
||||||
<classname>SecurityContextHolder</classname> always contains an
|
</section>
|
||||||
<interfacename>Authentication</interfacename> object, and never
|
<section xml:id="anonymous-config">
|
||||||
<literal>null</literal>.</para>
|
<info>
|
||||||
</section>
|
<title>Configuration</title>
|
||||||
|
</info>
|
||||||
<section xml:id="anonymous-config">
|
<para>Spring Security provides three classes that together provide an anonymous
|
||||||
<info><title>Configuration</title></info>
|
authentication feature. <literal>AnonymousAuthenticationToken</literal> is an
|
||||||
|
implementation of <interfacename>Authentication</interfacename>, and stores the
|
||||||
<para>Spring Security provides three classes that together provide an
|
<interfacename>GrantedAuthority</interfacename>[]s which apply to the anonymous
|
||||||
anonymous authentication feature.
|
principal. There is a corresponding <literal>AnonymousAuthenticationProvider</literal>,
|
||||||
<literal>AnonymousAuthenticationToken</literal> is an implementation
|
which is chained into the <literal>ProviderManager</literal> so that
|
||||||
of <interfacename>Authentication</interfacename>, and stores the
|
<literal>AnonymousAuthenticationTokens</literal> are accepted. Finally, there is an
|
||||||
<interfacename>GrantedAuthority</interfacename>[]s which apply to the anonymous
|
AnonymousProcessingFilter, which is chained after the normal authentication mechanisms
|
||||||
principal. There is a corresponding
|
and automatically add an <literal>AnonymousAuthenticationToken</literal> to the
|
||||||
<literal>AnonymousAuthenticationProvider</literal>, which is chained
|
<classname>SecurityContextHolder</classname> if there is no existing
|
||||||
into the <literal>ProviderManager</literal> so that
|
<interfacename>Authentication</interfacename> held there. The definition of the
|
||||||
<literal>AnonymousAuthenticationTokens</literal> are accepted.
|
filter and authentication provider appears as follows:</para>
|
||||||
Finally, there is an AnonymousProcessingFilter, which is chained after
|
<para>
|
||||||
the normal authentication mechanisms and automatically add an
|
<programlisting>
|
||||||
<literal>AnonymousAuthenticationToken</literal> to the
|
|
||||||
<classname>SecurityContextHolder</classname> if there is no existing
|
|
||||||
<interfacename>Authentication</interfacename> held there. The definition of the
|
|
||||||
filter and authentication provider appears as follows:</para>
|
|
||||||
|
|
||||||
<para><programlisting>
|
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
<bean id="anonymousProcessingFilter"
|
<bean id="anonymousProcessingFilter"
|
||||||
class="org.springframework.security.web.authentication.AnonymousProcessingFilter">
|
class="org.springframework.security.web.authentication.AnonymousProcessingFilter">
|
||||||
|
@ -53,53 +47,44 @@
|
||||||
class="org.springframework.security.authentication.AnonymousAuthenticationProvider">
|
class="org.springframework.security.authentication.AnonymousAuthenticationProvider">
|
||||||
<property name="key" value="foobar"/>
|
<property name="key" value="foobar"/>
|
||||||
</bean>]]>
|
</bean>]]>
|
||||||
</programlisting></para>
|
</programlisting>
|
||||||
|
</para>
|
||||||
<para>The <literal>key</literal> is shared between the filter and
|
<para>The <literal>key</literal> is shared between the filter and authentication provider,
|
||||||
authentication provider, so that tokens created by the former are
|
so that tokens created by the former are accepted by the latter. The
|
||||||
accepted by the latter. The <literal>userAttribute</literal> is
|
<literal>userAttribute</literal> is expressed in the form of
|
||||||
expressed in the form of
|
<literal>usernameInTheAuthenticationToken,grantedAuthority[,grantedAuthority]</literal>.
|
||||||
<literal>usernameInTheAuthenticationToken,grantedAuthority[,grantedAuthority]</literal>.
|
This is the same syntax as used after the equals sign for
|
||||||
This is the same syntax as used after the equals sign for
|
<literal>InMemoryDaoImpl</literal>'s <literal>userMap</literal> property.</para>
|
||||||
<literal>InMemoryDaoImpl</literal>'s <literal>userMap</literal>
|
<para>As explained earlier, the benefit of anonymous authentication is that all URI patterns
|
||||||
property.</para>
|
can have security applied to them. For example:</para>
|
||||||
|
<para><programlisting>
|
||||||
<para>As explained earlier, the benefit of anonymous authentication is
|
|
||||||
that all URI patterns can have security applied to them. For
|
|
||||||
example:</para>
|
|
||||||
|
|
||||||
<para><programlisting>
|
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
<bean id="filterInvocationInterceptor"
|
<bean id="filterInvocationInterceptor"
|
||||||
class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
|
class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
|
||||||
<property name="authenticationManager" ref="authenticationManager"/>
|
<property name="authenticationManager" ref="authenticationManager"/>
|
||||||
<property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/>
|
<property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/>
|
||||||
<property name="objectDefinitionSource">
|
<property name="securityMetadata">
|
||||||
<security:filter-invocation-definition-source>
|
<security:filter-security-metadata-source>
|
||||||
<security:intercept-url pattern='/index.jsp' access='ROLE_ANONYMOUS,ROLE_USER'/>
|
<security:intercept-url pattern='/index.jsp' access='ROLE_ANONYMOUS,ROLE_USER'/>
|
||||||
<security:intercept-url pattern='/hello.htm' access='ROLE_ANONYMOUS,ROLE_USER'/>
|
<security:intercept-url pattern='/hello.htm' access='ROLE_ANONYMOUS,ROLE_USER'/>
|
||||||
<security:intercept-url pattern='/logoff.jsp' access='ROLE_ANONYMOUS,ROLE_USER'/>
|
<security:intercept-url pattern='/logoff.jsp' access='ROLE_ANONYMOUS,ROLE_USER'/>
|
||||||
<security:intercept-url pattern='/login.jsp' access='ROLE_ANONYMOUS,ROLE_USER'/>
|
<security:intercept-url pattern='/login.jsp' access='ROLE_ANONYMOUS,ROLE_USER'/>
|
||||||
<security:intercept-url pattern='/**' access='ROLE_USER'/>
|
<security:intercept-url pattern='/**' access='ROLE_USER'/>
|
||||||
</security:filter-invocation-definition-source>" +
|
</security:filter-security-metadata-source>" +
|
||||||
</property>
|
</property>
|
||||||
</bean>]]>
|
</bean>]]>
|
||||||
</programlisting>Rounding out the anonymous authentication discussion
|
</programlisting>Rounding out the anonymous authentication discussion is the
|
||||||
is the <literal>AuthenticationTrustResolver</literal> interface, with
|
<literal>AuthenticationTrustResolver</literal> interface, with its corresponding
|
||||||
its corresponding <literal>AuthenticationTrustResolverImpl</literal>
|
<literal>AuthenticationTrustResolverImpl</literal> implementation. This interface
|
||||||
implementation. This interface provides an
|
provides an <literal>isAnonymous(Authentication)</literal> method, which allows
|
||||||
<literal>isAnonymous(Authentication)</literal> method, which allows
|
interested classes to take into account this special type of authentication status. The
|
||||||
interested classes to take into account this special type of
|
<classname>ExceptionTranslationFilter</classname> uses this interface in processing
|
||||||
authentication status. The
|
<literal>AccessDeniedException</literal>s. If an
|
||||||
<classname>ExceptionTranslationFilter</classname> uses this interface in
|
<literal>AccessDeniedException</literal> is thrown, and the authentication is of an
|
||||||
processing <literal>AccessDeniedException</literal>s. If an
|
anonymous type, instead of throwing a 403 (forbidden) response, the filter will instead
|
||||||
<literal>AccessDeniedException</literal> is thrown, and the
|
commence the <interfacename>AuthenticationEntryPoint</interfacename> so the principal
|
||||||
authentication is of an anonymous type, instead of throwing a 403
|
can authenticate properly. This is a necessary distinction, otherwise principals would
|
||||||
(forbidden) response, the filter will instead commence the
|
always be deemed "authenticated" and never be given an opportunity to login via form,
|
||||||
<interfacename>AuthenticationEntryPoint</interfacename> so the principal can
|
basic, digest or some other normal authentication mechanism</para>
|
||||||
authenticate properly. This is a necessary distinction, otherwise
|
</section>
|
||||||
principals would always be deemed "authenticated" and never be given
|
|
||||||
an opportunity to login via form, basic, digest or some other normal
|
|
||||||
authentication mechanism</para>
|
|
||||||
</section>
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
|
@ -1,52 +1,49 @@
|
||||||
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="channel-security" xmlns:xlink="http://www.w3.org/1999/xlink">
|
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="channel-security"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
<info><title>Channel Security</title></info>
|
<info>
|
||||||
|
<title>Channel Security</title>
|
||||||
<section xml:id="channel-security-overview">
|
</info>
|
||||||
<info><title>Overview</title></info>
|
<section xml:id="channel-security-overview">
|
||||||
|
<info>
|
||||||
<para>In addition to coordinating the authentication and authorization
|
<title>Overview</title>
|
||||||
requirements of your application, Spring Security is also able to
|
</info>
|
||||||
ensure unauthenticated web requests have certain properties. These
|
<para>In addition to coordinating the authentication and authorization requirements of your
|
||||||
properties may include being of a particular transport type, having a
|
application, Spring Security is also able to ensure unauthenticated web requests have
|
||||||
particular <literal>HttpSession</literal> attribute set and so on. The
|
certain properties. These properties may include being of a particular transport type,
|
||||||
most common requirement is for your web requests to be received using
|
having a particular <literal>HttpSession</literal> attribute set and so on. The most
|
||||||
a particular transport protocol, such as HTTPS.</para>
|
common requirement is for your web requests to be received using a particular transport
|
||||||
|
protocol, such as HTTPS.</para>
|
||||||
<para>An important issue in considering transport security is that of
|
<para>An important issue in considering transport security is that of session hijacking.
|
||||||
session hijacking. Your web container manages a
|
Your web container manages a <literal>HttpSession</literal> by reference to a
|
||||||
<literal>HttpSession</literal> by reference to a
|
<literal>jsessionid</literal> that is sent to user agents either via a cookie or URL
|
||||||
<literal>jsessionid</literal> that is sent to user agents either via a
|
rewriting. If the <literal>jsessionid</literal> is ever sent over HTTP, there is a
|
||||||
cookie or URL rewriting. If the <literal>jsessionid</literal> is ever
|
possibility that session identifier can be intercepted and used to impersonate the user
|
||||||
sent over HTTP, there is a possibility that session identifier can be
|
after they complete the authentication process. This is because most web containers
|
||||||
intercepted and used to impersonate the user after they complete the
|
maintain the same session identifier for a given user, even after they switch from HTTP
|
||||||
authentication process. This is because most web containers maintain
|
to HTTPS pages.</para>
|
||||||
the same session identifier for a given user, even after they switch
|
<para>If session hijacking is considered too significant a risk for your particular
|
||||||
from HTTP to HTTPS pages.</para>
|
application, the only option is to use HTTPS for every request. This means the
|
||||||
|
<literal>jsessionid</literal> is never sent across an insecure channel. You will
|
||||||
<para>If session hijacking is considered too significant a risk for
|
need to ensure your <literal>web.xml</literal>-defined
|
||||||
your particular application, the only option is to use HTTPS for every
|
<literal><welcome-file></literal> points to an HTTPS location, and the
|
||||||
request. This means the <literal>jsessionid</literal> is never sent
|
application never directs the user to an HTTP location. Spring Security provides a
|
||||||
across an insecure channel. You will need to ensure your
|
solution to assist with the latter.</para>
|
||||||
<literal>web.xml</literal>-defined
|
</section>
|
||||||
<literal><welcome-file></literal> points to an HTTPS location,
|
<section xml:id="channel-security-config">
|
||||||
and the application never directs the user to an HTTP location. Spring
|
<info>
|
||||||
Security provides a solution to assist with the latter.</para>
|
<title>Configuration</title>
|
||||||
</section>
|
</info>
|
||||||
|
<para>Channel security is supported by the <link xlink:href="#ns-requires-channel">security
|
||||||
<section xml:id="channel-security-config">
|
namespace</link> by means of the <literal>requires-channel</literal> attribute on
|
||||||
<info><title>Configuration</title></info>
|
the <literal><intercept-url></literal> element and this is the simplest (and
|
||||||
<para>Channel security is supported by the <link xlink:href="#ns-requires-channel">security namespace</link>
|
recommended approach).</para>
|
||||||
by means of the <literal>requires-channel</literal> attribute on the <literal><intercept-url></literal>
|
<para>To confiure channel security explicitly, you would define the following the filter in
|
||||||
element and this is the simplest (and recommended approach).</para>
|
your application context: <programlisting><![CDATA[
|
||||||
<para>To confiure channel security explicitly, you would define the following the filter in your application
|
|
||||||
context:
|
|
||||||
<programlisting><![CDATA[
|
|
||||||
<bean id="channelProcessingFilter"
|
<bean id="channelProcessingFilter"
|
||||||
class="org.springframework.security.web.access.channel.ChannelProcessingFilter">
|
class="org.springframework.security.web.access.channel.ChannelProcessingFilter">
|
||||||
<property name="channelDecisionManager" ref="channelDecisionManager"/>
|
<property name="channelDecisionManager" ref="channelDecisionManager"/>
|
||||||
<property name="filterInvocationSecurityMetadataSource">
|
<property name="securityMetadataSource">
|
||||||
<security:filter-invocation-definition-source path-type="regex">
|
<security:filter-security-metadata-source path-type="regex">
|
||||||
<security:intercept-url pattern="\A/secure/.*\Z"
|
<security:intercept-url pattern="\A/secure/.*\Z"
|
||||||
access="REQUIRES_SECURE_CHANNEL"/>
|
access="REQUIRES_SECURE_CHANNEL"/>
|
||||||
<security:intercept-url pattern="\A/acegilogin.jsp.*\Z"
|
<security:intercept-url pattern="\A/acegilogin.jsp.*\Z"
|
||||||
|
@ -54,7 +51,7 @@
|
||||||
<security:intercept-url pattern="\A/j_spring_security_check.*\Z"
|
<security:intercept-url pattern="\A/j_spring_security_check.*\Z"
|
||||||
access="REQUIRES_SECURE_CHANNEL"/>
|
access="REQUIRES_SECURE_CHANNEL"/>
|
||||||
<security:intercept-url pattern="\A/.*\Z" access="ANY_CHANNEL"/>
|
<security:intercept-url pattern="\A/.*\Z" access="ANY_CHANNEL"/>
|
||||||
</security:filter-invocation-definition-source>
|
</security:filter-security-metadata-source>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
@ -73,95 +70,73 @@
|
||||||
<bean id="insecureChannelProcessor"
|
<bean id="insecureChannelProcessor"
|
||||||
class="org.springframework.security.access.channel.InsecureChannelProcessor"/>]]>
|
class="org.springframework.security.access.channel.InsecureChannelProcessor"/>]]>
|
||||||
</programlisting>
|
</programlisting>
|
||||||
Like <classname>FilterSecurityInterceptor</classname>, Apache Ant
|
Like <classname>FilterSecurityInterceptor</classname>, Apache Ant style paths are also
|
||||||
style paths are also supported by the
|
supported by the <literal>ChannelProcessingFilter</literal>.</para>
|
||||||
<literal>ChannelProcessingFilter</literal>.</para>
|
<para>The <literal>ChannelProcessingFilter</literal> operates by filtering all web requests
|
||||||
|
and determining the configuration attributes that apply. It then delegates to the
|
||||||
<para>The <literal>ChannelProcessingFilter</literal> operates by
|
<literal>ChannelDecisionManager</literal>. The default implementation,
|
||||||
filtering all web requests and determining the configuration
|
<literal>ChannelDecisionManagerImpl</literal>, should suffice in most cases. It
|
||||||
attributes that apply. It then delegates to the
|
simply delegates to the list of configured <literal>ChannelProcessor</literal>
|
||||||
<literal>ChannelDecisionManager</literal>. The default implementation,
|
instances. The attribute <literal>ANY_CHANNEL</literal> can be used to override this
|
||||||
<literal>ChannelDecisionManagerImpl</literal>, should suffice in most
|
behaviour and skip a particular URL. Otherwise, a <literal>ChannelProcessor</literal>
|
||||||
cases. It simply delegates to the list of configured
|
will review the request, and if it is unhappy with the request (e.g. if it was received
|
||||||
<literal>ChannelProcessor</literal> instances. The attribute <literal>ANY_CHANNEL</literal>
|
across the incorrect transport protocol), it will perform a redirect, throw an exception
|
||||||
can be used to override this behaviour and skip a particular URL. Otherwise, a
|
or take whatever other action is appropriate.</para>
|
||||||
<literal>ChannelProcessor</literal> will review the request, and if it
|
<para>Included with Spring Security are two concrete <literal>ChannelProcessor</literal>
|
||||||
is unhappy with the request (e.g. if it was received across the incorrect
|
implementations: <literal>SecureChannelProcessor</literal> ensures requests with a
|
||||||
transport protocol), it will perform a redirect, throw an exception or
|
configuration attribute of <literal>REQUIRES_SECURE_CHANNEL</literal> are received over
|
||||||
take whatever other action is appropriate.</para>
|
HTTPS, whilst <literal>InsecureChannelProcessor</literal> ensures requests with a
|
||||||
|
configuration attribute of <literal>REQUIRES_INSECURE_CHANNEL</literal> are received
|
||||||
<para>Included with Spring Security are two concrete
|
over HTTP. Both implementations delegate to a <literal>ChannelEntryPoint</literal> if
|
||||||
<literal>ChannelProcessor</literal> implementations:
|
the required transport protocol is not used. The two
|
||||||
<literal>SecureChannelProcessor</literal> ensures requests with a
|
<literal>ChannelEntryPoint</literal> implementations included with Spring Security
|
||||||
configuration attribute of <literal>REQUIRES_SECURE_CHANNEL</literal>
|
simply redirect the request to HTTP and HTTPS as appropriate. Appropriate defaults are
|
||||||
are received over HTTPS, whilst
|
assigned to the <literal>ChannelProcessor</literal> implementations for the
|
||||||
<literal>InsecureChannelProcessor</literal> ensures requests with a
|
configuration attribute keywords they respond to and the
|
||||||
configuration attribute of
|
<interfacename>ChannelEntryPoint</interfacename> they delegate to, although you have
|
||||||
<literal>REQUIRES_INSECURE_CHANNEL</literal> are received over HTTP.
|
the ability to override these using the application context.</para>
|
||||||
Both implementations delegate to a
|
<para>Note that the redirections are absolute (eg
|
||||||
<literal>ChannelEntryPoint</literal> if the required transport
|
<literal>http://www.company.com:8080/app/page</literal>), not relative (eg
|
||||||
protocol is not used. The two <literal>ChannelEntryPoint</literal>
|
<literal>/app/page</literal>). During testing it was discovered that Internet
|
||||||
implementations included with Spring Security simply redirect the
|
Explorer 6 Service Pack 1 has a bug whereby it does not respond correctly to a
|
||||||
request to HTTP and HTTPS as appropriate. Appropriate defaults are
|
redirection instruction which also changes the port to use. Accordingly, absolute URLs
|
||||||
assigned to the <literal>ChannelProcessor</literal> implementations
|
are used in conjunction with bug detection logic in the
|
||||||
for the configuration attribute keywords they respond to and the
|
<classname>PortResolverImpl</classname> that is wired up by default to many Spring
|
||||||
<interfacename>ChannelEntryPoint</interfacename> they delegate to, although you
|
Security beans. Please refer to the JavaDocs for <classname>PortResolverImpl</classname>
|
||||||
have the ability to override these using the application
|
for further details.</para>
|
||||||
context.</para>
|
<para>You should note that using a secure channel is recommended if usernames and passwords
|
||||||
|
are to be kept secure during the login process. If you do decide to use
|
||||||
<para>Note that the redirections are absolute (eg
|
<classname>ChannelProcessingFilter</classname> with form-based login, please ensure
|
||||||
<literal>http://www.company.com:8080/app/page</literal>), not relative
|
that your login page is set to <literal>REQUIRES_SECURE_CHANNEL</literal>, and that the
|
||||||
(eg <literal>/app/page</literal>). During testing it was discovered
|
<literal>LoginUrlAuthenticationEntryPoint.forceHttps</literal> property is
|
||||||
that Internet Explorer 6 Service Pack 1 has a bug whereby it does not
|
<literal>true</literal>.</para>
|
||||||
respond correctly to a redirection instruction which also changes the
|
</section>
|
||||||
port to use. Accordingly, absolute URLs are used in conjunction with
|
<section xml:id="channel-security-conclusion">
|
||||||
bug detection logic in the <classname>PortResolverImpl</classname> that is
|
<info>
|
||||||
wired up by default to many Spring Security beans. Please refer to the
|
<title>Conclusion</title>
|
||||||
JavaDocs for <classname>PortResolverImpl</classname> for further
|
</info>
|
||||||
details.</para>
|
<para>Once configured, using the channel security filter is very easy. Simply request pages
|
||||||
|
without regard to the protocol (ie HTTP or HTTPS) or port (eg 80, 8080, 443, 8443 etc).
|
||||||
<para>You should note that using a secure channel is recommended if
|
Obviously you'll still need a way of making the initial request (probably via the
|
||||||
usernames and passwords are to be kept secure during the login
|
<literal>web.xml</literal>
|
||||||
process. If you do decide to use
|
<literal><welcome-file></literal> or a well-known home page URL), but once this is
|
||||||
<classname>ChannelProcessingFilter</classname> with form-based login,
|
done the filter will perform redirects as defined by your application context.</para>
|
||||||
please ensure that your login page is set to
|
<para>You can also add your own <literal>ChannelProcessor</literal> implementations to the
|
||||||
<literal>REQUIRES_SECURE_CHANNEL</literal>, and that the
|
<literal>ChannelDecisionManagerImpl</literal>. For example, you might set a
|
||||||
<literal>LoginUrlAuthenticationEntryPoint.forceHttps</literal>
|
<literal>HttpSession</literal> attribute when a human user is detected via a "enter
|
||||||
property is <literal>true</literal>.</para>
|
the contents of this graphic" procedure. Your <literal>ChannelProcessor</literal> would
|
||||||
</section>
|
respond to say <literal>REQUIRES_HUMAN_USER</literal> configuration attributes and
|
||||||
|
redirect to an appropriate entry point to start the human user validation process if the
|
||||||
<section xml:id="channel-security-conclusion">
|
<literal>HttpSession</literal> attribute is not currently set.</para>
|
||||||
<info><title>Conclusion</title></info>
|
<para>To decide whether a security check belongs in a <literal>ChannelProcessor</literal> or
|
||||||
|
an <interfacename>AccessDecisionVoter</interfacename>, remember that the former is
|
||||||
<para>Once configured, using the channel security filter is very easy.
|
designed to handle unauthenticated requests, whilst the latter is designed to handle
|
||||||
Simply request pages without regard to the protocol (ie HTTP or HTTPS)
|
authenticated requests. The latter therefore has access to the granted authorities of
|
||||||
or port (eg 80, 8080, 443, 8443 etc). Obviously you'll still need a
|
the authenticated principal. In addition, problems detected by a
|
||||||
way of making the initial request (probably via the
|
<literal>ChannelProcessor</literal> will generally cause an HTTP/HTTPS redirection
|
||||||
<literal>web.xml</literal> <literal><welcome-file></literal> or
|
so its requirements can be met, whilst problems detected by an
|
||||||
a well-known home page URL), but once this is done the filter will
|
<interfacename>AccessDecisionVoter</interfacename> will ultimately result in an
|
||||||
perform redirects as defined by your application context.</para>
|
<literal>AccessDeniedException</literal> (depending on the governing
|
||||||
|
<interfacename>AccessDecisionManager</interfacename>).</para>
|
||||||
<para>You can also add your own <literal>ChannelProcessor</literal>
|
</section>
|
||||||
implementations to the <literal>ChannelDecisionManagerImpl</literal>.
|
</chapter>
|
||||||
For example, you might set a <literal>HttpSession</literal> attribute
|
|
||||||
when a human user is detected via a "enter the contents of this
|
|
||||||
graphic" procedure. Your <literal>ChannelProcessor</literal> would
|
|
||||||
respond to say <literal>REQUIRES_HUMAN_USER</literal> configuration
|
|
||||||
attributes and redirect to an appropriate entry point to start the
|
|
||||||
human user validation process if the <literal>HttpSession</literal>
|
|
||||||
attribute is not currently set.</para>
|
|
||||||
|
|
||||||
<para>To decide whether a security check belongs in a
|
|
||||||
<literal>ChannelProcessor</literal> or an
|
|
||||||
<interfacename>AccessDecisionVoter</interfacename>, remember that the former is
|
|
||||||
designed to handle unauthenticated requests, whilst the latter is
|
|
||||||
designed to handle authenticated requests. The latter therefore has
|
|
||||||
access to the granted authorities of the authenticated principal. In
|
|
||||||
addition, problems detected by a <literal>ChannelProcessor</literal>
|
|
||||||
will generally cause an HTTP/HTTPS redirection so its requirements can
|
|
||||||
be met, whilst problems detected by an
|
|
||||||
<interfacename>AccessDecisionVoter</interfacename> will ultimately result in an
|
|
||||||
<literal>AccessDeniedException</literal> (depending on the governing
|
|
||||||
<interfacename>AccessDecisionManager</interfacename>).</para>
|
|
||||||
</section>
|
|
||||||
</chapter>
|
|
||||||
|
|
|
@ -1,36 +1,32 @@
|
||||||
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="secure-object-impls" xmlns:xlink="http://www.w3.org/1999/xlink">
|
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="secure-object-impls"
|
||||||
<info><title>Secure Object Implementations</title></info>
|
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<info>
|
||||||
|
<title>Secure Object Implementations</title>
|
||||||
|
</info>
|
||||||
<section xml:id="aop-alliance">
|
<section xml:id="aop-alliance">
|
||||||
<info>
|
<info>
|
||||||
<title>AOP Alliance (MethodInvocation) Security Interceptor</title>
|
<title>AOP Alliance (MethodInvocation) Security Interceptor</title>
|
||||||
</info>
|
</info>
|
||||||
|
<para> Prior to Spring Security 2.0, securing <classname>MethodInvocation</classname>s needed
|
||||||
<para>
|
quite a lot of boiler plate configuration. Now the recommended approach for method security is
|
||||||
Prior to Spring Security 2.0, securing <classname>MethodInvocation</classname>s needed quite a
|
to use <link xlink:href="#ns-method-security">namespace configuration</link>. This way the
|
||||||
lot of boiler plate configuration. Now the recommended approach for method security
|
method security infrastructure beans are configured automatically for you so you don't really
|
||||||
is to use <link xlink:href="#ns-method-security">namespace configuration</link>.
|
need to know about the implementation classes. We'll just provide a quick overview of the
|
||||||
This way the method security infrastructure beans are configured automatically for you so you don't really need to
|
classes that are involved here. </para>
|
||||||
know about the implementation classes. We'll just provide a quick overview of the classes that are involved here.
|
<para> Method security in enforced using a <classname>MethodSecurityInterceptor</classname>,
|
||||||
</para>
|
which secures <classname>MethodInvocation</classname>s. Depending on the configuration
|
||||||
|
approach, an interceptor may be specific to a single bean or shared between multiple beans.
|
||||||
<para>
|
The interceptor uses a <interfacename>MethodDefinitionSource</interfacename> instance to
|
||||||
Method security in enforced using a <classname>MethodSecurityInterceptor</classname>, which secures
|
obtain the configuration attributes that apply to a particular method invocation.
|
||||||
<classname>MethodInvocation</classname>s. Depending on the configuration approach, an interceptor may be specific to a single
|
<classname>MapBasedMethodDefinitionSource</classname> is used to store configuration
|
||||||
bean or shared between multiple beans. The interceptor uses a <interfacename>MethodDefinitionSource</interfacename>
|
attributes keyed by method names (which can be wildcarded) and will be used internally when
|
||||||
instance to obtain the configuration attributes that apply to a particular method invocation.
|
the attributes are defined in the application context using the
|
||||||
<classname>MapBasedMethodDefinitionSource</classname> is used to store configuration attributes keyed by method names
|
<literal><intercept-methods></literal> or <literal><protect-point></literal>
|
||||||
(which can be wildcarded) and will be used internally when the attributes are defined in the application context using
|
elements. Other implementations will be used to handle annotation-based configuration. </para>
|
||||||
the <literal><intercept-methods></literal> or <literal><protect-point></literal> elements. Other implementations
|
|
||||||
will be used to handle annotation-based configuration.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<title>Explicit MethodSecurityIterceptor Configuration</title>
|
<title>Explicit MethodSecurityIterceptor Configuration</title>
|
||||||
<para>
|
<para> You can of course configure a <classname>MethodSecurityIterceptor</classname> directly
|
||||||
You can of course configure a <classname>MethodSecurityIterceptor</classname> directly in your application context
|
in your application context for use with one of Spring AOP's proxying mechanisms: <programlisting><![CDATA[
|
||||||
for use with one of Spring AOP's proxying mechanisms:
|
|
||||||
<programlisting><![CDATA[
|
|
||||||
<bean id="bankManagerSecurity"
|
<bean id="bankManagerSecurity"
|
||||||
class="org.springframework.security.intercept.aopalliance.MethodSecurityInterceptor">
|
class="org.springframework.security.intercept.aopalliance.MethodSecurityInterceptor">
|
||||||
<property name="authenticationManager" ref="authenticationManager"/>
|
<property name="authenticationManager" ref="authenticationManager"/>
|
||||||
|
@ -43,37 +39,26 @@
|
||||||
</value>
|
</value>
|
||||||
</property>
|
</property>
|
||||||
</bean> ]]>
|
</bean> ]]>
|
||||||
</programlisting>
|
</programlisting></para>
|
||||||
</para>
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section xml:id="aspectj">
|
<section xml:id="aspectj">
|
||||||
<info>
|
<info>
|
||||||
<title>AspectJ (JoinPoint) Security Interceptor</title>
|
<title>AspectJ (JoinPoint) Security Interceptor</title>
|
||||||
</info>
|
</info>
|
||||||
|
<para>The AspectJ security interceptor is very similar to the AOP Alliance security interceptor
|
||||||
<para>The AspectJ security interceptor is very similar to the AOP
|
discussed in the previous section. Indeed we will only discuss the differences in this
|
||||||
Alliance security interceptor discussed in the previous section.
|
section.</para>
|
||||||
Indeed we will only discuss the differences in this section.</para>
|
<para>The AspectJ interceptor is named <literal>AspectJSecurityInterceptor</literal>. Unlike the
|
||||||
|
AOP Alliance security interceptor, which relies on the Spring application context to weave in
|
||||||
<para>The AspectJ interceptor is named
|
the security interceptor via proxying, the <literal>AspectJSecurityInterceptor</literal> is
|
||||||
<literal>AspectJSecurityInterceptor</literal>. Unlike the AOP Alliance
|
weaved in via the AspectJ compiler. It would not be uncommon to use both types of security
|
||||||
security interceptor, which relies on the Spring application context
|
interceptors in the same application, with <literal>AspectJSecurityInterceptor</literal> being
|
||||||
to weave in the security interceptor via proxying, the
|
used for domain object instance security and the AOP Alliance
|
||||||
<literal>AspectJSecurityInterceptor</literal> is weaved in via the
|
<classname>MethodSecurityInterceptor</classname> being used for services layer
|
||||||
AspectJ compiler. It would not be uncommon to use both types of
|
security.</para>
|
||||||
security interceptors in the same application, with
|
<para>Let's first consider how the <literal>AspectJSecurityInterceptor</literal> is configured
|
||||||
<literal>AspectJSecurityInterceptor</literal> being used for domain
|
in the Spring application context:</para>
|
||||||
object instance security and the AOP Alliance
|
|
||||||
<classname>MethodSecurityInterceptor</classname> being used for services
|
|
||||||
layer security.</para>
|
|
||||||
|
|
||||||
<para>Let's first consider how the
|
|
||||||
<literal>AspectJSecurityInterceptor</literal> is configured in the
|
|
||||||
Spring application context:</para>
|
|
||||||
|
|
||||||
<programlisting><![CDATA[
|
<programlisting><![CDATA[
|
||||||
<bean id="bankManagerSecurity"
|
<bean id="bankManagerSecurity"
|
||||||
class="org.springframework.security.intercept.aspectj.AspectJSecurityInterceptor">
|
class="org.springframework.security.intercept.aspectj.AspectJSecurityInterceptor">
|
||||||
|
@ -87,23 +72,18 @@
|
||||||
</value>
|
</value>
|
||||||
</property>
|
</property>
|
||||||
</bean>]]> </programlisting>
|
</bean>]]> </programlisting>
|
||||||
|
|
||||||
<para>As you can see, aside from the class name, the
|
<para>As you can see, aside from the class name, the
|
||||||
<literal>AspectJSecurityInterceptor</literal> is exactly the same as
|
<literal>AspectJSecurityInterceptor</literal> is exactly the same as the AOP Alliance
|
||||||
the AOP Alliance security interceptor. Indeed the two interceptors can
|
security interceptor. Indeed the two interceptors can share the same
|
||||||
share the same <literal>securityMetadataSource</literal>, as the
|
<literal>securityMetadataSource</literal>, as the
|
||||||
<interfacename>SecurityMetadataSource</interfacename> works with
|
<interfacename>SecurityMetadataSource</interfacename> works with
|
||||||
<literal>java.lang.reflect.Method</literal>s rather than an AOP
|
<literal>java.lang.reflect.Method</literal>s rather than an AOP library-specific class. Of
|
||||||
library-specific class. Of course, your access decisions have access
|
course, your access decisions have access to the relevant AOP library-specific invocation (ie
|
||||||
to the relevant AOP library-specific invocation (ie
|
<classname>MethodInvocation</classname> or <literal>JoinPoint</literal>) and as such can
|
||||||
<classname>MethodInvocation</classname> or <literal>JoinPoint</literal>)
|
consider a range of addition criteria when making access decisions (such as method
|
||||||
and as such can consider a range of addition criteria when making
|
arguments).</para>
|
||||||
access decisions (such as method arguments).</para>
|
<para>Next you'll need to define an AspectJ <literal>aspect</literal>. For example:</para>
|
||||||
|
<programlisting language="java">
|
||||||
<para>Next you'll need to define an AspectJ <literal>aspect</literal>.
|
|
||||||
For example:</para>
|
|
||||||
|
|
||||||
<programlisting>
|
|
||||||
package org.springframework.security.samples.aspectj;
|
package org.springframework.security.samples.aspectj;
|
||||||
|
|
||||||
import org.springframework.security.intercept.aspectj.AspectJSecurityInterceptor;
|
import org.springframework.security.intercept.aspectj.AspectJSecurityInterceptor;
|
||||||
|
@ -144,22 +124,16 @@ public void afterPropertiesSet() throws Exception {
|
||||||
throw new IllegalArgumentException("securityInterceptor required");
|
throw new IllegalArgumentException("securityInterceptor required");
|
||||||
}
|
}
|
||||||
}</programlisting>
|
}</programlisting>
|
||||||
|
<para>In the above example, the security interceptor will be applied to every instance of
|
||||||
<para>In the above example, the security interceptor will be applied
|
<literal>PersistableEntity</literal>, which is an abstract class not shown (you can use any
|
||||||
to every instance of <literal>PersistableEntity</literal>, which is an
|
other class or <literal>pointcut</literal> expression you like). For those curious,
|
||||||
abstract class not shown (you can use any other class or
|
<literal>AspectJCallback</literal> is needed because the <literal>proceed();</literal>
|
||||||
<literal>pointcut</literal> expression you like). For those curious,
|
statement has special meaning only within an <literal>around()</literal> body. The
|
||||||
<literal>AspectJCallback</literal> is needed because the
|
<literal>AspectJSecurityInterceptor</literal> calls this anonymous
|
||||||
<literal>proceed();</literal> statement has special meaning only
|
<literal>AspectJCallback</literal> class when it wants the target object to continue.</para>
|
||||||
within an <literal>around()</literal> body. The
|
<para>You will need to configure Spring to load the aspect and wire it with the
|
||||||
<literal>AspectJSecurityInterceptor</literal> calls this anonymous
|
<literal>AspectJSecurityInterceptor</literal>. A bean declaration which achieves this is
|
||||||
<literal>AspectJCallback</literal> class when it wants the target
|
shown below:</para>
|
||||||
object to continue.</para>
|
|
||||||
|
|
||||||
<para>You will need to configure Spring to load the aspect and wire it
|
|
||||||
with the <literal>AspectJSecurityInterceptor</literal>. A bean
|
|
||||||
declaration which achieves this is shown below:</para>
|
|
||||||
|
|
||||||
<programlisting><![CDATA[
|
<programlisting><![CDATA[
|
||||||
<bean id="domainObjectInstanceSecurityAspect"
|
<bean id="domainObjectInstanceSecurityAspect"
|
||||||
class="org.springframework.security.samples.aspectj.DomainObjectInstanceSecurityAspect"
|
class="org.springframework.security.samples.aspectj.DomainObjectInstanceSecurityAspect"
|
||||||
|
@ -167,23 +141,18 @@ public void afterPropertiesSet() throws Exception {
|
||||||
<property name="securityInterceptor" ref="aspectJSecurityInterceptor"/>
|
<property name="securityInterceptor" ref="aspectJSecurityInterceptor"/>
|
||||||
</bean>]]>
|
</bean>]]>
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
<para>That's it! Now you can create your beans from anywhere within your application, using
|
||||||
<para>That's it! Now you can create your beans from anywhere within
|
whatever means you think fit (eg <literal>new Person();</literal>) and they will have the
|
||||||
your application, using whatever means you think fit (eg <literal>new
|
security interceptor applied.</para>
|
||||||
Person();</literal>) and they will have the security interceptor
|
|
||||||
applied.</para>
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section xml:id="filter-invocation-authorization">
|
<section xml:id="filter-invocation-authorization">
|
||||||
<info><title>FilterInvocation Security Interceptor</title></info>
|
<info>
|
||||||
|
<title>FilterInvocation Security Interceptor</title>
|
||||||
<para>To secure <classname>FilterInvocation</classname>s, developers need
|
</info>
|
||||||
to add a <classname>FilterSecurityInterceptor</classname> to their filter chain.
|
<para>To secure <classname>FilterInvocation</classname>s, developers need to add a
|
||||||
A typical configuration example is provided below:</para>
|
<classname>FilterSecurityInterceptor</classname> to their filter chain. A typical
|
||||||
|
configuration example is provided below:</para>
|
||||||
<para>In the application context you will need to configure three
|
<para>In the application context you will need to configure three beans:</para>
|
||||||
beans:</para>
|
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
<bean id="exceptionTranslationFilter"
|
<bean id="exceptionTranslationFilter"
|
||||||
|
@ -202,93 +171,69 @@ public void afterPropertiesSet() throws Exception {
|
||||||
<property name="authenticationManager" ref="authenticationManager"/>
|
<property name="authenticationManager" ref="authenticationManager"/>
|
||||||
<property name="accessDecisionManager" ref="accessDecisionManager"/>
|
<property name="accessDecisionManager" ref="accessDecisionManager"/>
|
||||||
<property name="securityMetadataSource">
|
<property name="securityMetadataSource">
|
||||||
<security:filter-invocation-definition-source>
|
<security:filter-security-metadata-source>
|
||||||
<security:intercept-url pattern="/secure/super/**" access="ROLE_WE_DONT_HAVE"/>
|
<security:intercept-url pattern="/secure/super/**" access="ROLE_WE_DONT_HAVE"/>
|
||||||
<security:intercept-url pattern="/secure/**" access="ROLE_SUPERVISOR,ROLE_TELLER"/>
|
<security:intercept-url pattern="/secure/**" access="ROLE_SUPERVISOR,ROLE_TELLER"/>
|
||||||
</security:filter-invocation-definition-source>
|
</security:filter-security-metadata-source>
|
||||||
</property>
|
</property>
|
||||||
</bean>]]> </programlisting>
|
</bean>]]> </programlisting>
|
||||||
|
<para>The <classname>ExceptionTranslationFilter</classname> provides the bridge between Java
|
||||||
<para>The <classname>ExceptionTranslationFilter</classname> provides
|
exceptions and HTTP responses. It is solely concerned with maintaining the user interface.
|
||||||
the bridge between Java exceptions and HTTP responses. It is solely
|
This filter does not do any actual security enforcement. If an
|
||||||
concerned with maintaining the user interface. This filter does not do
|
<exceptionname>AuthenticationException</exceptionname> is detected, the filter will call the
|
||||||
any actual security enforcement. If an
|
AuthenticationEntryPoint to commence the authentication process (e.g. a user login).</para>
|
||||||
<exceptionname>AuthenticationException</exceptionname> is detected,
|
<para>The <interfacename>AuthenticationEntryPoint</interfacename> will be called if the user
|
||||||
the filter will call the AuthenticationEntryPoint to commence the
|
requests a secure HTTP resource but they are not authenticated. The class handles presenting
|
||||||
authentication process (e.g. a user login).</para>
|
the appropriate response to the user so that authentication can begin. Three concrete
|
||||||
|
implementations are provided with Spring Security:
|
||||||
<para>The <interfacename>AuthenticationEntryPoint</interfacename> will be called
|
<classname>LoginUrlAuthenticationEntryPoint</classname> for commencing a form-based
|
||||||
if the user requests a secure HTTP resource but they are not
|
authentication, <literal>BasicProcessingFilterEntryPoint</literal> for commencing a HTTP Basic
|
||||||
authenticated. The class handles presenting the appropriate response
|
authentication process, and <literal>CasProcessingFilterEntryPoint</literal> for commencing a
|
||||||
to the user so that authentication can begin. Three concrete
|
JA-SIG Central Authentication Service (CAS) login. The
|
||||||
implementations are provided with Spring Security:
|
<classname>LoginUrlAuthenticationEntryPoint</classname> and
|
||||||
<classname>LoginUrlAuthenticationEntryPoint</classname> for
|
<literal>CasProcessingFilterEntryPoint</literal> have optional properties related to forcing
|
||||||
commencing a form-based authentication,
|
the use of HTTPS, so please refer to the JavaDocs if you require this.</para>
|
||||||
<literal>BasicProcessingFilterEntryPoint</literal> for commencing a
|
<para><classname>FilterSecurityInterceptor</classname> is responsible for handling the security
|
||||||
HTTP Basic authentication process, and
|
of HTTP resources. Like any other security interceptor, it requires a reference to an
|
||||||
<literal>CasProcessingFilterEntryPoint</literal> for commencing a
|
<interfacename>AuthenticationManager</interfacename> and an
|
||||||
JA-SIG Central Authentication Service (CAS) login. The
|
<interfacename>AccessDecisionManager</interfacename>, which are both discussed in separate
|
||||||
<classname>LoginUrlAuthenticationEntryPoint</classname> and
|
sections below. The <classname>FilterSecurityInterceptor</classname> is also configured with
|
||||||
<literal>CasProcessingFilterEntryPoint</literal> have optional
|
configuration attributes that apply to different HTTP URL requests. A full discussion of
|
||||||
properties related to forcing the use of HTTPS, so please refer to the
|
configuration attributes is provided in the High Level Design section of this document.</para>
|
||||||
JavaDocs if you require this.</para>
|
<para>The <classname>FilterSecurityInterceptor</classname> can be configured with configuration
|
||||||
|
attributes in two ways. The first, which is shown above, is using the
|
||||||
<para><classname>FilterSecurityInterceptor</classname> is responsible for
|
<literal><filter-security-metadata-source></literal> namespace element. This is
|
||||||
handling the security of HTTP resources. Like any other security
|
similar to the <literal><filter-chain-map></literal> used to configure a
|
||||||
interceptor, it requires a reference to an
|
<classname>FilterChainProxy</classname> but the <literal><intercept-url></literal>
|
||||||
<interfacename>AuthenticationManager</interfacename> and an
|
child elements only use the <literal>pattern</literal> and <literal>access</literal>
|
||||||
<interfacename>AccessDecisionManager</interfacename>, which are both discussed in
|
attributes. The second is by writing your own
|
||||||
separate sections below. The
|
<interfacename>SecurityMetadataSource</interfacename>, although this is beyond the scope of
|
||||||
<classname>FilterSecurityInterceptor</classname> is also configured with
|
this document. Irrespective of the approach used, the
|
||||||
configuration attributes that apply to different HTTP URL requests. A
|
<interfacename>SecurityMetadataSource</interfacename> is responsible for returning a
|
||||||
full discussion of configuration attributes is provided in the High
|
<literal>List<ConfigAttribute></literal> containing all of the configuration
|
||||||
Level Design section of this document.</para>
|
attributes associated with a single secure HTTP URL.</para>
|
||||||
|
|
||||||
<para>The <classname>FilterSecurityInterceptor</classname> can be
|
|
||||||
configured with configuration attributes in two ways. The first,
|
|
||||||
which is shown above, is using the <literal><filter-invocation-definition-source></literal>
|
|
||||||
namespace element. This is similar to the <literal><filter-chain-map></literal>
|
|
||||||
used to configure a <classname>FilterChainProxy</classname> but the <literal><intercept-url></literal>
|
|
||||||
child elements only use the <literal>pattern</literal> and <literal>access</literal> attributes.
|
|
||||||
The second is by writing your own
|
|
||||||
<interfacename>SecurityMetadataSource</interfacename>, although this is beyond the
|
|
||||||
scope of this document. Irrespective of the approach used, the
|
|
||||||
<interfacename>SecurityMetadataSource</interfacename> is responsible for returning
|
|
||||||
a <literal>List<ConfigAttribute></literal> containing
|
|
||||||
all of the configuration attributes associated with a single secure
|
|
||||||
HTTP URL.</para>
|
|
||||||
|
|
||||||
<para>It should be noted that the
|
<para>It should be noted that the
|
||||||
<literal>FilterSecurityInterceptor.setSecurityMetadataSource()</literal>
|
<literal>FilterSecurityInterceptor.setSecurityMetadataSource()</literal> method actually
|
||||||
method actually expects an instance of
|
expects an instance of <interfacename>FilterInvocationDefinitionSource</interfacename>. This
|
||||||
<interfacename>FilterInvocationDefinitionSource</interfacename>. This is a marker
|
is a marker interface which subclasses <interfacename>SecurityMetadataSource</interfacename>.
|
||||||
interface which subclasses <interfacename>SecurityMetadataSource</interfacename>.
|
It simply denotes the <interfacename>SecurityMetadataSource</interfacename> understands
|
||||||
It simply denotes the <interfacename>SecurityMetadataSource</interfacename>
|
<classname>FilterInvocation</classname>s. In the interests of simplicity we'll continue to
|
||||||
understands <classname>FilterInvocation</classname>s. In the interests of
|
refer to the <interfacename>FilterInvocationDefinitionSource</interfacename> as an
|
||||||
simplicity we'll continue to refer to the
|
<interfacename>SecurityMetadataSource</interfacename>, as the distinction is of little
|
||||||
<interfacename>FilterInvocationDefinitionSource</interfacename> as an
|
relevance to most users of the <classname>FilterSecurityInterceptor</classname>.</para>
|
||||||
<interfacename>SecurityMetadataSource</interfacename>, as the distinction is of
|
<para>When using the namespace option to configure the interceptor, commas are used to delimit
|
||||||
little relevance to most users of the
|
the different configuration attributes that apply to each HTTP URL. Each configuration
|
||||||
<classname>FilterSecurityInterceptor</classname>.</para>
|
attribute is assigned into its own <literal>SecurityConfig</literal> object. The
|
||||||
|
<literal>SecurityConfig</literal> object is discussed in the High Level Design section. The
|
||||||
<para>When using the namespace option to configure the interceptor,
|
<interfacename>SecurityMetadataSource</interfacename> created by the property editor,
|
||||||
commas are used to delimit the different configuration
|
<interfacename>FilterInvocationDefinitionSource</interfacename>, matches configuration
|
||||||
attributes that apply to each HTTP URL. Each configuration attribute
|
attributes against <literal>FilterInvocations</literal> based on expression evaluation of the
|
||||||
is assigned into its own <literal>SecurityConfig</literal> object. The
|
request URL. Two standard expression syntaxes are supported. The default is to treat all
|
||||||
<literal>SecurityConfig</literal> object is discussed in the High
|
expressions as Apache Ant paths and regular expressions are also supported for ore complex
|
||||||
Level Design section. The <interfacename>SecurityMetadataSource</interfacename>
|
cases. The <literal>path-type</literal> attribute is used to specify the type of pattern being
|
||||||
created by the property editor,
|
used. It is not possible to mix expression syntaxes within the same definition. For example,
|
||||||
<interfacename>FilterInvocationDefinitionSource</interfacename>, matches
|
the previous configuration using regular expressions instead of Ant paths would be written as
|
||||||
configuration attributes against <literal>FilterInvocations</literal>
|
follows:</para>
|
||||||
based on expression evaluation of the request URL. Two standard
|
|
||||||
expression syntaxes are supported. The default is to treat all
|
|
||||||
expressions as Apache Ant paths and regular expressions are also supported
|
|
||||||
for ore complex cases. The <literal>path-type</literal> attribute is used
|
|
||||||
to specify the type of pattern being used. It is not possible to
|
|
||||||
mix expression syntaxes within the same definition. For example, the
|
|
||||||
previous configuration using regular expressions instead of Ant paths would be
|
|
||||||
written as follows:</para>
|
|
||||||
|
|
||||||
<programlisting><![CDATA[
|
<programlisting><![CDATA[
|
||||||
<bean id="filterInvocationInterceptor"
|
<bean id="filterInvocationInterceptor"
|
||||||
class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
|
class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
|
||||||
|
@ -296,32 +241,25 @@ public void afterPropertiesSet() throws Exception {
|
||||||
<property name="accessDecisionManager" ref="accessDecisionManager"/>
|
<property name="accessDecisionManager" ref="accessDecisionManager"/>
|
||||||
<property name="runAsManager" ref="runAsManager"/>
|
<property name="runAsManager" ref="runAsManager"/>
|
||||||
<property name="securityMetadataSource">
|
<property name="securityMetadataSource">
|
||||||
<security:filter-invocation-definition-source path-type="regex">
|
<security:filter-security-metadata-source path-type="regex">
|
||||||
<security:intercept-url pattern="\A/secure/super/.*\Z" access="ROLE_WE_DONT_HAVE"/>
|
<security:intercept-url pattern="\A/secure/super/.*\Z" access="ROLE_WE_DONT_HAVE"/>
|
||||||
<security:intercept-url pattern="\A/secure/.*\" access="ROLE_SUPERVISOR,ROLE_TELLER"/>
|
<security:intercept-url pattern="\A/secure/.*\" access="ROLE_SUPERVISOR,ROLE_TELLER"/>
|
||||||
</security:filter-invocation-definition-source>
|
</security:filter-security-metadata-source>
|
||||||
</property>
|
</property>
|
||||||
</bean>]]> </programlisting>
|
</bean>]]> </programlisting>
|
||||||
|
<para>Irrespective of the type of expression syntax used, expressions are always evaluated in
|
||||||
<para>Irrespective of the type of expression syntax used, expressions
|
the order they are defined. Thus it is important that more specific expressions are defined
|
||||||
are always evaluated in the order they are defined. Thus it is
|
higher in the list than less specific expressions. This is reflected in our example above,
|
||||||
important that more specific expressions are defined higher in the
|
where the more specific <literal>/secure/super/</literal> pattern appears higher than the less
|
||||||
list than less specific expressions. This is reflected in our example
|
specific <literal>/secure/</literal> pattern. If they were reversed, the
|
||||||
above, where the more specific <literal>/secure/super/</literal>
|
<literal>/secure/</literal> pattern would always match and the
|
||||||
pattern appears higher than the less specific
|
<literal>/secure/super/</literal> pattern would never be evaluated.</para>
|
||||||
<literal>/secure/</literal> pattern. If they were reversed, the
|
<para>As with other security interceptors, the <literal>validateConfigAttributes</literal>
|
||||||
<literal>/secure/</literal> pattern would always match and the
|
property is observed. When set to <literal>true</literal> (the default), at startup time the
|
||||||
<literal>/secure/super/</literal> pattern would never be
|
<classname>FilterSecurityInterceptor</classname> will evaluate if the provided configuration
|
||||||
evaluated.</para>
|
attributes are valid. It does this by checking each configuration attribute can be processed
|
||||||
|
by either the <interfacename>AccessDecisionManager</interfacename> or the
|
||||||
<para>As with other security interceptors, the
|
<literal>RunAsManager</literal>. If neither of these can process a given configuration
|
||||||
<literal>validateConfigAttributes</literal> property is observed. When
|
attribute, an exception is thrown.</para>
|
||||||
set to <literal>true</literal> (the default), at startup time the
|
|
||||||
<classname>FilterSecurityInterceptor</classname> will evaluate if the
|
|
||||||
provided configuration attributes are valid. It does this by checking
|
|
||||||
each configuration attribute can be processed by either the
|
|
||||||
<interfacename>AccessDecisionManager</interfacename> or the
|
|
||||||
<literal>RunAsManager</literal>. If neither of these can process a
|
|
||||||
given configuration attribute, an exception is thrown.</para>
|
|
||||||
</section>
|
</section>
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
|
@ -92,11 +92,11 @@
|
||||||
<property name="authenticationManager" ref="authenticationManager"/>
|
<property name="authenticationManager" ref="authenticationManager"/>
|
||||||
<property name="accessDecisionManager" ref="accessDecisionManager"/>
|
<property name="accessDecisionManager" ref="accessDecisionManager"/>
|
||||||
<property name="securityMetadataSource">
|
<property name="securityMetadataSource">
|
||||||
<sec:filter-invocation-definition-source>
|
<sec:filter-security-metadata-source>
|
||||||
<sec:intercept-url pattern="/secure/extreme/**" access="ROLE_2"/>
|
<sec:intercept-url pattern="/secure/extreme/**" access="ROLE_2"/>
|
||||||
<sec:intercept-url pattern="/secure/**" access="ROLE_1"/>
|
<sec:intercept-url pattern="/secure/**" access="ROLE_1"/>
|
||||||
<sec:intercept-url pattern="/**" access="ROLE_0"/>
|
<sec:intercept-url pattern="/**" access="ROLE_0"/>
|
||||||
</sec:filter-invocation-definition-source>
|
</sec:filter-security-metadata-source>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
|
|
@ -51,15 +51,15 @@ public class ChannelProcessingFilter extends SpringSecurityFilter implements Ini
|
||||||
//~ Instance fields ================================================================================================
|
//~ Instance fields ================================================================================================
|
||||||
|
|
||||||
private ChannelDecisionManager channelDecisionManager;
|
private ChannelDecisionManager channelDecisionManager;
|
||||||
private FilterInvocationSecurityMetadataSource filterInvocationSecurityMetadataSource;
|
private FilterInvocationSecurityMetadataSource securityMetadataSource;
|
||||||
|
|
||||||
//~ Methods ========================================================================================================
|
//~ Methods ========================================================================================================
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
Assert.notNull(filterInvocationSecurityMetadataSource, "filterInvocationSecurityMetadataSource must be specified");
|
Assert.notNull(securityMetadataSource, "securityMetadataSource must be specified");
|
||||||
Assert.notNull(channelDecisionManager, "channelDecisionManager must be specified");
|
Assert.notNull(channelDecisionManager, "channelDecisionManager must be specified");
|
||||||
|
|
||||||
Collection<ConfigAttribute> attrDefs = this.filterInvocationSecurityMetadataSource.getAllConfigAttributes();
|
Collection<ConfigAttribute> attrDefs = this.securityMetadataSource.getAllConfigAttributes();
|
||||||
|
|
||||||
if (attrDefs == null) {
|
if (attrDefs == null) {
|
||||||
if (logger.isWarnEnabled()) {
|
if (logger.isWarnEnabled()) {
|
||||||
|
@ -91,7 +91,7 @@ public class ChannelProcessingFilter extends SpringSecurityFilter implements Ini
|
||||||
throws IOException, ServletException {
|
throws IOException, ServletException {
|
||||||
|
|
||||||
FilterInvocation fi = new FilterInvocation(request, response, chain);
|
FilterInvocation fi = new FilterInvocation(request, response, chain);
|
||||||
List<ConfigAttribute> attr = this.filterInvocationSecurityMetadataSource.getAttributes(fi);
|
List<ConfigAttribute> attr = this.securityMetadataSource.getAttributes(fi);
|
||||||
|
|
||||||
if (attr != null) {
|
if (attr != null) {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
|
@ -112,16 +112,16 @@ public class ChannelProcessingFilter extends SpringSecurityFilter implements Ini
|
||||||
return channelDecisionManager;
|
return channelDecisionManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FilterInvocationSecurityMetadataSource getFilterInvocationSecurityMetadataSource() {
|
public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {
|
||||||
return filterInvocationSecurityMetadataSource;
|
return securityMetadataSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setChannelDecisionManager(ChannelDecisionManager channelDecisionManager) {
|
public void setChannelDecisionManager(ChannelDecisionManager channelDecisionManager) {
|
||||||
this.channelDecisionManager = channelDecisionManager;
|
this.channelDecisionManager = channelDecisionManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFilterInvocationSecurityMetadataSource(FilterInvocationSecurityMetadataSource filterInvocationSecurityMetadataSource) {
|
public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource filterInvocationSecurityMetadataSource) {
|
||||||
this.filterInvocationSecurityMetadataSource = filterInvocationSecurityMetadataSource;
|
this.securityMetadataSource = filterInvocationSecurityMetadataSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getOrder() {
|
public int getOrder() {
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
package org.springframework.security.web.access.channel;
|
package org.springframework.security.web.access.channel;
|
||||||
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.*;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -31,8 +31,6 @@ import org.springframework.mock.web.MockHttpServletResponse;
|
||||||
import org.springframework.security.access.ConfigAttribute;
|
import org.springframework.security.access.ConfigAttribute;
|
||||||
import org.springframework.security.access.SecurityConfig;
|
import org.springframework.security.access.SecurityConfig;
|
||||||
import org.springframework.security.web.FilterInvocation;
|
import org.springframework.security.web.FilterInvocation;
|
||||||
import org.springframework.security.web.access.channel.ChannelDecisionManager;
|
|
||||||
import org.springframework.security.web.access.channel.ChannelProcessingFilter;
|
|
||||||
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
|
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
|
||||||
|
|
||||||
|
|
||||||
|
@ -50,7 +48,7 @@ public class ChannelProcessingFilterTests {
|
||||||
ChannelProcessingFilter filter = new ChannelProcessingFilter();
|
ChannelProcessingFilter filter = new ChannelProcessingFilter();
|
||||||
|
|
||||||
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "MOCK");
|
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "MOCK");
|
||||||
filter.setFilterInvocationSecurityMetadataSource(fids);
|
filter.setSecurityMetadataSource(fids);
|
||||||
|
|
||||||
filter.afterPropertiesSet();
|
filter.afterPropertiesSet();
|
||||||
}
|
}
|
||||||
|
@ -69,7 +67,7 @@ public class ChannelProcessingFilterTests {
|
||||||
|
|
||||||
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "SUPPORTS_MOCK_ONLY");
|
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "SUPPORTS_MOCK_ONLY");
|
||||||
|
|
||||||
filter.setFilterInvocationSecurityMetadataSource(fids);
|
filter.setSecurityMetadataSource(fids);
|
||||||
|
|
||||||
filter.afterPropertiesSet();
|
filter.afterPropertiesSet();
|
||||||
}
|
}
|
||||||
|
@ -81,7 +79,7 @@ public class ChannelProcessingFilterTests {
|
||||||
|
|
||||||
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "SUPPORTS_MOCK_ONLY", "INVALID_ATTRIBUTE");
|
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "SUPPORTS_MOCK_ONLY", "INVALID_ATTRIBUTE");
|
||||||
|
|
||||||
filter.setFilterInvocationSecurityMetadataSource(fids);
|
filter.setSecurityMetadataSource(fids);
|
||||||
filter.afterPropertiesSet();
|
filter.afterPropertiesSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +90,7 @@ public class ChannelProcessingFilterTests {
|
||||||
|
|
||||||
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "SOME_ATTRIBUTE");
|
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "SOME_ATTRIBUTE");
|
||||||
|
|
||||||
filter.setFilterInvocationSecurityMetadataSource(fids);
|
filter.setSecurityMetadataSource(fids);
|
||||||
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
request.setQueryString("info=now");
|
request.setQueryString("info=now");
|
||||||
|
@ -110,7 +108,7 @@ public class ChannelProcessingFilterTests {
|
||||||
|
|
||||||
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "SOME_ATTRIBUTE");
|
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "SOME_ATTRIBUTE");
|
||||||
|
|
||||||
filter.setFilterInvocationSecurityMetadataSource(fids);
|
filter.setSecurityMetadataSource(fids);
|
||||||
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
request.setQueryString("info=now");
|
request.setQueryString("info=now");
|
||||||
|
@ -129,7 +127,7 @@ public class ChannelProcessingFilterTests {
|
||||||
|
|
||||||
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "NOT_USED");
|
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "NOT_USED");
|
||||||
|
|
||||||
filter.setFilterInvocationSecurityMetadataSource(fids);
|
filter.setSecurityMetadataSource(fids);
|
||||||
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
request.setQueryString("info=now");
|
request.setQueryString("info=now");
|
||||||
|
@ -148,8 +146,8 @@ public class ChannelProcessingFilterTests {
|
||||||
|
|
||||||
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", false, "MOCK");
|
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", false, "MOCK");
|
||||||
|
|
||||||
filter.setFilterInvocationSecurityMetadataSource(fids);
|
filter.setSecurityMetadataSource(fids);
|
||||||
assertTrue(filter.getFilterInvocationSecurityMetadataSource() != null);
|
assertSame(fids, filter.getSecurityMetadataSource());
|
||||||
|
|
||||||
filter.init(null);
|
filter.init(null);
|
||||||
filter.afterPropertiesSet();
|
filter.afterPropertiesSet();
|
||||||
|
|
Loading…
Reference in New Issue