1

It might sound a bit strange. But i have a situation where my app needs to make an ROPC token request with userdetails to be taken from properties.

The call is triggered when there is a random incoming request, which is anonymous. But in the token request, while reaching AccessTokenProviderChain.class, token request fails.

org.springframework.security.authentication.InsufficientAuthenticationException: Authentication is required to obtain an access token (anonymous not allowed)

On debug, i found it is happening at below line.

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth instanceof AnonymousAuthenticationToken && !resource.isClientOnly()) {
    throw new InsufficientAuthenticationException("Authentication is required to obtain an access token (anonymous not allowed)");
}

I see that AnonymousAuthenticationFilter sets principal as anonymousUser

  • Is this because the incoming request is anonymous and i am trying to make an ROPC token request ?
  • Is it because I have enabled @EnableMongoAuditing.

Is there a way to fix this issue other than creating a custom token request.

Code :

public OAuth2RestTemplate myappROPCRestTemplate() {
    OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(myappPasswordResourceDetails());
    restTemplate.setAccessTokenProvider(getAccessTokenProvider());

    if (proxyEnabled) {
        restTemplate.setRequestFactory(getRequestFactoryWithProxy());
    }

    return restTemplate;
}



private AccessTokenProvider getAccessTokenProvider() {
    ResourceOwnerPasswordAccessTokenProvider resourceOwnerPasswordAccessTokenProvider = new ResourceOwnerPasswordAccessTokenProvider();
    if (proxyEnabled) {
        resourceOwnerPasswordAccessTokenProvider.setRequestFactory(getRequestFactoryWithProxy());
    }
    return new AccessTokenProviderChain(Collections.singletonList(resourceOwnerPasswordAccessTokenProvider));
}

private SimpleClientHttpRequestFactory getRequestFactoryWithProxy() {
    SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
    requestFactory.setOutputStreaming(false);
    Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, Integer.parseInt(proxyPort)));
    requestFactory.setProxy(proxy);
    return requestFactory;
}

private OAuth2ProtectedResourceDetails myappPasswordResourceDetails() {
    ResourceOwnerPasswordResourceDetails resource = new ResourceOwnerPasswordResourceDetails();
    resource.setAccessTokenUri(tokenUrl);
    resource.setClientId(clientId);
    resource.setClientSecret(clientSecret);
    resource.setUsername(username);
    resource.setPassword(password);
    resource.setClientAuthenticationScheme(AuthenticationScheme.form);
    resource.setGrantType("password");
    return resource;
}
Abbin Varghese
  • 2,422
  • 5
  • 28
  • 42
  • My app is exposing a REST endpoint. When that endpoint is triggered, my app internally makes another REST call, which is exposed under ROPC oAuth. In short, my app is the resource owner. – Abbin Varghese Apr 01 '19 at 10:18
  • To add - same ROPC call works fine when it is made from a kafka message consumer. May be I am wrong, but I don't think the issue is with the ROPC call itself, but with the combination of (first) incoming rest call + (second) outgoing rest call – Abbin Varghese Apr 01 '19 at 10:34
  • Could you trace client's access token request with headers? Does the request contains `client_id` and `client_secret` and `username` and `password`? – dur Apr 01 '19 at 11:03
  • The request itself is not created. This exception is thrown at line71 and ROPC token request is triggered in line 96 : `accessToken = this.obtainNewAccessTokenInternal(resource, request);` – Abbin Varghese Apr 01 '19 at 11:29
  • Oh, I thought the code and exception is at server-side. You get this exception on client-side. – dur Apr 01 '19 at 11:51
  • Why do you use an `AccessTokenProviderChain`? Couldn't you use only your custom `AccessTokenProvider `? – dur Apr 01 '19 at 11:53

0 Answers0