我们的团队正在使用 Spring boot (2.2.2) 开发 Web 应用程序。它使用 Spring security 来处理登录过程。我们希望应用程序重定向回登录前的页面(例如,用户访问 http://example.com/foo/bar -> 如果登录 session 已过期,则显示登录页面 -> 如果登录成功,则重定向回 http://example.com/foo/bar )
一切看起来都很好,只是应用程序偶尔会定向到默认页面(例如 http://example.com )而不是登录前的页面。发生这种情况时,似乎登录前的页面没有保存在 session 中(根据我的队友报告)。这是由于我们的配置问题吗?
以下是我们的WebSecurityConfig
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("...")
.anyRequest().authenticated()
.and()
.csrf().ignoringAntMatchers("...")
.and()
.formLogin()
.loginPage("/loginForm")
.loginProcessingUrl("/login")
.usernameParameter("userId")
.passwordParameter("password")
.failureUrl("/loginForm?error=true")
.permitAll()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessHandler(logoutSuccessHandler())
.deleteCookies("JSESSIONID")
.invalidateHttpSession(true)
.permitAll()
.and()
.exceptionHandling()
.accessDeniedHandler(new CustomAccessDeniedHandler())
.and()
.sessionManagement()
.invalidSessionUrl("/loginForm")
;
}
由于 WebSecurityConfig 中未设置 successHandler,因此默认会调用 SavedRequestAwareAuthenticationSuccessHandler。问题似乎出现在 onAuthenticationSuccess 方法的以下部分:
@Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication authentication)
throws ServletException, IOException {
SavedRequest savedRequest = requestCache.getRequest(request, response);
if (savedRequest == null) {
super.onAuthenticationSuccess(request, response, authentication);
return;
}
String targetUrlParameter = getTargetUrlParameter();
if (isAlwaysUseDefaultTargetUrl()
|| (targetUrlParameter != null && StringUtils.hasText(request
.getParameter(targetUrlParameter)))) {
requestCache.removeRequest(request, response);
super.onAuthenticationSuccess(request, response, authentication);
return;
}
clearAuthenticationAttributes(request);
// Use the DefaultSavedRequest URL
String targetUrl = savedRequest.getRedirectUrl();
logger.debug("Redirecting to DefaultSavedRequest Url: " + targetUrl);
getRedirectStrategy().sendRedirect(request, response, targetUrl);
}
有时,savedRequest 为 null,因此 Spring 安全性会在成功登录后定向到默认页面 ( http://example.com )。原因是什么?
最佳答案
重定向到上下文根是由于 sessionManagement().invalidSessionUrl("/loginForm")
引起的。
这是因为您正在对登录页面进行显式调用,因此它被视为请求的页面,而不是重定向以进行身份验证。身份验证后,spring 将重定向到默认 url(默认情况下是上下文根,除非在配置中覆盖)。
在我看来,这种情况应该经常发生,而不是偶尔发生。
请删除上述配置并让 spring 处理身份验证的重定向。 :)
关于java - Spring security 有时会在成功登录后重定向到默认页面而不是预登录页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59835130/