Reputation: 2634
Spring Boot, Security OAuth2 implementation, default token endpoint (/oauht/token) is working fine. However, when I send a request to new endpoint at /oauth/http/token it is throws Bad Credentials because of the following reason:
FilterChainProxy
triggers around 12 filters and out of which one is BasicAuthenticationFilter
. It uses UserDetailsService
of DaoAuthenticationProvider
class to fetch user data. For client authentication this should be ClientDetailsService
but, for some reason this is always UserDetailsService
and because of this client credentials goes to UserRepository
and fails. This class does initialize properly because default /oauth/token
works fine.
I tried to inject existing Authentication Manager in BasicAuthenticationFilter
and added that as a filter in ResourceServerConfigurerAdapter
but that didn’t make any difference. It does change Authentication Manager provider from AnonymousAuthenticationProvider
to DaoAuthenticationProvider
but UserDetailsService
still remains UserDetails
.
Request at /oauth/http/token
, this doesn't work. Code is almost same as postAccessToken()
of org.springframework.security.oauth2.provider.endpoint.TokenEndpoint
In above screenshot we can see that userDetailsService is UserDetailsServiceImpl and due to this client details present in request header as Basic dGVzdDpwYXNzd29yZA==
is going to user repository and checking at user table instead of going to client repository and checking at client table.
Request at /oauth/token
, this works
Upvotes: 3
Views: 2061
Reputation: 12021
FilterChainProxy
maintains not a single filter chain but a list of SecurityFilterChain
-s.Each security filter chain contains a request matcher and a list of filters. So you will have several instances of BasicAuthenticationFilter
in these different chains.
Which filter chain will be triggered depends on the incoming request and the decisions of the request matchers.
/oauth/token
triggers the chain which is created by spring oauth and uses ClientDetailsService
at the end.
/oauth/http/token
triggers another chain created by your web security configuration and uses user details service.
So... that is the reason. To see how the chains are created on startup you may enable the security debug, e.g. in application.yml
logging:
level:
org.springframework.security: DEBUG
Then you will see the oauth security chain creation:
Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/oauth/token'], Ant [pattern='/oauth/token_key'], Ant [pattern='/oauth/check_token']]], [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@4ce4e309, org.springframework.security.web.context.SecurityContextPersistenceFilter@16331720, org.springframework.security.web.header.HeaderWriterFilter@60ef29a5, org.springframework.security.web.authentication.logout.LogoutFilter@4c9638cc, org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter@9eefda5, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@16d090e9, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@484a9950, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@1c4fefe8, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@12082780, org.springframework.security.web.session.SessionManagementFilter@20a49b7b, org.springframework.security.web.access.ExceptionTranslationFilter@24313d10, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@47ce08d2]
Note the request matchers.
UPDATE: If you want to 'remap' the endpoint to your own endpoint you may reconfigure that.
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.pathMapping("/oauth/token", "/oauth/http/token");
}
Upvotes: 2