Add Forward after authentication attempt config support

Fixes gh-3728
This commit is contained in:
Shazin Sadakath
2016-03-10 22:09:12 +05:30
committed by Rob Winch
parent dbf73c4692
commit e33e21fe6b
7 changed files with 176 additions and 9 deletions

View File

@@ -19,6 +19,8 @@ import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.ForwardAuthenticationFailureHandler;
import org.springframework.security.web.authentication.ForwardAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.RememberMeServices;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
@@ -62,6 +64,7 @@ import org.springframework.security.web.util.matcher.RequestMatcher;
* </ul>
*
* @author Rob Winch
* @author Shazin Sadakath
* @since 3.2
*/
public final class FormLoginConfigurer<H extends HttpSecurityBuilder<H>>
@@ -206,6 +209,28 @@ public final class FormLoginConfigurer<H extends HttpSecurityBuilder<H>>
return this;
}
/**
* Forward Authentication Failure Handler
*
* @param forwardUrl the target URL in case of failure
* @return he {@link FormLoginConfigurer} for additional customization
*/
public FormLoginConfigurer<H> failureForwardUrl(String forwardUrl) {
failureHandler(new ForwardAuthenticationFailureHandler(forwardUrl));
return this;
}
/**
* Forward Authentication Success Handler
*
* @param forwardUrl the target URL in case of success
* @return he {@link FormLoginConfigurer} for additional customization
*/
public FormLoginConfigurer<H> successForwardUrl(String forwardUrl) {
successHandler(new ForwardAuthenticationSuccessHandler(forwardUrl));
return this;
}
@Override
public void init(H http) throws Exception {
super.init(http);

View File

@@ -22,9 +22,7 @@ import org.springframework.beans.factory.config.BeanReference;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.authentication.*;
import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
@@ -34,6 +32,7 @@ import org.w3c.dom.Element;
* @author Ben Alex
* @author Rob Winch
* @author Kazuki Shimizu
* @author Shazin Sadakath
*/
public class FormLoginBeanDefinitionParser {
protected final Log logger = LogFactory.getLog(getClass());
@@ -55,6 +54,8 @@ public class FormLoginBeanDefinitionParser {
private static final String ATT_SUCCESS_HANDLER_REF = "authentication-success-handler-ref";
private static final String ATT_FAILURE_HANDLER_REF = "authentication-failure-handler-ref";
private static final String ATT_FORM_LOGIN_AUTHENTICATION_FAILURE_FORWARD_URL = "authentication-failure-forward-url";
private static final String ATT_FORM_LOGIN_AUTHENTICATION_SUCCESS_FORWARD_URL = "authentication-success-forward-url";
private final String defaultLoginProcessingUrl;
private final String filterClassName;
@@ -95,6 +96,8 @@ public class FormLoginBeanDefinitionParser {
String usernameParameter = null;
String passwordParameter = null;
String authDetailsSourceRef = null;
String authenticationFailureForwardUrl = null;
String authenticationSuccessForwardUrl = null;
Object source = null;
@@ -113,6 +116,10 @@ public class FormLoginBeanDefinitionParser {
failureHandlerRef = elt.getAttribute(ATT_FAILURE_HANDLER_REF);
authDetailsSourceRef = elt
.getAttribute(AuthenticationConfigBuilder.ATT_AUTH_DETAILS_SOURCE_REF);
authenticationFailureForwardUrl = elt.getAttribute(ATT_FORM_LOGIN_AUTHENTICATION_FAILURE_FORWARD_URL);
WebConfigUtils.validateHttpRedirect(authenticationFailureForwardUrl, pc, source);
authenticationSuccessForwardUrl = elt.getAttribute(ATT_FORM_LOGIN_AUTHENTICATION_SUCCESS_FORWARD_URL);
WebConfigUtils.validateHttpRedirect(authenticationSuccessForwardUrl, pc, source);
if (!StringUtils.hasText(loginPage)) {
loginPage = null;
@@ -124,7 +131,7 @@ public class FormLoginBeanDefinitionParser {
filterBean = createFilterBean(loginUrl, defaultTargetUrl, alwaysUseDefault,
loginPage, authenticationFailureUrl, successHandlerRef,
failureHandlerRef, authDetailsSourceRef);
failureHandlerRef, authDetailsSourceRef, authenticationFailureForwardUrl, authenticationSuccessForwardUrl);
if (StringUtils.hasText(usernameParameter)) {
filterBean.getPropertyValues().addPropertyValue("usernameParameter",
@@ -152,7 +159,7 @@ public class FormLoginBeanDefinitionParser {
private RootBeanDefinition createFilterBean(String loginUrl, String defaultTargetUrl,
String alwaysUseDefault, String loginPage, String authenticationFailureUrl,
String successHandlerRef, String failureHandlerRef,
String authDetailsSourceRef) {
String authDetailsSourceRef, String authenticationFailureForwardUrl, String authenticationSuccessForwardUrl) {
BeanDefinitionBuilder filterBuilder = BeanDefinitionBuilder
.rootBeanDefinition(filterClassName);
@@ -176,8 +183,12 @@ public class FormLoginBeanDefinitionParser {
if (StringUtils.hasText(successHandlerRef)) {
filterBuilder.addPropertyReference("authenticationSuccessHandler",
successHandlerRef);
}
else {
} else if(StringUtils.hasText(authenticationSuccessForwardUrl)) {
BeanDefinitionBuilder forwardSuccessHandler = BeanDefinitionBuilder
.rootBeanDefinition(ForwardAuthenticationSuccessHandler.class);
forwardSuccessHandler.addConstructorArgValue(authenticationSuccessForwardUrl);
filterBuilder.addPropertyValue("authenticationSuccessHandler", forwardSuccessHandler.getBeanDefinition());
} else {
BeanDefinitionBuilder successHandler = BeanDefinitionBuilder
.rootBeanDefinition(SavedRequestAwareAuthenticationSuccessHandler.class);
if ("true".equals(alwaysUseDefault)) {
@@ -205,8 +216,12 @@ public class FormLoginBeanDefinitionParser {
if (StringUtils.hasText(failureHandlerRef)) {
filterBuilder.addPropertyReference("authenticationFailureHandler",
failureHandlerRef);
}
else {
} else if(StringUtils.hasText(authenticationFailureForwardUrl)) {
BeanDefinitionBuilder forwardFailureHandler = BeanDefinitionBuilder
.rootBeanDefinition(ForwardAuthenticationFailureHandler.class);
forwardFailureHandler.addConstructorArgValue(authenticationFailureForwardUrl);
filterBuilder.addPropertyValue("authenticationFailureHandler", forwardFailureHandler.getBeanDefinition());
} else {
BeanDefinitionBuilder failureHandler = BeanDefinitionBuilder
.rootBeanDefinition(SimpleUrlAuthenticationFailureHandler.class);
if (!StringUtils.hasText(authenticationFailureUrl)) {

View File

@@ -438,6 +438,12 @@ form-login.attlist &=
form-login.attlist &=
## Reference to an AuthenticationDetailsSource which will be used by the authentication filter
attribute authentication-details-source-ref {xsd:token}?
form-login.attlist &=
## The URL for the ForwardAuthenticationFailureHandler
attribute authentication-failure-forward-url {xsd:token}?
form-login.attlist &=
## The URL for the ForwardAuthenticationSuccessHandler
attribute authentication-success-forward-url {xsd:token}?
openid-login =

View File

@@ -1465,6 +1465,18 @@
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="authentication-failure-forward-url" type="xs:token">
<xs:annotation>
<xs:documentation>The URL for the ForwardAuthenticationFailureHandler
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="authentication-success-forward-url" type="xs:token">
<xs:annotation>
<xs:documentation>The URL for the ForwardAuthenticationSuccessHandler
</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:attributeGroup>
<xs:element name="attribute-exchange">