java 安全筛选器链不允许requestsMatchers

uinbv5nw  于 2023-04-28  发布在  Java
关注(0)|答案(1)|浏览(206)

我正在建立一个eshop作为一个练习,我想允许所有不需要授权的请求,如产品列表,客户注册等。
我设法允许登录和GET返回可用产品列表,但我不能使它工作为客户自我注册。
我得到错误403,因为令牌不存在(显然)。
这是我的安全过滤器链:

public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

    http
        .csrf().disable()
        .authorizeRequests()
            .requestMatchers("/api/v1/auth/**").permitAll()
            .requestMatchers(HttpMethod.GET, "/api/v1/products/**").permitAll()
            .requestMatchers("/api/v1/user/**").permitAll() //i think the problem is either here
            .anyRequest().authenticated()
            .and()
        .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
        .authenticationProvider(authenticationProvider)
        .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class); 

    /*http.formLogin();  
    http.httpBasic();*/  

    return http.build();
}

我也试着用这种方式写requestMatchers

.requestMatchers(HttpMethod.POST, "/api/v1/user/**")

.requestMatchers(HttpMethod.POST, "/api/v1/user/self-registration")

.requestMatchers("/api/v1/user/self-registration")

但什么都没变
我甚至不确定其中一个能用,因为如果我猜对了,这个

.requestMatchers(HttpMethod.GET , "/api/v1/products/**").permitAll()

应该允许以/api/v1/products开头任何端点的所有GET请求。如果是这种情况,我不能添加只有管理员可以执行的请求。
有人能解释一下我做错了什么吗?

  • Java 17
  • Sping Boot 3.0,
  • Spring Security最新
    ---更新----

以下是安全日志:

2023-04-21T16:42:12.328+02:00 DEBUG 13148 --- [nio-8082-exec-1] o.s.security.web.FilterChainProxy        : Securing POST /api/v1/user/self-registration
2023-04-21T16:42:12.337+02:00 DEBUG 13148 --- [nio-8082-exec-1] o.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to anonymous SecurityContext
2023-04-21T16:42:12.353+02:00 DEBUG 13148 --- [nio-8082-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor    : Authorized filter invocation [POST /api/v1/user/self-registration] with attributes [permitAll]
2023-04-21T16:42:12.353+02:00 DEBUG 13148 --- [nio-8082-exec-1] o.s.security.web.FilterChainProxy        : Secured POST /api/v1/user/self-registration
2023-04-21T16:42:12.373+02:00 DEBUG 13148 --- [nio-8082-exec-1] o.s.security.web.FilterChainProxy        : Securing POST /error
2023-04-21T16:42:12.376+02:00 DEBUG 13148 --- [nio-8082-exec-1] o.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to anonymous SecurityContext
2023-04-21T16:42:12.376+02:00 DEBUG 13148 --- [nio-8082-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor    : Failed to authorize filter invocation [POST /error] with attributes [authenticated]
2023-04-21T16:42:12.376+02:00 DEBUG 13148 --- [nio-8082-exec-1] o.s.s.w.a.Http403ForbiddenEntryPoint     : Pre-authenticated entry point called. Rejecting access

这些是请求头。我还尝试添加“Authorization”头空和“Bearer“,但没有任何令牌之后。不是问题所在

----已解决-----

我终于解决了
首先,我了解到可以向同一个.requestMatchers()方法添加多个字符串
因此,目前过滤器已更改此请求匹配器

.requestMatchers("/api/v1/auth/**","/api/v1/user/selfregistration")   
            .permitAll()

然后我得到了error 404 not found,我不得不改变我的控制器,现在它的工作正常

zbdgwd5y

zbdgwd5y1#

假设您正在构建一个公开API的服务,下面的配置对我来说很好

@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.csrf().disable().authorizeHttpRequests()
                .requestMatchers("/api/v1/auth/**").permitAll()
                .requestMatchers(HttpMethod.GET, "/api/v1/products/**").permitAll()
                .requestMatchers("/api/v1/users/**").permitAll()
                .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and().oauth2ResourceServer().jwt();
        return http.build();
    }

    @Bean
    JwtDecoder jwtDecoder() {
        return new NimbusJwtDecoder(jwtProcessor());
    }

    private JWTProcessor<SecurityContext> jwtProcessor() {
        return new DefaultJWTProcessor<>();
    }
}

控制器:

@RestController
public class ApiController {

    @GetMapping("/api/v1/auth/{id}")
    public String auth(@PathVariable String id) {
        return id;
    }

    @GetMapping("/api/v1/products/{id}")
    public String getProduct(@PathVariable String id) {
        return id;
    }

    @GetMapping("/api/v1/users/{id}")
    public String getUser(@PathVariable String id) {
        return id;
    }

    @GetMapping("/api/v1/secured/{id}")
    public String getSecuredResource(@PathVariable String id) {
        return id;
    }
}

curl 请求:

curl localhost:8080/api/v1/auth/username                                                                                                                                                                               
username                                                                                                                                                                                                                                   

curl localhost:8080/api/v1/products/product1                                                                                                                                                                           
product1
                                                                                                                                                                                                                                   
curl localhost:8080/api/v1/users/user1                                                                                                                                                                                 
user1
                                                                                                                                                                                                                                     
curl localhost:8080/api/v1/secured/id

我没有你的完整的安全配置类,看看是否有一个问题与您的配置。希望这能帮上忙。

相关问题