如何让所有@RequestMapping默认应用@PreAuthorize("isAuthenticated()")权限控制?
解决方案:Spring Security 全局默认认证 + 方法级注解覆盖
要实现所有接口默认需要认证,仅方法级显式注解可覆盖的最小权限原则,核心是让方法级安全规则接管全局权限判断,同时为无注解方法添加默认认证要求。以下是可行方案:
1. 配置SecurityFilterChain,放开URL级全局认证
首先需要关闭URL级的强制认证规则,避免其优先级高于方法级注解:
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth.anyRequest().permitAll()) // 权限判断交给方法级安全处理 // 根据实际认证方式调整,比如JWT、OAuth2等 .formLogin(withDefaults()) .httpBasic(withDefaults()); return http.build(); }
2. 自定义方法安全元数据,添加默认认证规则
通过重写MethodSecurityMetadataSource,为没有安全注解的方法自动添加isAuthenticated()规则,同时保留注解的优先级:
@Configuration @EnableMethodSecurity // Spring Security 6.x 用此注解;5.x 替换为 @EnableGlobalMethodSecurity(prePostEnabled = true) public class CustomMethodSecurityConfig extends GlobalMethodSecurityConfiguration { @Override protected MethodSecurityMetadataSource customMethodSecurityMetadataSource() { return new DefaultMethodSecurityMetadataSource() { @Override public Collection<ConfigAttribute> getAttributes(Method method, Class<?> targetClass) { // 先获取方法/类上的显式安全注解配置 Collection<ConfigAttribute> attributes = super.getAttributes(method, targetClass); // 如果没有任何安全注解(@PreAuthorize、@PermitAll、@PostAuthorize等),添加默认认证要求 if (attributes == null || attributes.isEmpty()) { return SecurityConfig.createList("isAuthenticated()"); } // 有注解则直接使用注解配置 return attributes; } }; } }
验证场景
- 无注解的Controller方法:自动触发
isAuthenticated()校验,未登录访问返回401 - 标注@PermitAll的方法:允许匿名访问,直接跳过认证
- 标注@PreAuthorize("hasRole('ADMIN')")的方法:仅拥有ADMIN角色的用户可访问,覆盖默认规则
注意事项
- 确保项目已启用方法级安全:Spring Security 6.x用
@EnableMethodSecurity,5.x用@EnableGlobalMethodSecurity(prePostEnabled = true) - 认证方式可根据业务需求替换示例中的
formLogin/httpBasic(比如JWT过滤器、OAuth2资源服务器配置) - 若需排除静态资源等特定路径,可在SecurityFilterChain中单独配置
requestMatchers("/static/**").permitAll(),不影响接口的默认认证规则
内容的提问来源于stack exchange,提问作者CidTori
相关产品推荐
相关产品推荐

