当在Spring Security 6中使用securityMatcher时,Default /logout不起作用

szqfcxe2  于 5个月前  发布在  Spring
关注(0)|答案(1)|浏览(72)

在Spring Security 6中,(特别是Sping Boot 3.2,在我的情况下是Spring MVC with Thymeleaf)当使用securityMatcher时,默认/注销POST或GET停止工作。

@Bean
    public SecurityFilterChain openFilterChain(HttpSecurity http) throws Exception {
        http.securityMatcher("/EParticipate/baudit/**")
            .addFilterBefore(new BauditUsernamePasswordAuthenticationFilter(
                this.authenticationManager(userDetailsService, passwordEncoder())),
                UsernamePasswordAuthenticationFilter.class
            )
            .authorizeHttpRequests((requests) -> requests
                .dispatcherTypeMatchers(DispatcherType.FORWARD, DispatcherType.ERROR).permitAll()
                .requestMatchers("/EParticipate/baudit/**").hasRole("BAUDIT")
                .requestMatchers("/EParticipateSecurity/**").permitAll()
            )
            .authenticationManager(this.authenticationManager(userDetailsService, passwordEncoder()))
            .formLogin(form -> form
                .loginPage("/EParticipateSecurity/login_request").permitAll()
                .defaultSuccessUrl("/EParticipate/baudit")
            )
        return http.build();
    }

字符串
Thymeleaf中的POST链接:

<form id="logout_form" th:action="@{/logout}" method="POST">
         <button id="logout_button" type="submit">Logout</button>
    </form>


即使您将permitAll()添加到requestMatcher,它仍然无法工作:

@Bean
    public SecurityFilterChain openFilterChain(HttpSecurity http) throws Exception {
        http.securityMatcher("/EParticipate/baudit/**")
            .addFilterBefore(new BauditUsernamePasswordAuthenticationFilter(
                this.authenticationManager(userDetailsService, passwordEncoder())),
                UsernamePasswordAuthenticationFilter.class
            )
            .authorizeHttpRequests((requests) -> requests
                .dispatcherTypeMatchers(DispatcherType.FORWARD, DispatcherType.ERROR).permitAll()
                .requestMatchers("/EParticipate/baudit/**").hasRole("BAUDIT")
                //Doesn't work
                .requestMatchers("/EParticipateSecurity/**","/logout").permitAll()
            )
            .authenticationManager(this.authenticationManager(userDetailsService, passwordEncoder()))
            .formLogin(form -> form
                .loginPage("/EParticipateSecurity/login_request").permitAll()
                .defaultSuccessUrl("/EParticipate/baudit")
            )
        return http.build();
    }

rnmwe5a2

rnmwe5a21#

为了解决这个问题,我必须在securityMatcher的URL下添加一个自定义注销作为子URL(我还添加了一个注销处理程序,以确保注销时清除所有内容)。

@Bean
public SecurityFilterChain openFilterChain(HttpSecurity http) throws Exception {
    http.securityMatcher("/EParticipate/baudit/**")
        .addFilterBefore(new BauditUsernamePasswordAuthenticationFilter(
            this.authenticationManager(userDetailsService, passwordEncoder())),
        UsernamePasswordAuthenticationFilter.class
        )
        .authorizeHttpRequests((requests) -> requests
            .dispatcherTypeMatchers(DispatcherType.FORWARD, DispatcherType.ERROR).permitAll()
            .requestMatchers("/EParticipate/baudit/**").hasRole("BAUDIT")
            .requestMatchers("/EParticipateSecurity/**").permitAll()
        )
        .authenticationManager(this.authenticationManager(userDetailsService, passwordEncoder()))
        .formLogin(form -> form
            .loginPage("/EParticipateSecurity/login_request").permitAll()
            .defaultSuccessUrl("/EParticipate/baudit")
        )
        .logout((logout) -> logout
            .addLogoutHandler(new HeaderWriterLogoutHandler(new ClearSiteDataHeaderWriter(Directive.CACHE,Directive.COOKIES,Directive.EXECUTION_CONTEXTS,Directive.STORAGE)))
            .logoutUrl("/EParticipate/baudit/logout")//URL under the securityMatcher URL above
            .logoutSuccessUrl("/EParticipateSecurity/login_request").permitAll()
        );
    return http.build();
}

字符串

相关问题