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
相关产品推荐
相关产品推荐

