我已经实现了一个资源服务器来验证令牌并允许访问受保护的资源。当我实现ResourceServerConfig
类并运行它时,发生了以下错误
Method springSecurityFilterChain in org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration required a single bean, but 2 were found:
- tokenServices: defined by method 'tokenServices' in class path resource [com/benz/resource/api/config/ResourceServerConfig.class]
- remoteTokenServices: defined by method 'remoteTokenServices' in class path resource [org/springframework/boot/autoconfigure/security/oauth2/resource/ResourceServerTokenServicesConfiguration$RemoteTokenServicesConfiguration$TokenInfoServicesConfiguration.class]
资源服务器配置类
@Configuration
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Value("${security.key.public-key}")
private Resource publicKey;
private TokenStore tokenStore;
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.tokenStore(tokenStore());
}
@Bean
public DefaultTokenServices tokenServices(TokenStore tokenStore)
{
DefaultTokenServices tokenServices=new DefaultTokenServices();
tokenServices.setTokenStore(tokenStore);
return tokenServices;
}
@Bean
public TokenStore tokenStore() throws Exception
{
if(tokenStore==null)
tokenStore=new JwtTokenStore(tokenConverter());
return tokenStore;
}
private JwtAccessTokenConverter tokenConverter() throws Exception
{
JwtAccessTokenConverter converter=new JwtAccessTokenConverter();
converter.setVerifierKey(getPublicKeyAsString());
return converter;
}
private String getPublicKeyAsString() throws Exception
{
return IOUtils.toString(publicKey.getInputStream(),UTF_8);
}
}
但在这种情况下,我不能使用@Primary
或@Qualifier
注释来为特定的bean实例提供优先级。当config类运行时,我需要执行这两个bean实例,如果不使用@Primary
或@Qualifier
注释,我该如何执行?
从错误堆栈中,您似乎正在自动注入RemoteTokenServices
。它用于查询/check_token
端点以获取访问令牌的内容(作用域、权限…等(。此类的自动布线可能是由于使用了security.oauth2.*
属性。可以使用prefer-token-info: false
禁用它。
public class RemoteTokenServices implements ResourceServerTokenServices {}
public class DefaultTokenServices implements AuthorizationServerTokenServices, ResourceServerTokenServices,
ConsumerTokenServices, InitializingBean {}
这两个类都实现了ResourceServerTokenServices
,因此可以使用DefaultTokenServices
而不是RemoteTokenServices
而不会出现问题。请在此处查看ResourceServer
如何处理security.oauth2.*
属性:https://docs.spring.io/spring-security-oauth2-boot/docs/2.0.0.RC2/reference/htmlsingle/#boot-功能-安全-oauth2-资源服务器