本文介绍了Spring Security - @PreAuthorize 返回 404的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用 Spring Method Security 时遇到了一个奇怪的问题,@PreAuthorize("hasRole('MODERATOR')")

I"m currently having a strange issue when I use Spring Method Security, @PreAuthorize("hasRole('MODERATOR')")

如果用户尝试访问需要MODERATOR"角色的控制器,则返回资源,一切正常(如果用户实际上具有该角色).但是,如果用户没有此角色,则服务器返回 404 - Not Found.这很奇怪,因为我预计服务器会返回其他内容,也许是 403 Forbidden?知道为什么会发生这种情况吗?这是我的安全配置:

If the user tries to access a controller, which requires the role of "MODERATOR", then the resource is returned, and everything is fine (if the user, in fact, has that role). However, if the user does not have this role, the server returns 404 - Not Found. This is odd, since I expect the server would have returned something else, perhaps 403 Forbidden? Any idea why this would happen? Here is my Security Configuration:

@EnableWebSecurity
@Order(2)
public class WebSecurity extends WebSecurityConfigurerAdapter {

    private final UserDetailsService userDetailsService;
    private final BCryptPasswordEncoder bCryptPasswordEncoder;

    public WebSecurity(UserDetailsService userDetailsService, BCryptPasswordEncoder bCryptPasswordEncoder) {
        super();
        this.userDetailsService = userDetailsService;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .antMatcher("/api/**")
                .cors()
                .and()
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("/**").permitAll()
                .anyRequest().authenticated()
                .and()
                .addFilter(new JWTAuthenticationFilter(authenticationManager()))
                .addFilter(new JWTAuthorizationFilter(authenticationManager()))
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
    }

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.applyPermitDefaultValues();
        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

}

和我的控制器:

@GetMapping
@PreAuthorize("hasRole('MODERATOR')")
public List<ApplicationUser> getAllUsers(HttpServletRequest request) {
    try (final ConnectionResource connectionResource = connectionFactory.create(); final UserDAO dao = new UserDAO()) {
        dao.setEm(connectionResource.em);
        return dao.getAllUsers();
    } catch (Exception ex) {
        Logger.getLogger(UserController.class.getName()).log(Level.SEVERE, "unable to get all users", ex);
        return null;
    }
}

谢谢!

推荐答案

全局方法安全可以在注解 @EnableGlobalMethodSecurity(prePostEnabled=true) 的帮助下启用.这个和 @Preauthorize 的组合将为您的控制器创建一个新的代理,它会丢失请求映射(在您的情况下为 GetMapping),这将导致 404 异常.

Global method security can be enabled with the help of annotation @EnableGlobalMethodSecurity(prePostEnabled=true) . The combination of this and @Preauthorize will create a new proxy for your controller and it will loose the Request mapping (GetMapping in your case) which will result in 404 Exception.

要处理此问题,您可以使用 @EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)

To handle this you can use @EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)

注释控制器Spring 文档

一个相关的 Github 问题

这篇关于Spring Security - @PreAuthorize 返回 404的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 07:03