java - Spring security 有时会在成功登录后重定向到默认页面而不是预登录页面

标签 java spring spring-boot spring-security

我们的团队正在使用 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/

相关文章:

java BufferedImage 到 int[] 问题

java - Java.io.FileNotFoundException:类路径资源[../ProductDao.class]无法打开,因为它不存在

spring - 如何在 spring mvc 中获取资源文件夹的正确路径?

java - Spring Boot外部文件db配置

PostgreSQL 驱动程序不接受 URL

java - java中如何找出sql结果集中的变量类型?

java - 线程主 java.util.InputMismatchException 中的异常

spring - @Resource 和 @Autowired 的区别

Java springdoc-openapi 在 Swagger UI 示例值中显示 LocalDateTime 字段以及附加日期/时间字段

java - 使用 Spring 启动服务器的 Android 登录身份验证