spring-security 使用@PreAuthorize时,Spring Security返回26而不是403

ylamdve6  于 2022-11-11  发布在  Spring
关注(0)|答案(1)|浏览(172)

我正在做一个小项目,包括使用react的web和使用spring data rest的rest api,它们都打包在一个jar中。web和api都受到Spring Security的保护,表单登录的默认配置,以及在仓库方法上使用@ PreAuthorize(“hasRole('ADMIN')”)这样的@PreAuthorize注解。登录后,如果用户有权限,一切都很好;但如果不是,则请求将等待很长时间(几分钟),并返回HTTP状态26。
Sping Boot 版本为2.7.0
我尝试过使用spring-session-jdbc和X-Auth-Token头,但还是一样。
安全配置:

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration
public class SecurityConfiguration {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
        .authorizeRequests().anyRequest().authenticated()
        .and()
        .csrf().disable()
        .cors(Customizer.withDefaults())
        .formLogin();
        return http.build();
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.addAllowedHeader("*");
        configuration.addAllowedMethod("*");
        configuration.addAllowedOrigin("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/api/**", configuration);
        return source;
    }
}

存储库端点:

public interface UserRepository extends JpaRepository<User, String> {

    @PreAuthorize("hasRole('ADMIN')")
    <S extends User> S save(User u);

    @PreAuthorize("hasRole('USER')")
    List<User> findByNameContains(String name);

测试请求和响应报头:

curl -X POST -H 'Content-Type: application/json; charset=utf8;' -i 'http://xxxxxxxxxxxx:8080/api/users' --data '{
"username": "john.m",
"name": "John Murdoch"
}'

# response header

Status Code: 26
access-control-allow-origin: *
cache-control: no-cache, no-store, max-age=0, must-revalidate
connection: keep-alive
date: Mon, 10 Oct 2022 00:58:34 GMT
expires: 0
keep-alive: timeout=60
pragma: no-cache
vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers
x-content-type-options: nosniff
x-frame-options: DENY
x-xss-protection: 1; mode=block

我发现了这个问题,我配置了一个全局异常处理程序来处理AccessDeniedException,但是忘记了原因,它导致了这个问题。删除该配置后,响应变得正常403。

@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler({ AccessDeniedException.class })
    public ResponseEntity<Object> handleAccessDeniedException(Exception ex, WebRequest request) {
        return new ResponseEntity<Object>(
            ex.getLocalizedMessage(),
            new HttpHeaders(),
            HttpStatus.FORBIDDEN.ordinal());
    }
...
}
r3i60tvu

r3i60tvu1#

HttpStatus是一个枚举,而您使用的是HttpStatus.FORBIDDEN.ordinal()。Enum中的ordinal方法返回枚举声明中的位置。删除ordinal(),它应该可以工作。
下面您可以看到HttpStatus枚举中的代码,它是枚举声明中的第26项。

相关问题