Oaut2RestTemplate with client_credentials error (anonymous not allowed)

java, spring, spring-boot, spring-oauth2, spring-security

Solution

I had the same problem and concluded that the `AccessTokenProvider` interface, which has multiple implementors is the culprit. By default, the `OAuth2RestTemplate` instantiates the `AccessTokenProviderChain` which tries to re-use the existing login context. However, if no such login exists, this is bound to fail. Try

restTemplate.setAccessTokenProvider(new ResourceOwnerPasswordAccessTokenProvider());

in your factory method. This uses a token provider which owns its credentials and doesn't reference the thread local `SecurityContextHolder` in its implementation at all.

Problem

I'm trying to access a web service which is protected by Spring Security using `ResourceServerConfigurerAdapter` (with Oauth2 `client_credentials`) Following is the security configuration ``` //Micoservice 1 @Configuration @EnableResourceServer class ResourceServerConfiguration extends ResourceServerConfigurerAdapter { @Autowired private Environment env; @Autowired private DummyUserFilter dummyUserFilter; @Override public void configure(HttpSecurity http) throws Exception { http.addFilterAfter(dummyUserFilter, LogoutFilter.class) .formLogin().disable() .httpBasic().disable() .csrf().disable() .antMatcher("/**") .authorizeRequests() .antMatchers("/js/**", "/webjars/**").permitAll() .anyRequest() .authenticated(); } } ``` This application (Microservice 1) is to be accessed by another application (Microservice 2) with the `Oauth2RestTemplate`. Following is the `Oauth2RestTemplate` configuration. ``` //MicroService 2 @Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate() { ClientCredentialsResourceDetails resourceDetails = new ClientCredentialsResourceDetails(); resourceDetails.setAccessTokenUri("https://<UAA>/oauth/token"); resourceDetails.setClientId("#####"); resourceDetails.setClientSecret("#####"); resourceDetails.setGrantType("client_credentials"); resourceDetails.setTokenName("access_token"); DefaultOAuth2ClientContext clientContext = new DefaultOAuth2ClientContext(); OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resourceDetails, clientContext); return restTemplate; } } ``` `Microservice 2` has various web services which use RestTemplate to access the protected web services of `Microservice 1`. This always results in following exception Authentication is required to obtain an access token (anonymous not allowed) I have searched for this error and found that it's thrown in `AccessTokenProviderChain` Here's the link from github for the relevant code https://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/AccessTokenProviderChain.java#L89 ``` if (auth instanceof AnonymousAuthenticationToken) { if (!resource.isClientOnly()) { throw new InsufficientAuthenticationException( "Authentication is required to obtain an access token (anonymous not allowed)"); } } ``` It seems that it doesn't allow anonymous user to get access to the Oauth2 token. I have no intention of protecting the client application (Microservice 2) with Oauth2 and I must use `client_credentials` for the `Oauth2RestTemplate`, that's preconfigured. How can I stop Spring from blocking anonymous user from accessing token ? I have already tried to populate `SecurityContextHolder` with dummy authentication in case of anonymouse user, with no success. Even if I do succeed in doing so, it seems like a hack.

Original source