Spring Authorization Server实现自定义authenticationProvider遇403问题咨询
问题根因
你当前返回403的核心原因有三个:
- 未配置Spring Security 5资源服务器的核心处理逻辑,默认过滤器链不会走你自定义的
AuthenticationProvider - 缺少替代原有
tokenExtractor的转换器,没有生成对应类型的待认证对象,请求无法进入认证流程 - 使用了授权服务器侧的
OAuth2AccessTokenAuthenticationToken作为返回值,资源服务器侧不识别该认证类型
解决方案
完整适配后的本地环境配置如下,完全兼容原有业务代码中获取认证信息、读取claim的逻辑,无需调整业务层代码:
@Configuration @EnableWebSecurity @Profile("local") public class ResourceServerConfigurationLocal extends WebSecurityConfigurerAdapter { private static final String LOCAL = "local"; @Value("${id.local.oauth}") private String id; @Value("${clientId.local.oauth}") private Integer clientId; @Override public void configure(HttpSecurity http) throws Exception { http .requestMatchers() .antMatchers("/api/**") .and() .authorizeRequests() .anyRequest() .authenticated() .and() // 配置OAuth2资源服务器,绑定自定义转换器和认证逻辑 .oauth2ResourceServer(oauth2 -> oauth2 .bearerTokenConverter(customBearerTokenConverter()) .authenticationManager(authenticationManager()) ) .authenticationProvider(localAuthenticationProvider()); } // 替代原有tokenExtractor:无论请求是否带token,都生成待认证的令牌对象 private Converter<HttpServletRequest, BearerTokenAuthenticationToken> customBearerTokenConverter() { return request -> new BearerTokenAuthenticationToken(LOCAL); } @Bean public AuthenticationProvider localAuthenticationProvider() { return new AuthenticationProvider() { @Override public Authentication authenticate(Authentication authentication) { log.info("Logged with ID: {}", id); CustomUserDetails userDetails = CustomUserDetails.builder().userId(clientId).build(); // 可根据测试需要自定义权限列表 List<GrantedAuthority> authorities = Collections.emptyList(); // 填充需要的claim,完全兼容原有代码的取值逻辑 Map<String, Object> claims = new HashMap<>(); claims.put("sub", id); claims.put("client_id", clientId.toString()); claims.put("user_details", userDetails); // 返回资源服务器可识别的认证对象 return new BearerTokenAuthentication( new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, LOCAL, Instant.now(), Instant.now().plus(Duration.ofDays(1))), authorities, claims ); } @Override public boolean supports(Class<?> authentication) { return BearerTokenAuthenticationToken.class.isAssignableFrom(authentication); } }; } }
注意事项
如果需要调整返回的认证信息结构,直接修改claims的填充逻辑即可,原有业务代码中从SecurityContext获取认证信息、读取claim的逻辑不需要做任何改动,该配置仅在local环境生效,和生产环境的JWT认证逻辑完全隔离。
内容的提问来源于stack exchange,提问作者Juan Pablo Meza Utreras
相关产品推荐
相关产品推荐

