OPEN - issue SEC-763: Allow setting of alwaysUseDirectTargetUrl via form-login namespace URL

http://jira.springframework.org/browse/SEC-763. Added always-use-default target attribute to namespace.
This commit is contained in:
Luke Taylor 2008-04-11 12:03:55 +00:00
parent 3e259b460c
commit 7145198e5a
4 changed files with 75 additions and 50 deletions

View File

@ -28,6 +28,7 @@ public class FormLoginBeanDefinitionParser implements BeanDefinitionParser {
static final String DEF_LOGIN_PAGE = DefaultLoginPageGeneratingFilter.DEFAULT_LOGIN_PAGE_URL;
static final String ATT_FORM_LOGIN_TARGET_URL = "default-target-url";
static final String ATT_ALWAYS_USE_DEFAULT_TARGET_URL = "always-use-default-target";
static final String DEF_FORM_LOGIN_TARGET_URL = "/";
static final String ATT_FORM_LOGIN_AUTHENTICATION_FAILURE_URL = "authentication-failure-url";
@ -49,6 +50,7 @@ public class FormLoginBeanDefinitionParser implements BeanDefinitionParser {
String loginUrl = null;
String defaultTargetUrl = null;
String authenticationFailureUrl = null;
String alwaysUseDefault = null;
Object source = null;
@ -56,6 +58,7 @@ public class FormLoginBeanDefinitionParser implements BeanDefinitionParser {
loginUrl = elt.getAttribute(ATT_LOGIN_URL);
defaultTargetUrl = elt.getAttribute(ATT_FORM_LOGIN_TARGET_URL);
authenticationFailureUrl = elt.getAttribute(ATT_FORM_LOGIN_AUTHENTICATION_FAILURE_URL);
alwaysUseDefault = elt.getAttribute(ATT_ALWAYS_USE_DEFAULT_TARGET_URL);
loginPage = elt.getAttribute(ATT_LOGIN_PAGE);
if (!StringUtils.hasText(loginPage)) {
loginPage = null;
@ -65,7 +68,7 @@ public class FormLoginBeanDefinitionParser implements BeanDefinitionParser {
ConfigUtils.registerProviderManagerIfNecessary(parserContext);
filterBean = createFilterBean(loginUrl, defaultTargetUrl, loginPage, authenticationFailureUrl);
filterBean = createFilterBean(loginUrl, defaultTargetUrl, alwaysUseDefault, loginPage, authenticationFailureUrl);
filterBean.setSource(source);
filterBean.getPropertyValues().addPropertyValue("authenticationManager",
@ -82,13 +85,19 @@ public class FormLoginBeanDefinitionParser implements BeanDefinitionParser {
return null;
}
private RootBeanDefinition createFilterBean(String loginUrl, String defaultTargetUrl, String loginPage, String authenticationFailureUrl) {
private RootBeanDefinition createFilterBean(String loginUrl, String defaultTargetUrl, String alwaysUseDefault,
String loginPage, String authenticationFailureUrl) {
BeanDefinitionBuilder filterBuilder = BeanDefinitionBuilder.rootBeanDefinition(filterClassName);
if (!StringUtils.hasText(loginUrl)) {
loginUrl = defaultLoginProcessingUrl;
}
if ("true".equals(alwaysUseDefault)) {
filterBuilder.addPropertyValue("alwaysUseDefaultTargetUrl", Boolean.TRUE);
}
filterBuilder.addPropertyValue("filterProcessesUrl", loginUrl);

View File

@ -262,6 +262,9 @@ form-login.attlist &=
form-login.attlist &=
## The URL that will be redirected to after successful authentication, if the user's previous action could not be resumed. This generally happens if the user visits a login page without having first requested a secured operation that triggers authentication. If unspecified, defaults to the root of the application.
attribute default-target-url {xsd:string}?
form-login.attlist &=
## Whether the user should always be redirected to the default-target-url after login.
attribute always-use-default-target {boolean}?
form-login.attlist &=
## The URL for the login page. If no login URL is specified, Spring Security will automatically create a login URL at /spring_security_login and a corresponding filter to render that login URL when requested.
attribute login-page {xsd:string}?

View File

@ -296,7 +296,46 @@
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" ref="security:password-compare"/>
<xs:element minOccurs="0" name="password-compare">
<xs:annotation>
<xs:documentation>Specifies that an LDAP provider should use an LDAP compare operation
of the user's password to authenticate the user</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="password-encoder">
<xs:annotation>
<xs:documentation>element which defines a password encoding strategy. Used by an
authentication provider to convert submitted passwords to hashed versions, for
example.</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="salt-source">
<xs:complexType>
<xs:attribute name="user-property" type="xs:string">
<xs:annotation>
<xs:documentation>A property of the UserDetails object which will be
used as salt by a password encoder. Typically something like
"username" might be used. </xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="system-wide" type="xs:string">
<xs:annotation>
<xs:documentation>A single value that will be used as the salt for a
password encoder. </xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attributeGroup ref="security:password-encoder.attlist"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attributeGroup ref="security:password-compare.attlist"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attributeGroup ref="security:ldap-ap.attlist"/>
</xs:complexType>
@ -337,46 +376,6 @@
</xs:annotation>
</xs:attribute>
</xs:attributeGroup>
<xs:element name="password-compare">
<xs:annotation>
<xs:documentation>Specifies that an LDAP provider should use an LDAP compare operation of the
user's password to authenticate the user</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="password-encoder">
<xs:annotation>
<xs:documentation>element which defines a password encoding strategy. Used by an
authentication provider to convert submitted passwords to hashed versions, for
example.</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="salt-source">
<xs:complexType>
<xs:attribute name="user-property" type="xs:string">
<xs:annotation>
<xs:documentation>A property of the UserDetails object which will be used as
salt by a password encoder. Typically something like "username" might be
used. </xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="system-wide" type="xs:string">
<xs:annotation>
<xs:documentation>A single value that will be used as the salt for a password
encoder. </xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attributeGroup ref="security:password-encoder.attlist"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attributeGroup ref="security:password-compare.attlist"/>
</xs:complexType>
</xs:element>
<xs:attributeGroup name="password-compare.attlist">
<xs:attribute name="password-attribute" type="xs:string">
<xs:annotation>
@ -805,6 +804,12 @@
application.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="always-use-default-target" type="security:boolean">
<xs:annotation>
<xs:documentation>Whether the user should always be redirected to the default-target-url
after login. </xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="login-page" type="xs:string">
<xs:annotation>
<xs:documentation>The URL for the login page. If no login URL is specified, Spring Security

View File

@ -131,12 +131,24 @@ public class HttpSecurityBeanDefinitionParserTests {
@Test
public void formLoginWithNoLoginPageAddsDefaultLoginPageFilter() throws Exception {
setContext(
" <http auto-config='true' path-type='ant' lowercase-comparisons='false'>" +
" <form-login />" +
" </http>" + AUTH_PROVIDER_XML);
"<http auto-config='true' path-type='ant' lowercase-comparisons='false'>" +
" <form-login />" +
"</http>" + AUTH_PROVIDER_XML);
// These will be matched by the default pattern "/**"
checkAutoConfigFilters(getFilters("/anything"));
}
@Test
public void formLoginAlwaysUseDefaultSetsCorrectProperty() throws Exception {
setContext(
"<http>" +
" <form-login default-target-url='/default' always-use-default-target='true' />" +
"</http>" + AUTH_PROVIDER_XML);
// These will be matched by the default pattern "/**"
AuthenticationProcessingFilter filter = (AuthenticationProcessingFilter) getFilters("/anything").get(2);
assertEquals("/default", filter.getDefaultTargetUrl());
assertEquals(Boolean.TRUE, FieldUtils.getFieldValue(filter, "alwaysUseDefaultTargetUrl"));
}
@Test
public void lowerCaseComparisonIsRespectedBySecurityFilterInvocationDefinitionSource() throws Exception {
@ -385,10 +397,6 @@ public class HttpSecurityBeanDefinitionParserTests {
getFilters.setAccessible(true);
return (List) ReflectionUtils.invokeMethod(getFilters, fcp, new Object[] {url});
}
private FilterChainProxy getFilterChainProxy() {
return (FilterChainProxy) appContext.getBean(BeanIds.FILTER_CHAIN_PROXY);
}
private FilterInvocation createFilterinvocation(String path, String method) {
MockHttpServletRequest request = new MockHttpServletRequest();