Spring Security 6如何让端点同时支持资源服务器与客户端登录?
Spring Security 6 配置路径支持双认证(会话登录+资源服务器)
你的问题出在多个同路径的授权规则是逻辑与关系,Spring Security会要求请求同时满足hasAuthority("SCOPE_read_actuator")和hasRole("developer"),这显然无法实现两种认证方式二选一的需求。下面是两种简便的实现方案:
方案一:使用SpEL表达式(最简洁)
直接在access()中用SpEL的or逻辑组合两个授权条件,让请求满足其中一个即可通过:
@Bean public SecurityFilterChain authorizeInternal(final HttpSecurity http) throws Exception { http.oauth2Login(withDefaults()) .oauth2ResourceServer(withDefaults()); http.authorizeHttpRequests(req -> req .requestMatchers("/actuator/**") // 满足资源服务器权限 或 登录用户角色即可访问 .access("hasAuthority('SCOPE_read_actuator') or hasRole('developer')") .anyRequest().authenticated() ); return http.build(); }
注意:
hasRole('developer')会自动给角色添加ROLE_前缀,如果你数据库中存储的角色是全大写的ROLE_DEVELOPER,这个表达式依然有效;如果需要直接匹配权限字符串,改用hasAuthority('ROLE_developer')即可。
方案二:使用组合式AuthorizationManager(适合复杂逻辑)
如果你的授权逻辑更复杂,或者需要复用授权规则,可以通过OrAuthorizationManager组合两个独立的授权管理器,实现逻辑或的效果:
@Bean public SecurityFilterChain authorizeInternal(final HttpSecurity http) throws Exception { // 定义资源服务器授权规则 AuthorizationManager<RequestAuthorizationContext> resourceServerAuth = AuthorityAuthorizationManager.hasAuthority("SCOPE_read_actuator"); // 定义登录用户授权规则 AuthorizationManager<RequestAuthorizationContext> userAuth = AuthorityAuthorizationManager.hasRole("developer"); // 组合为"或"逻辑的授权管理器 AuthorizationManager<RequestAuthorizationContext> combinedAuth = new OrAuthorizationManager<>(resourceServerAuth, userAuth); http.oauth2Login(withDefaults()) .oauth2ResourceServer(withDefaults()); http.authorizeHttpRequests(req -> req .requestMatchers("/actuator/**") .access(combinedAuth) .anyRequest().authenticated() ); return http.build(); }
额外注意事项
- 确保
oauth2Login和oauth2ResourceServer的基础配置正确:比如客户端注册信息、JWT解码器(或opaque token配置)都已在application.yml/application.properties中配置完成。 - 如果使用JWT作为资源服务器的认证方式,需要确保令牌中包含
SCOPE_read_actuator这个权限声明。
内容的提问来源于stack exchange,提问作者daniu
相关产品推荐
相关产品推荐

