Spring Boot如何实现仅允许方法级注解授权的请求?
解决方案
要实现「强制所有请求必须通过方法级注解授权,否则拒绝」的需求,核心是让方法级安全校验优先于全局Http规则,同时设置默认拒绝未注解的方法,具体步骤如下:
1. 开启方法级安全并设置默认拒绝规则
在你的Security配置类上添加@EnableMethodSecurity注解,通过配置默认规则,让所有未显式添加安全注解的方法默认被拒绝:
@Configuration @EnableMethodSecurity( prePostEnabled = true, defaultMethodSecurity = @MethodSecurity( // 默认拒绝所有未加注解的方法 preAuthorize = "denyAll()" ) ) public class SecurityConfig { private final BamRequestFilter bamRequestFilter; public SecurityConfig(BamRequestFilter bamRequestFilter) { this.bamRequestFilter = bamRequestFilter; } // 后续SecurityFilterChain配置写在这里 }
2. 修改SecurityFilterChain全局规则
把原来的.anyRequest().denyAll()改成.anyRequest().authenticated(),这样既确保所有请求(除了/login)都需要先通过认证,又不会提前拦截掉需要执行方法级注解校验的请求:
@Bean public SecurityFilterChain configure(final HttpSecurity http) throws Exception { return http.cors(withDefaults()) .csrf(AbstractHttpConfigurer::disable) .authorizeHttpRequests(auth -> auth .antMatchers("/login").permitAll() // 先要求所有请求必须认证,后续交给方法级注解控制权限 .anyRequest().authenticated() ) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .addFilterBefore(bamRequestFilter, UsernamePasswordAuthenticationFilter.class) .build(); }
3. 控制器方法的显式授权
只有添加了@PreAuthorize(或@PostAuthorize)注解的方法才会被允许访问,未添加注解的方法会触发默认的denyAll()规则:
@PutMapping(path = "/getInfo") @PreAuthorize("hasAnyAuthority('GET')") public ActionResult getInfo(@RequestBody Map<String, String> input) { return service.getInfo(input); } // 未加注解的方法会被拒绝访问 @GetMapping("/unprotected") public String unprotected() { return "这个请求会被拒绝"; }
原理说明
- 原来的
.anyRequest().denyAll()会在方法级注解校验之前就拒绝所有请求,导致带注解的方法也无法执行; - 改成
.anyRequest().authenticated()后,先确保用户已登录,然后由@EnableMethodSecurity配置的默认规则接管未注解方法的权限控制; - 显式添加
@PreAuthorize的方法会覆盖默认规则,按照注解内的表达式进行权限校验。
内容的提问来源于stack exchange,提问作者Leos Literak
相关产品推荐
相关产品推荐

