Spring security loginProcessingUrl 仅适用于本地主机

Spring security loginProcessingUrl only works on localhost

我已经使用 Spring Boot 和 Thymeleaf 构建了一个应用程序。我的应用程序在本地主机中按预期工作,但是当我将其打包为 .war 并将其部署在测试 tomcat 服务器中时,它会提示登录页面,然后将我重定向到错误页面或将我带回登录页面。

我尝试了多种方法,我认为我处理 SecurityConfig.java class 中的 formLogin() 的方式存在问题。更具体地说,由于 Tomcat 在上传我的应用程序时添加了 base-url (例如从 localhost:8080serverUrl:8080/reservation),loginProcessingUrl class 可能无法识别“/process-login”class 位于 login.html 页面。

请在下面找到我的 SecurityConfig.java class

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private UserService userService;
    private CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler;
    private AccessDeniedHandler accessDeniedHandler;

    @Autowired
    public SecurityConfig(UserService userService, CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler, AccessDeniedHandler accessDeniedHandler) {
        this.userService = userService;
        this.customAuthenticationSuccessHandler = customAuthenticationSuccessHandler;
        this.accessDeniedHandler = accessDeniedHandler;
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvider());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
        .authorizeRequests()
        .antMatchers("/login-form-page","/resources/**").permitAll()
        .antMatchers("/", "/new-reservation", "/your-reservations","/all-reservations",
                "/change-password").hasAnyRole("ADMIN","EMPLOYEE","MANAGER")
        .antMatchers("/users","/user-reservations","/arrival-date","/duplicate-reservations","/all-reservations","/registration**")
                .hasAnyRole("ADMIN").and()
        .formLogin()
            .loginPage("/login-form-page")
            .loginProcessingUrl("/process-login")
            .successHandler(customAuthenticationSuccessHandler)
            .permitAll()
        .and()
        .logout()
            .logoutUrl("/login-form-page")
            .permitAll()
        .and()
                .exceptionHandling().accessDeniedHandler(accessDeniedHandler);
    }

    @Override
    public void configure(WebSecurity web) {
        web.ignoring()
                .antMatchers("/resources/**", "/static/**");
    }
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider auth = new DaoAuthenticationProvider();
        auth.setUserDetailsService(userService); 
        auth.setPasswordEncoder(passwordEncoder());
        return auth;
    }

这里是 login.html 页面的一个小示例。


    <div class="form-container sign-in-container">
        <form id="loginForm" name="regForm" th:action="@{/process-login}"
            method="POST">
                <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
                    <h1>Sign In</h1>
                    <!-- Login Error -->
                    <div th:if="${param.error}"
                        class="alert alert-danger  col-xs-10">Wrong email and/or password</div>
    
                    <!-- Logout notify -->
                    <div th:if="${param.logout}"
                        class="alert alert-success 1 col-xs-10">You
                        have been logged out.</div>


所有 .html 页面位于

-resources
 -templates

最后,我在日志中看到的唯一错误如下

DEBUG o.s.w.s.r.ResourceHttpRequestHandler - Resource not found

对于任何感兴趣的人,我设法解决了上述问题。这似乎不是 loginProcessingUrl() class 中的配置错误。相反,问题在于远程服务器处理 JSESSIONIDcsrf 的方式。 更具体地说,我必须做的是

  • 在我的 SecurityConfig.java
  • 中添加了以下代码块
 cookieServerCsrfTokenRepository.setCookieHttpOnly(false);
    http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
  • 接下来,添加下面的代码块
 @Bean
    public ServletContextInitializer servletContextInitializer(@Value("${secure.cookie}") boolean secure) {
        return new ServletContextInitializer() {

            @Override
            public void onStartup(ServletContext servletContext) throws ServletException {
                servletContext.getSessionCookieConfig().setSecure(secure);
            }
        };
    }

需要设置 secure.cookie 值(如果您打算使用 HTTPs 协议,application.properties 中的值为 true。