Spring Security<5.2版本下如何按请求URL配置授权服务器多认证管理器
Spring Security <5.2 密码授权模式多AuthenticationManager适配方案
由于版本限制无法使用AuthenticationManagerResolver,可通过自定义全局AuthenticationManager代理类的方式实现路径匹配路由到不同认证逻辑,具体实现步骤如下:
核心实现思路
框架仅支持配置1个全局密码授权AuthenticationManager,我们可以将这个全局实例替换为自定义代理类,内部自行根据当前请求路径匹配对应真实的认证处理器,实现无版本升级的逻辑路由。
步骤1:实现代理AuthenticationManager
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.util.AntPathMatcher; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; public class DelegatingPasswordGrantAuthManager implements AuthenticationManager { private final AntPathMatcher pathMatcher = new AntPathMatcher(); private final AuthenticationManager adminAuthManager; private final AuthenticationManager normalAuthManager; // 可根据业务需求扩展更多匹配规则 private static final String ADMIN_PATH_PATTERN = "/admin/**"; public DelegatingPasswordGrantAuthManager(AuthenticationManager adminAuthManager, AuthenticationManager normalAuthManager) { this.adminAuthManager = adminAuthManager; this.normalAuthManager = normalAuthManager; } @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); if (attributes == null) { throw new BadCredentialsException("无可用请求上下文"); } HttpServletRequest request = attributes.getRequest(); // 存在context-path配置时可改用request.getServletPath()获取匹配路径 String requestUri = request.getRequestURI(); if (pathMatcher.match(ADMIN_PATH_PATTERN, requestUri)) { return adminAuthManager.authenticate(authentication); } return normalAuthManager.authenticate(authentication); } }
步骤2:替换授权服务器全局认证管理器
在你原有继承AuthorizationServerConfigurerAdapter的配置类中,将全局AuthenticationManager替换为上述代理类即可:
@Configuration @EnableAuthorizationServer public class CustomAuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { // 注入自行实现的管理端认证逻辑处理器 @Autowired @Qualifier("adminAuthenticationManager") private AuthenticationManager adminAuthManager; // 注入自行实现的普通端认证逻辑处理器 @Autowired @Qualifier("normalAuthenticationManager") private AuthenticationManager normalAuthManager; @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { // 构造代理类作为全局密码授权认证管理器 DelegatingPasswordGrantAuthManager delegatingAuthManager = new DelegatingPasswordGrantAuthManager(adminAuthManager, normalAuthManager); endpoints.authenticationManager(delegatingAuthManager); // 其余原有端点配置保持不变 } // 其余原有配置保持不变 }
注意事项
- 若认证逻辑运行在异步线程中,需提前将
RequestContextHolder的请求上下文透传到子线程,避免获取请求对象为空 - 若需要扩展更多路径匹配规则,仅需修改代理类的匹配逻辑,无需调整授权服务器核心配置
备选方案(逻辑完全隔离场景)
如果两类路径的授权逻辑完全独立,可拆分配置两个独立的AuthorizationServer实例,分别绑定不同的路径前缀和AuthenticationManager,该方案改造成本高于代理类方案,适合隔离要求高的场景。
内容的提问来源于stack exchange,提问作者somename
相关产品推荐
相关产品推荐

