diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/HttpSecurityBuilder.java b/config/src/main/java/org/springframework/security/config/annotation/web/HttpSecurityBuilder.java index d095885daa..2be57a9f95 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/HttpSecurityBuilder.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/HttpSecurityBuilder.java @@ -152,7 +152,7 @@ public interface HttpSecurityBuilder> extends S *
  • {@link UsernamePasswordAuthenticationFilter}
  • *
  • {@link ConcurrentSessionFilter}
  • *
  • {@link OpenIDAuthenticationFilter}
  • - *
  • {@link DefaultLoginPageViewFilter}
  • + *
  • {@link DefaultLoginPageGeneratingFilter}
  • *
  • {@link ConcurrentSessionFilter}
  • *
  • {@link DigestAuthenticationFilter}
  • *
  • {@link BasicAuthenticationFilter}
  • diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/builders/FilterComparator.java b/config/src/main/java/org/springframework/security/config/annotation/web/builders/FilterComparator.java index 16108001eb..fc257364bc 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/builders/FilterComparator.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/builders/FilterComparator.java @@ -32,7 +32,7 @@ import org.springframework.security.web.authentication.preauth.AbstractPreAuthen import org.springframework.security.web.authentication.preauth.x509.X509AuthenticationFilter; import org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter; import org.springframework.security.web.authentication.switchuser.SwitchUserFilter; -import org.springframework.security.web.authentication.ui.DefaultLoginPageViewFilter; +import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; import org.springframework.security.web.authentication.www.DigestAuthenticationFilter; import org.springframework.security.web.context.SecurityContextPersistenceFilter; @@ -86,7 +86,7 @@ final class FilterComparator implements Comparator, Serializable { order += STEP; filterToOrder.put("org.springframework.security.openid.OpenIDAuthenticationFilter", order); order += STEP; - put(DefaultLoginPageViewFilter.class, order); + put(DefaultLoginPageGeneratingFilter.class, order); order += STEP; put(ConcurrentSessionFilter.class, order); order += STEP; diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/DefaultLoginPageConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/DefaultLoginPageConfigurer.java index a0e063f0a1..2172e69371 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/DefaultLoginPageConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/DefaultLoginPageConfigurer.java @@ -18,7 +18,7 @@ package org.springframework.security.config.annotation.web.configurers; import org.springframework.security.config.annotation.web.HttpSecurityBuilder; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.web.AuthenticationEntryPoint; -import org.springframework.security.web.authentication.ui.DefaultLoginPageViewFilter; +import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter; /** * Adds a Filter that will generate a login page if one is not specified otherwise when using {@link WebSecurityConfigurerAdapter}. @@ -32,7 +32,7 @@ import org.springframework.security.web.authentication.ui.DefaultLoginPageViewFi * The following Filters are conditionally populated * * * *

    Shared Objects Created

    @@ -56,11 +56,11 @@ import org.springframework.security.web.authentication.ui.DefaultLoginPageViewFi public final class DefaultLoginPageConfigurer> extends AbstractHttpConfigurer,H> { - private DefaultLoginPageViewFilter loginPageGeneratingFilter = new DefaultLoginPageViewFilter(); + private DefaultLoginPageGeneratingFilter loginPageGeneratingFilter = new DefaultLoginPageGeneratingFilter(); @Override public void init(H http) throws Exception { - http.setSharedObject(DefaultLoginPageViewFilter.class, loginPageGeneratingFilter); + http.setSharedObject(DefaultLoginPageGeneratingFilter.class, loginPageGeneratingFilter); } @Override diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/FormLoginConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/FormLoginConfigurer.java index 3d3aadbfbf..90e7060b09 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/FormLoginConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/FormLoginConfigurer.java @@ -22,7 +22,7 @@ import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.authentication.RememberMeServices; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; -import org.springframework.security.web.authentication.ui.DefaultLoginPageViewFilter; +import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; @@ -57,7 +57,7 @@ import org.springframework.security.web.util.matcher.RequestMatcher; *
  • {@link AuthenticationManager}
  • *
  • {@link RememberMeServices} - is optionally used. See {@link RememberMeConfigurer}
  • *
  • {@link SessionAuthenticationStrategy} - is optionally used. See {@link SessionManagementConfigurer}
  • - *
  • {@link DefaultLoginPageViewFilter} - if present will be populated with information from the configuration
  • + *
  • {@link DefaultLoginPageGeneratingFilter} - if present will be populated with information from the configuration
  • * * * @author Rob Winch @@ -245,12 +245,12 @@ public final class FormLoginConfigurer> extends } /** - * If available, initializes the {@link DefaultLoginPageViewFilter} shared object. + * If available, initializes the {@link DefaultLoginPageGeneratingFilter} shared object. * * @param http the {@link HttpSecurityBuilder} to use */ private void initDefaultLoginFilter(H http) { - DefaultLoginPageViewFilter loginPageGeneratingFilter = http.getSharedObject(DefaultLoginPageViewFilter.class); + DefaultLoginPageGeneratingFilter loginPageGeneratingFilter = http.getSharedObject(DefaultLoginPageGeneratingFilter.class); if(loginPageGeneratingFilter != null && !isCustomLoginPage()) { loginPageGeneratingFilter.setFormLoginEnabled(true); loginPageGeneratingFilter.setUsernameParameter(getUsernameParameter()); diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.java index b0b1421996..05d643818c 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.java @@ -29,7 +29,7 @@ import org.springframework.security.web.authentication.logout.LogoutHandler; import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler; -import org.springframework.security.web.authentication.ui.DefaultLoginPageViewFilter; +import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; @@ -228,7 +228,7 @@ public final class LogoutConfigurer> extends Ab PermitAllSupport.permitAll(http, this.getLogoutRequestMatcher(http)); } - DefaultLoginPageViewFilter loginPageGeneratingFilter = http.getSharedObject(DefaultLoginPageViewFilter.class); + DefaultLoginPageGeneratingFilter loginPageGeneratingFilter = http.getSharedObject(DefaultLoginPageGeneratingFilter.class); if(loginPageGeneratingFilter != null && !isCustomLogoutSuccess()) { loginPageGeneratingFilter.setLogoutSuccessUrl(getLogoutSuccessUrl()); } diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java index 4d4eead13e..f5f5df2cfc 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java @@ -32,7 +32,7 @@ import org.springframework.security.web.authentication.rememberme.PersistentToke import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository; import org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter; import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices; -import org.springframework.security.web.authentication.ui.DefaultLoginPageViewFilter; +import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter; /** * Configures Remember Me authentication. This typically involves the user @@ -67,7 +67,7 @@ import org.springframework.security.web.authentication.ui.DefaultLoginPageViewFi *
      *
    • {@link AuthenticationManager}
    • *
    • {@link UserDetailsService} if no {@link #userDetailsService(UserDetailsService)} was specified.
    • - *
    • {@link DefaultLoginPageViewFilter} - if present will be populated with information from the configuration
    • + *
    • {@link DefaultLoginPageGeneratingFilter} - if present will be populated with information from the configuration
    • *
    * * @author Rob Winch @@ -229,12 +229,12 @@ public final class RememberMeConfigurer> extend } /** - * If available, initializes the {@link DefaultLoginPageViewFilter} shared object. + * If available, initializes the {@link DefaultLoginPageGeneratingFilter} shared object. * * @param http the {@link HttpSecurityBuilder} to use */ private void initDefaultLoginFilter(H http) { - DefaultLoginPageViewFilter loginPageGeneratingFilter = http.getSharedObject(DefaultLoginPageViewFilter.class); + DefaultLoginPageGeneratingFilter loginPageGeneratingFilter = http.getSharedObject(DefaultLoginPageGeneratingFilter.class); if(loginPageGeneratingFilter != null) { loginPageGeneratingFilter.setRememberMeParameter(getRememberMeParameter()); } diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/openid/OpenIDLoginConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/openid/OpenIDLoginConfigurer.java index 2dadab4c43..58adb80563 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/openid/OpenIDLoginConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/openid/OpenIDLoginConfigurer.java @@ -49,7 +49,7 @@ import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; import org.springframework.security.web.authentication.RememberMeServices; import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; -import org.springframework.security.web.authentication.ui.DefaultLoginPageViewFilter; +import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; @@ -340,12 +340,12 @@ public final class OpenIDLoginConfigurer> exten } /** - * If available, initializes the {@link DefaultLoginPageViewFilter} shared object. + * If available, initializes the {@link DefaultLoginPageGeneratingFilter} shared object. * * @param http the {@link HttpSecurityBuilder} to use */ private void initDefaultLoginFilter(H http) { - DefaultLoginPageViewFilter loginPageGeneratingFilter = http.getSharedObject(DefaultLoginPageViewFilter.class); + DefaultLoginPageGeneratingFilter loginPageGeneratingFilter = http.getSharedObject(DefaultLoginPageGeneratingFilter.class); if(loginPageGeneratingFilter != null && !isCustomLoginPage()) { loginPageGeneratingFilter.setOpenIdEnabled(true); loginPageGeneratingFilter.setOpenIDauthenticationUrl(getLoginProcessingUrl()); diff --git a/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/DefaultLoginPageConfigurerTests.groovy b/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/DefaultLoginPageConfigurerTests.groovy index c05ad41fcf..e523a2d8ab 100644 --- a/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/DefaultLoginPageConfigurerTests.groovy +++ b/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/DefaultLoginPageConfigurerTests.groovy @@ -33,7 +33,7 @@ import org.springframework.security.web.access.ExceptionTranslationFilter; import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler -import org.springframework.security.web.authentication.ui.DefaultLoginPageViewFilter; +import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter /** * Tests to verify that {@link DefaultLoginPageConfigurer} works @@ -48,7 +48,7 @@ public class DefaultLoginPageConfigurerTests extends BaseSpringSpec { when: springSecurityFilterChain.doFilter(request,response,chain) then: - findFilter(DefaultLoginPageViewFilter) + findFilter(DefaultLoginPageGeneratingFilter) response.getRedirectedUrl() == "http://localhost/login" when: "request the login page" super.setup() @@ -293,7 +293,7 @@ public class DefaultLoginPageConfigurerTests extends BaseSpringSpec { when: loadConfig(DefaultLoginWithCustomAuthenticationEntryPointConfig) then: - !findFilter(DefaultLoginPageViewFilter) + !findFilter(DefaultLoginPageGeneratingFilter) } @Configuration @@ -328,7 +328,7 @@ public class DefaultLoginPageConfigurerTests extends BaseSpringSpec { .build() then: "DefaultLoginPageGeneratingFilter is registered with LifecycleManager" - 1 * objectPostProcessor.postProcess(_ as DefaultLoginPageViewFilter) >> {DefaultLoginPageViewFilter o -> o} + 1 * objectPostProcessor.postProcess(_ as DefaultLoginPageGeneratingFilter) >> {DefaultLoginPageGeneratingFilter o -> o} 1 * objectPostProcessor.postProcess(_ as UsernamePasswordAuthenticationFilter) >> {UsernamePasswordAuthenticationFilter o -> o} 1 * objectPostProcessor.postProcess(_ as LoginUrlAuthenticationEntryPoint) >> {LoginUrlAuthenticationEntryPoint o -> o} 1 * objectPostProcessor.postProcess(_ as ExceptionTranslationFilter) >> {ExceptionTranslationFilter o -> o} diff --git a/config/src/test/groovy/org/springframework/security/config/http/HttpOpenIDConfigTests.groovy b/config/src/test/groovy/org/springframework/security/config/http/HttpOpenIDConfigTests.groovy index ed64d7ea26..f2403092c6 100644 --- a/config/src/test/groovy/org/springframework/security/config/http/HttpOpenIDConfigTests.groovy +++ b/config/src/test/groovy/org/springframework/security/config/http/HttpOpenIDConfigTests.groovy @@ -99,7 +99,7 @@ class OpenIDConfigTests extends AbstractHttpConfigTests { openIDFilter.setReturnToUrlParameters(returnToUrlParameters) assert loginFilter.openIDrememberMeParameter != null - MockHttpServletRequest request = new MockHttpServletRequest(); + MockHttpServletRequest request = new MockHttpServletRequest(method:'GET'); MockHttpServletResponse response = new MockHttpServletResponse(); when: "Initial request is made" diff --git a/samples/messages-jc/pom.xml b/samples/messages-jc/pom.xml index d2b5b59001..368c232525 100644 --- a/samples/messages-jc/pom.xml +++ b/samples/messages-jc/pom.xml @@ -132,18 +132,18 @@ spring-core 3.2.4.RELEASE compile - - - commons-logging - commons-logging - - org.springframework spring-core 3.2.4.RELEASE compile + + + commons-logging + commons-logging + + org.springframework diff --git a/web/src/main/java/org/springframework/security/web/authentication/ui/DefaultLoginPageGeneratingFilter.java b/web/src/main/java/org/springframework/security/web/authentication/ui/DefaultLoginPageGeneratingFilter.java index ff9d065394..8a6ba75d19 100644 --- a/web/src/main/java/org/springframework/security/web/authentication/ui/DefaultLoginPageGeneratingFilter.java +++ b/web/src/main/java/org/springframework/security/web/authentication/ui/DefaultLoginPageGeneratingFilter.java @@ -15,6 +15,7 @@ import org.springframework.security.web.WebAttributes; import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices; +import org.springframework.security.web.csrf.CsrfToken; import org.springframework.web.filter.GenericFilterBean; /** @@ -29,8 +30,11 @@ import org.springframework.web.filter.GenericFilterBean; public class DefaultLoginPageGeneratingFilter extends GenericFilterBean { public static final String DEFAULT_LOGIN_PAGE_URL = "/spring_security_login"; public static final String ERROR_PARAMETER_NAME = "login_error"; - boolean formLoginEnabled; - boolean openIdEnabled; + private String loginPageUrl; + private String logoutSuccessUrl; + private String failureUrl; + private boolean formLoginEnabled; + private boolean openIdEnabled; private String authenticationUrl; private String usernameParameter; private String passwordParameter; @@ -39,6 +43,8 @@ public class DefaultLoginPageGeneratingFilter extends GenericFilterBean { private String openIDusernameParameter; private String openIDrememberMeParameter; + public DefaultLoginPageGeneratingFilter() {} + public DefaultLoginPageGeneratingFilter(AbstractAuthenticationProcessingFilter filter) { if (filter instanceof UsernamePasswordAuthenticationFilter) { init((UsernamePasswordAuthenticationFilter)filter, null); @@ -52,6 +58,9 @@ public class DefaultLoginPageGeneratingFilter extends GenericFilterBean { } private void init(UsernamePasswordAuthenticationFilter authFilter, AbstractAuthenticationProcessingFilter openIDFilter) { + this.loginPageUrl = DEFAULT_LOGIN_PAGE_URL; + this.logoutSuccessUrl = DEFAULT_LOGIN_PAGE_URL + "?logout"; + this.failureUrl = DEFAULT_LOGIN_PAGE_URL + "?" + ERROR_PARAMETER_NAME; if (authFilter != null) { formLoginEnabled = true; authenticationUrl = authFilter.getFilterProcessesUrl(); @@ -74,13 +83,68 @@ public class DefaultLoginPageGeneratingFilter extends GenericFilterBean { } } + public boolean isEnabled() { + return formLoginEnabled || openIdEnabled; + } + + public void setLogoutSuccessUrl(String logoutSuccessUrl) { + this.logoutSuccessUrl = logoutSuccessUrl; + } + + public String getLoginPageUrl() { + return loginPageUrl; + } + + public void setLoginPageUrl(String loginPageUrl) { + this.loginPageUrl = loginPageUrl; + } + + public void setFailureUrl(String failureUrl) { + this.failureUrl = failureUrl; + } + + public void setFormLoginEnabled(boolean formLoginEnabled) { + this.formLoginEnabled = formLoginEnabled; + } + + public void setOpenIdEnabled(boolean openIdEnabled) { + this.openIdEnabled = openIdEnabled; + } + + public void setAuthenticationUrl(String authenticationUrl) { + this.authenticationUrl = authenticationUrl; + } + + public void setUsernameParameter(String usernameParameter) { + this.usernameParameter = usernameParameter; + } + + public void setPasswordParameter(String passwordParameter) { + this.passwordParameter = passwordParameter; + } + + public void setRememberMeParameter(String rememberMeParameter) { + this.rememberMeParameter = rememberMeParameter; + this.openIDrememberMeParameter = rememberMeParameter; + } + + public void setOpenIDauthenticationUrl(String openIDauthenticationUrl) { + this.openIDauthenticationUrl = openIDauthenticationUrl; + } + + public void setOpenIDusernameParameter(String openIDusernameParameter) { + this.openIDusernameParameter = openIDusernameParameter; + } + public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; - if (isLoginUrlRequest(request)) { - String loginPageHtml = generateLoginPageHtml(request); + boolean loginError = isErrorPage(request); + boolean logoutSuccess = isLogoutSuccess(request); + if (isLoginUrlRequest(request) || loginError || logoutSuccess) { + String loginPageHtml = generateLoginPageHtml(request, loginError, logoutSuccess); response.setContentType("text/html;charset=UTF-8"); response.setContentLength(loginPageHtml.length()); response.getWriter().write(loginPageHtml); @@ -91,8 +155,7 @@ public class DefaultLoginPageGeneratingFilter extends GenericFilterBean { chain.doFilter(request, response); } - private String generateLoginPageHtml(HttpServletRequest request) { - boolean loginError = request.getParameter(ERROR_PARAMETER_NAME) != null; + private String generateLoginPageHtml(HttpServletRequest request, boolean loginError, boolean logoutSuccess) { String errorMsg = "none"; if (loginError) { @@ -118,6 +181,10 @@ public class DefaultLoginPageGeneratingFilter extends GenericFilterBean { sb.append("

    "); } + if (logoutSuccess) { + sb.append("

    You have been logged out

    "); + } + if (formLoginEnabled) { sb.append("

    Login with Username and Password

    "); sb.append("
    \n"); @@ -131,6 +198,7 @@ public class DefaultLoginPageGeneratingFilter extends GenericFilterBean { } sb.append(" \n"); + renderHiddenInputs(sb, request); sb.append(" \n"); sb.append("
    "); } @@ -148,6 +216,7 @@ public class DefaultLoginPageGeneratingFilter extends GenericFilterBean { sb.append(" \n"); sb.append(" \n"); + renderHiddenInputs(sb, request); sb.append(""); } @@ -156,7 +225,30 @@ public class DefaultLoginPageGeneratingFilter extends GenericFilterBean { return sb.toString(); } + private void renderHiddenInputs(StringBuilder sb, HttpServletRequest request) { + CsrfToken token = (CsrfToken) request.getAttribute(CsrfToken.class.getName()); + + if(token != null) { + sb.append(" \n"); + } + } + + private boolean isLogoutSuccess(HttpServletRequest request) { + return logoutSuccessUrl != null && matches(request, logoutSuccessUrl); + } + private boolean isLoginUrlRequest(HttpServletRequest request) { + return matches(request, loginPageUrl); + } + + private boolean isErrorPage(HttpServletRequest request) { + return matches(request, failureUrl); + } + + private boolean matches(HttpServletRequest request, String url) { + if(!"GET".equals(request.getMethod()) || url == null) { + return false; + } String uri = request.getRequestURI(); int pathParamIndex = uri.indexOf(';'); @@ -165,10 +257,14 @@ public class DefaultLoginPageGeneratingFilter extends GenericFilterBean { uri = uri.substring(0, pathParamIndex); } - if ("".equals(request.getContextPath())) { - return uri.endsWith(DEFAULT_LOGIN_PAGE_URL); + if(request.getQueryString() != null) { + uri += "?" + request.getQueryString(); } - return uri.endsWith(request.getContextPath() + DEFAULT_LOGIN_PAGE_URL); + if ("".equals(request.getContextPath())) { + return uri.endsWith(url); + } + + return uri.endsWith(request.getContextPath() + url); } } diff --git a/web/src/main/java/org/springframework/security/web/authentication/ui/DefaultLoginPageViewFilter.java b/web/src/main/java/org/springframework/security/web/authentication/ui/DefaultLoginPageViewFilter.java deleted file mode 100644 index d1188e626c..0000000000 --- a/web/src/main/java/org/springframework/security/web/authentication/ui/DefaultLoginPageViewFilter.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.security.web.authentication.ui; - -import java.io.IOException; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.web.WebAttributes; -import org.springframework.security.web.csrf.CsrfToken; -import org.springframework.web.filter.GenericFilterBean; - -/** - * This class generates a default login page if one was not specified. - * - * @author Rob Winch - * @since 3.2 - */ -public class DefaultLoginPageViewFilter extends GenericFilterBean { - private String loginPageUrl; - private String logoutSuccessUrl; - private String failureUrl; - private boolean formLoginEnabled; - private boolean openIdEnabled; - private String authenticationUrl; - private String usernameParameter; - private String passwordParameter; - private String rememberMeParameter; - private String openIDauthenticationUrl; - private String openIDusernameParameter; - private String openIDrememberMeParameter; - - public boolean isEnabled() { - return formLoginEnabled || openIdEnabled; - } - - public void setLogoutSuccessUrl(String logoutSuccessUrl) { - this.logoutSuccessUrl = logoutSuccessUrl; - } - - public String getLoginPageUrl() { - return loginPageUrl; - } - - public void setLoginPageUrl(String loginPageUrl) { - this.loginPageUrl = loginPageUrl; - } - - public void setFailureUrl(String failureUrl) { - this.failureUrl = failureUrl; - } - - public void setFormLoginEnabled(boolean formLoginEnabled) { - this.formLoginEnabled = formLoginEnabled; - } - - public void setOpenIdEnabled(boolean openIdEnabled) { - this.openIdEnabled = openIdEnabled; - } - - public void setAuthenticationUrl(String authenticationUrl) { - this.authenticationUrl = authenticationUrl; - } - - public void setUsernameParameter(String usernameParameter) { - this.usernameParameter = usernameParameter; - } - - public void setPasswordParameter(String passwordParameter) { - this.passwordParameter = passwordParameter; - } - - public void setRememberMeParameter(String rememberMeParameter) { - this.rememberMeParameter = rememberMeParameter; - this.openIDrememberMeParameter = rememberMeParameter; - } - - public void setOpenIDauthenticationUrl(String openIDauthenticationUrl) { - this.openIDauthenticationUrl = openIDauthenticationUrl; - } - - public void setOpenIDusernameParameter(String openIDusernameParameter) { - this.openIDusernameParameter = openIDusernameParameter; - } - - public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) - throws IOException, ServletException { - HttpServletRequest request = (HttpServletRequest) req; - HttpServletResponse response = (HttpServletResponse) res; - - boolean loginError = isErrorPage(request); - boolean logoutSuccess = isLogoutSuccess(request); - if (isLoginUrlRequest(request) || loginError || logoutSuccess) { - String loginPageHtml = generateLoginPageHtml(request, loginError, logoutSuccess); - response.setContentType("text/html;charset=UTF-8"); - response.setContentLength(loginPageHtml.length()); - response.getWriter().write(loginPageHtml); - - return; - } - - chain.doFilter(request, response); - } - - private String generateLoginPageHtml(HttpServletRequest request, boolean loginError, boolean logoutSuccess) { - String errorMsg = "none"; - - if (loginError) { - HttpSession session = request.getSession(false); - - if(session != null) { - AuthenticationException ex = (AuthenticationException) session.getAttribute(WebAttributes.AUTHENTICATION_EXCEPTION); - errorMsg = ex != null ? ex.getMessage() : "none"; - } - } - - StringBuilder sb = new StringBuilder(); - - sb.append("Login Page"); - - if (formLoginEnabled) { - sb.append("\n"); - } - - if (loginError) { - sb.append("

    Your login attempt was not successful, try again.

    Reason: "); - sb.append(errorMsg); - sb.append("

    "); - } - - if (logoutSuccess) { - sb.append("

    You have been logged out

    "); - } - - if (formLoginEnabled) { - sb.append("

    Login with Username and Password

    "); - sb.append("
    \n"); - sb.append(" \n"); - sb.append(" \n"); - sb.append(" \n"); - - if (rememberMeParameter != null) { - sb.append(" \n"); - } - - sb.append(" \n"); - renderHiddenInputs(sb, request); - sb.append("
    User:
    Password:
    Remember me on this computer.
    \n"); - sb.append("
    "); - } - - if(openIdEnabled) { - sb.append("

    Login with OpenID Identity

    "); - sb.append("
    \n"); - sb.append(" \n"); - sb.append(" \n"); - - if (openIDrememberMeParameter != null) { - sb.append(" \n"); - } - - sb.append(" \n"); - sb.append("
    Identity:
    Remember me on this computer.
    \n"); - renderHiddenInputs(sb, request); - sb.append("
    "); - } - - sb.append(""); - - return sb.toString(); - } - - private void renderHiddenInputs(StringBuilder sb, HttpServletRequest request) { - CsrfToken token = (CsrfToken) request.getAttribute(CsrfToken.class.getName()); - - if(token != null) { - sb.append(" \n"); - } - } - - private boolean isLogoutSuccess(HttpServletRequest request) { - return logoutSuccessUrl != null && matches(request, logoutSuccessUrl); - } - - private boolean isLoginUrlRequest(HttpServletRequest request) { - return matches(request, loginPageUrl); - } - - private boolean isErrorPage(HttpServletRequest request) { - return matches(request, failureUrl); - } - - private boolean matches(HttpServletRequest request, String url) { - if(!"GET".equals(request.getMethod()) || url == null) { - return false; - } - String uri = request.getRequestURI(); - int pathParamIndex = uri.indexOf(';'); - - if (pathParamIndex > 0) { - // strip everything after the first semi-colon - uri = uri.substring(0, pathParamIndex); - } - - if(request.getQueryString() != null) { - uri += "?" + request.getQueryString(); - } - - if ("".equals(request.getContextPath())) { - return uri.endsWith(url); - } - - return uri.endsWith(request.getContextPath() + url); - } -}