Spring Security 6 POST请求未通过permitAll()授权

qxsslcnc  于 2023-01-13  发布在  Spring
关注(0)|答案(2)|浏览(292)

我使用的是Spring Boot 3和Spring Security 6。我的安全配置不能正常工作。我有两个路径,在这两个路径上任何请求都应该被允许,而对于其他所有请求,都需要进行身份验证。
GETPOST方法都适用于需要身份验证的对象。
permitAll()上,只有GET请求工作。对于POST,我得到401未授权。
我处理了CSRF,而且无论如何,我希望所有的POST请求都能工作,而不仅仅是那些带有身份验证的请求。
在Postman上,我选择了POST,No Auth,放了一个RAW主体,然后选择了JSON。我真的不知道为什么它不工作。
下面是我的代码:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
        return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http,  KeycloakLogoutHandler keycloakLogoutHandler) throws Exception {

        http
            .authorizeHttpRequests()
                .requestMatchers("/firstpath/**", "/secondpath/**").permitAll()
                .and()
            .authorizeHttpRequests()
                .anyRequest().authenticated()
                .and()
            .oauth2ResourceServer(oauth2 -> oauth2.jwt());
        http
            .oauth2Login()
                .and()
            .logout()
                .addLogoutHandler(keycloakLogoutHandler)
                .logoutSuccessUrl("/");
        http
            .csrf()
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
        return http.build();
    }
}
@Slf4j
@RestController
@RequestMapping("/firstpath")
public class NameitController {

    @PostMapping(value = "path", produces = WSConstants.JSON_MEDIATYPE)
    @ResponseBody
    public ResponseEntity saveMyObject(@RequestBody ObjectDTO dto) {
        [...] //my code
    }
}

我也试过http.authorizeHttpRequests().requestMatchers(HttpMethod.POST, "/firstpath/path").permitAll(),但没有用。
编辑:还是和CSRF保护有关,因为我累了http.csrf().disable();的时候一切都很好,但是我还是想要CSRF保护,好像令牌不是用permitAll()送的?...

Edit2:添加Spring Security日志后:

编辑3:我发现我在Swagger中的任何POST请求上都有相同的403响应。我还添加了CsrfTokenRequestAttributeHandler,仍然不起作用:

@Bean
    public SecurityFilterChain filterChain(HttpSecurity http, KeycloakLogoutHandler keycloakLogoutHandler) throws Exception {

        CsrfTokenRequestAttributeHandler requestHandler = new CsrfTokenRequestAttributeHandler();
        // set the name of the attribute the CsrfToken will be populated on
        requestHandler.setCsrfRequestAttributeName(null);

        http
                .authorizeHttpRequests().requestMatchers("/firstpath/**", "/secondpath/**", "/error/**").permitAll().and()
                .authorizeHttpRequests().anyRequest().authenticated().and()
                .oauth2ResourceServer(oauth2 -> oauth2.jwt());
        http.oauth2Login()
                .and()
                .logout()
                .addLogoutHandler(keycloakLogoutHandler)
                .logoutSuccessUrl("/");
        http.csrf((csrf) -> csrf
                .csrfTokenRequestHandler(requestHandler));
        return http.build();
    }
5rgfhyps

5rgfhyps1#

变化
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());

http.csrf().ignoringRequestMatchers("/path/**").csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
成功了。但我不明白它在做什么或为什么。

ht4b089n

ht4b089n2#

您在安全配置中定义的顺序请看以下顺序

`@Override
   protected void configure(HttpSecurity http) throws Exception {
   http
        .authorizeRequests()
        .antMatchers(HttpMethod.POST, "/api/auth/**")
        .permitAll()
        .antMatchers("/",
                "/favicon.ico",
                "/**/*.png",
                "/**/*.gif",
                "/**/*.svg",
                "/**/*.jpg",
                "/**/*.html",
                "/**/*.css",
                "/**/*.js")
        .permitAll()                   
        .anyRequest()
        .authenticated()
        .and()
        .cors()
        .and()
        .exceptionHandling()
        .authenticationEntryPoint(this.jwtAuthenticationEntryPoint)
        .and()
        .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .csrf()
        .disable();

// Add our custom JWT security filter
http.addFilterBefore(jwtAuthenticationFilter(), 
 UsernamePasswordAuthenticationFilter.class);

 }`

相关问题