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

Spring SecurityFilterChain中如何组合authenticated()与非hasAuthority()?

在Spring Security 6中实现已认证且无指定权限的URL访问控制

你可以借助Spring Security提供的AuthorizationManagers.not()方法对AuthorityAuthorizationManager.hasAuthority()的校验结果取反,再结合AuthorizationManagers.allOf()组合已认证校验逻辑,正好对应你需要的「已认证 AND 无指定权限」规则。

修改后的完整代码如下:

@Bean
public SecurityFilterChain filterChain(MvcRequestMatcher.Builder mvc,
                                       HttpSecurity http) throws Exception {

    return http
        .authorizeHttpRequests(authorize -> authorize
            .requestMatchers(mvc.pattern("/secrets/**")).access(
                AuthorizationManagers.allOf(
                    AuthenticatedAuthorizationManager.authenticated(),
                    AuthorizationManagers.not(AuthorityAuthorizationManager.hasAuthority("VERY_NAUGHTY"))
                )
            )
            .anyRequest().denyAll())
        .build();
}

逻辑说明

  • AuthorizationManagers.not():将传入的权限校验器结果取反,对应SpEL表达式里的!hasAuthority('VERY_NAUGHTY')
  • AuthorizationManagers.allOf():要求所有传入的校验器都通过,等价于逻辑「AND」,确保用户同时满足「已认证」和「不具备VERY_NAUGHTY权限」两个条件

如果你需要更灵活的自定义逻辑,也可以通过Lambda表达式手动实现校验逻辑:

@Bean
public SecurityFilterChain filterChain(MvcRequestMatcher.Builder mvc,
                                       HttpSecurity http) throws Exception {

    return http
        .authorizeHttpRequests(authorize -> authorize
            .requestMatchers(mvc.pattern("/secrets/**")).access((authentication, context) -> {
                // 先校验是否已认证
                AuthenticationResult authCheck = AuthenticatedAuthorizationManager.authenticated().check(authentication, context);
                if (authCheck.isDenied()) {
                    return authCheck;
                }
                // 校验是否存在指定权限,存在则拒绝,不存在则允许
                AuthorityAuthorizationManager authorityManager = AuthorityAuthorizationManager.hasAuthority("VERY_NAUGHTY");
                AuthenticationResult authorityCheck = authorityManager.check(authentication, context);
                return authorityCheck.isDenied() ? AuthenticationResult.success() : AuthenticationResult.denied();
            })
            .anyRequest().denyAll())
        .build();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 23:30:04