spring Sping Boot 3中忽略@PermitAll注解

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

我目前正在开发一个简单的应用程序,它使用了一个整体架构,其中我使用了基于角色的身份验证的基本形式(使用自签名JWT)。令牌的设置和发布工作正常。
我使用的是Spring Security。默认情况下,我希望所有内容都被锁定,也就是说,如果我想专门启用对端点方法的访问,我希望使用@PermitAll annotation在端点中only这样做。
然而,该注解被忽略,所以我必须在Spring Config中手动指定公共端点,特别是在“requestMatchers”中。我不喜欢这个解决方案,因为我必须写两次端点路径(在控制器中,并在安全配置中):

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    return http
            .csrf(AbstractHttpConfigurer::disable)
            .authorizeHttpRequests(auth ->
                    auth
                            .requestMatchers("/register", "/login").permitAll()
                            .anyRequest().authenticated()
            )
            .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> jwt.decoder(jwtDecoder())))
            .exceptionHandling(ex ->
                    ex.authenticationEntryPoint(new BearerTokenAuthenticationEntryPoint())
                            .accessDeniedHandler(new BearerTokenAccessDeniedHandler()))
            .build();
}

字符串
此外,端点看起来如下所示:

@RestController
@RequiredArgsConstructor
public class AuthController {

    private final AuthService authService;

    @GetMapping
    public String foo() {
        return "Only authenticated users can use this";
    }

    // @PermitAll is ignored here, manual config is needed
    @PostMapping("login")
    public String login(@RequestBody LoginDto loginDto) {
        return authService.login(loginDto);
    }

    // @PermitAll is ignored here, manual config is needed
    @PostMapping("register")
    public String register(@RequestBody RegisterDto registerDto) {
        return authService.register(registerDto);
    }

}


安全配置类使用以下注解进行注解:

@Configuration
@EnableWebSecurity
@EnableMethodSecurity(securedEnabled = true, jsr250Enabled = true)

  • 注意:请注意,所有其他注解(例如安全/角色允许,...)都按预期工作。
ep6jt1vc

ep6jt1vc1#

我认为这与spring security的SecurityFilterChain的默认行为有关。你还没有提供你的非工作SecurityFilterChain配置,但我假设authorizeHttpRequests lambda看起来像这样:

authorizeHttpRequests(auth ->
                    auth.anyRequest().authenticated())

字符串
由于spring调度调用to the first FilterChain that matches,并且您可能将FilterChain定义为需要对每个端点进行身份验证(如果上述假设成立),那么无论您使用什么注解端点,访问都将被拒绝。
我不认为复制公共端点的路径是特别糟糕的做法,但如果你不想这样做,你可以对所有公共端点使用一个公共前缀,并在安全配置中将该前缀与通配符匹配:

authorizeHttpRequests(auth ->
                     auth.requestMatchers("/your-prefix/**").permitAll()
                    .anyRequest().authenticated())

相关问题