8

I have a controller that is autowired with many services. These services are HTTP restful calls that retrieve data from various data sources, but these services are protected with OAuth2.0.

I am trying to use Spring Security to implement a client-credentials flow that will allow these services to securely retrieve data from these protected data sources, but am having some difficulty in resolving the OAuth2AuthorizedClient data object at the service layer.

I've been trying to resolve the authorized client via the @RegisteredOAuth2AuthorizedClient annotation:

public void setAuthorizedClient(
      @RegisteredOAuth2AuthorizedClient("azure") OAuth2AuthorizedClient authorizedClient) {

    ClientRegistration clientRegistration =
        this.clientRegistrationRepository.findByRegistrationId("azure");
    System.out.println(clientRegistration);

    OAuth2AccessToken accessToken = authorizedClient.getAccessToken();

    jwtToken = accessToken.getTokenValue();
  }

Is it possible to resolve the OAuth2AuthorizedClient as a Spring bean that can then be injected into another bean?
Or is there a better way of architecting such a system?

Thanks!

Justin Chao
  • 173
  • 1
  • 8
  • The `OAuth2AuthorizedClient` is scoped to the user's session, so it wouldn't typically be autowired as a bean like that. You use that annotation for example in a controller method. You can also take a look at `OAuth2AuthorizedClientRepository`, which can be wired as a bean, e.g. with a setter like you are doing. – jzheaux Sep 12 '19 at 17:59
  • Spring Security 5.2.0 is being released Sep 25 which adds the `OAuth2AuthorizedClientManager` and `OAuth2AuthorizedClientProvider`. These new interfaces and associated implementations will likely meet your requirements. Please see this comment for further details https://github.com/spring-projects/spring-security/issues/6811#issuecomment-528917491 – Joe Grandja Sep 16 '19 at 14:02
  • @justin - Did you find any workaround for this? I also want to get hold of token at service layer . I want to make rest api calls through my grpc imlementation methods – Tarunjeet Singh Salh Feb 08 '22 at 07:30

1 Answers1

1

Bit of an old question but I just solved this for myself so here goes:

You can create a @Component that returns the OAuth2AuthorizedClient for you, and inject that where you need it. Here is an example approach:

  1. Create a provider Component class
  2. Inject the readily available OAuth2AuthorizedClientService bean to your class
  3. Create a method that uses the service in order to return the OAuth2AuthorizedClient
  4. Inject your provider class to your Controller

Example:

@Component
public class OAuth2AuthorizedClientProvider {
  
  @Autowired
  private OAuth2AuthorizedClientService clientService;

  public OAuth2AuthorizedClient getClient() {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    OAuth2AuthenticationToken oauthToken = (OAuth2AuthenticationToken) authentication;
    return clientService.loadAuthorizedClient(oauthToken.getAuthorizedClientRegistrationId(), oauthToken.getName());
  }

and then OAuth2AuthorizedClientProvider is used in a controller like so:

@RestController
public class Endpoint {

  @Autowired
  private final OAuth2AuthorizedClientProvider oauth2AuthorizedClientProvider;

  @GetMapping("/mymethod")
  public String mymethod() {

    return oauth2AuthorizedClientProvider.getClient().getAccessToken();
  }
}
gstoupis
  • 56
  • 1
  • 4