Context
I'm developing an application that allows an authenticated user to create OAuth2 bearer tokens for use with APIs published by the organization. The idea is to allow the user to self generate / revoke such tokens, similar to GitHub's Personal API tokens. The user can then use the issued tokens to gain programmatic access to protected resources. In this configuration, the OAuth "Client", "Authorization Server" and the "Resource Server" belong to the organization. For now, all of these services reside in the same process.
To this end, I'm trying support the Resource Owner Password Credentials Grant type. The implementation environment consists of following:
- Spring Boot
- Spring Security OAuth2
One constraint the implementation has is that is does not have access to the stored password. This processing is delegated to an internal web service which does the actual authentication.
Problem
Because of the constraint of not having access to the stored password, the default configured DaoAuthenticationProvider
cannot be used since it requires access to the password provided by the UserDetails
object returned by the provider's UserDetailsService
.
My guess is that I will need to replace this AuthenticationProvider
with a custom implementation. However, all attempts at doing so seem to not take effect.
The following seemed to register correctly in the parent
reference of the AuthenticationManager
, but is not delegated to at runtime (due the DaoAuthenticationProvider
taking precedence):
@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;
}
});
}
}
It seems no matter what I try (see references below) I always get the following two providers in ProviderManager
when the BasicAuthenticationFilter
invokes Authentication authResult = authenticationManager.authenticate(authRequest)
in its doFilter
method:
[
org.springframework.security.authentication.AnonymousAuthenticationProvider@366815e4,
org.springframework.security.authentication.dao.DaoAuthenticationProvider@5da3e311
]
I believe this may be a consequence of the AuthorizationServerSecurityConfigurer
's clientCredentialsTokenEndpointFilter
method. However, this class is marked final
and therefore cannot be customized.
Any suggestions or pointers would be greatly appreciated.
Resources
Things that I have tried / researched:
- http://projects.spring.io/spring-security-oauth/docs/oauth2.html#toc_7
- http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#howto-change-the-authenticationmanager-and-add-user-accounts
- Spring Security 3.2: @Autowire doesn't work with java configuration and custom AuthenticationProvider in Spring MVC application?
- How To Inject AuthenticationManager using Java Configuration in a Custom Filter
- Custom Authentication provider with Spring Security and Java Config
- https://gist.github.com/SlyDen/9408539 -https://github.com/royclarkson/spring-rest-service-oauth/blob/master/src/main/java/hello/WebSecurityConfiguration.java
- https://github.com/spring-projects/spring-boot/blob/master/spring-boot-samples/spring-boot-sample-web-secure/src/main/java/sample/ui/secure/SampleWebSecureApplication.java
- https://github.com/spring-projects/spring-security-oauth/blob/master/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/OAuth2ServerConfig.java
- https://github.com/spring-projects/spring-security-oauth/blob/6d9de66787cb60249f0de00ffe9075366a803924/tests/annotation/vanilla/src/main/java/demo/Application.java
- https://github.com/spring-projects/spring-security-javaconfig/blob/master/samples/oauth2-sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/SecurityConfiguration.java
BasicAuthenticationFilter
always gets aorg.springframework.security.authentication.dao.DaoAuthenticationProvider
instance - which then fails to find the user supplied via HttpBasic. – demaniak