我正在开发一个应用程序,允许经过身份验证的用户创建OAuth2 bearer tokens,以便与组织发布的API一起使用。这个想法是允许用户自己生成/撤销这样的令牌,类似于GitHub的Personal API tokens。然后,用户可以使用发布的令牌获得对受保护资源的编程访问。在此配置中,OAuth"客户端","授权服务器"和资源服务器"属于该组织。目前,所有这些服务都在同一个流程中。
为此,我尝试支持Resource Owner Password Credentials Grant类型。实施环境包括以下内容:
实现的一个约束是无法访问存储的密码。此处理委托给执行实际身份验证的内部Web服务。
由于无法访问存储密码的限制,因此无法使用默认配置的DaoAuthenticationProvider
,因为它需要访问由提供商返回的UserDetails
对象提供的密码。 s UserDetailsService
。
我的猜测是我需要用自定义实现替换这个AuthenticationProvider
。但是,所有这样做的尝试似乎都没有生效。
以下似乎在parent
的{{1}}引用中正确注册,但未在运行时委托(由于AuthenticationManager
优先):
DaoAuthenticationProvider
似乎无论我尝试什么(请参阅下面的参考资料)@Configuration
public class SecurityConfig extends GlobalAuthenticationConfigurerAdapter {
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(new AuthenticationProvider() {
@Override
public boolean supports(Class<?> authentication) {
// For testing this is easier, but should check for UsernamePasswordAuthentication.class
return true;
}
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
// Perform custom logic...
return authentication;
}
});
}
}
在其ProviderManager
方法中调用BasicAuthenticationFilter
时,Authentication authResult = authenticationManager.authenticate(authRequest)
始终会获得以下两个提供商:
doFilter
我认为这可能是[
org.springframework.security.authentication.AnonymousAuthenticationProvider@366815e4,
org.springframework.security.authentication.dao.DaoAuthenticationProvider@5da3e311
]
AuthorizationServerSecurityConfigurer
方法的结果。但是,此类标记为clientCredentialsTokenEndpointFilter
,因此无法自定义。
任何建议或指示都将不胜感激。
我尝试/研究过的事情:
答案 0 :(得分:5)
如果我理解正确,您需要为密码授予中的用户提供自定义身份验证管理器。有一个构建器方法:AuthorizationServerEndpointsConfigurer.authenticationManager(AuthenticationManager)
。以及使用它的一个例子:
@Configuration
@EnableAuthorizationServer
protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
}
...
答案 1 :(得分:1)
正如评论中所提到的,以下代码片段可以自动发送“全局&#39;您必须在AuthenticationManager中以某种方式知道上下文。
摘录:
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
}
仅配置HttpSecurity的特定实例。
我个人更喜欢将bean设置为primary并将中央配置的顺序设置为1以强制此配置优先于其他(自动)配置。
@Order(1)
@Configuration
public class SecurityConfig extends GlobalAuthenticationConfigurerAdapter {
@Bean
@Primary
public AuthenticationProvider authenticationProvider() {
return new AuthenticationProvider() {
@Override
public boolean supports(Class<?> authentication) {
// For testing this is easier, but should check for
// UsernamePasswordAuthentication.class
return true;
}
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
// Perform custom logic...
return authentication;
}
};
}
}