You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WebSecurityConfigurerAdapter如何配置无@PreAuthorize方法访问规则

配置方案

不需要自定义AccessDecisionManager,直接调整两层安全校验的规则即可,按以下两步修改:

  • 第一步:开启方法级注解支持
    在你的WebSecurityConfigurerAdapter实现类上添加注解,开启@PreAuthorize注解的解析能力:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) // 核心注解,必须添加
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    // 其余配置保留
}
  • 第二步:修改HttpSecurity拦截规则
    把原有配置里的anyRequest().authenticated()替换为permitAll(),关闭过滤器层面的全局限制:
@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            // 静态资源、登录接口等特殊规则可按原有逻辑写在前面,匹配优先级从上到下
            // .antMatchers("/static/**", "/auth/login").permitAll()
            .anyRequest().permitAll()
        .and()
        // 原有其他配置比如formLogin、csrf、cors规则全部保留即可
        .csrf().disable();
}
实现原理

Spring Security的权限校验是两层独立执行的逻辑:

  1. 第一层是Servlet过滤器链上的URL规则校验,也就是configure(HttpSecurity)中配置的内容,执行时机在请求进入Controller之前。配置anyRequest().permitAll()后,这一层不会对任何请求做认证、权限拦截,所有请求都能顺利到达Controller匹配环节。
  2. 第二层是AOP实现的方法级校验,只要开启了prePostEnabled = true,Spring会在Controller方法实际调用前拦截请求,检查方法上的@PreAuthorize注解:
    • 如果方法标注了@PreAuthorize,就按注解内的SpEL表达式做校验,比如hasAuthority('SOME_ROLE')会校验用户权限,isAuthenticated()会校验用户登录状态,校验不通过直接返回403或跳转登录页
    • 如果方法没有标注任何方法级安全注解,这层校验直接跳过,方法正常执行,正好实现「未标注@PreAuthorize的方法默认放行所有请求」的效果
自定义AccessDecisionManager不生效的原因

全局AccessDecisionManager是服务于第一层过滤器链URL校验的,它执行时Spring还没完成请求到Controller方法的匹配,根本拿不到当前请求对应方法上的注解元数据,自然没法实现「有注解就校验、无注解就放行」的逻辑,强行在这里写判断反而会绕开方法级校验,和需求相悖。

注意事项

配置完成后,所有需要做登录校验、角色权限校验的方法,必须显式添加@PreAuthorize注解——哪怕只是要求登录不需要特殊角色,也要标注@PreAuthorize("isAuthenticated()"),否则会因为默认放行导致未登录用户可访问。如果担心漏加,可以写简单的单元测试,扫描所有Controller的public方法,对没有标注@PreAuthorize、@PermitAll等安全注解的方法做告警,避免权限泄露。

内容的提问来源于stack exchange,提问作者Auryn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 18:39:27