Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use an OAuth2RestTemplate in a scheduled task?

I have two resource servers: one that has an API for emailing notifications and one that runs scheduled tasks. When a scheduled task starts, I want to call out to the email service to notify users that their task is starting. Both services use OAuth2 for authentication. The scheduled task service has client credentials set up so that it can get an access token by presenting it's client credentials: Get token


Call service

To accomplish this, I'm using Spring Boot with Spring Security OAuth2. The Task service has an OAuth2RestTemplate to make the call out to the Email service. When the scheduled task fires up and tries to use the OAuth2RestTemplate, it tries to get the OAuth2ClientContext as a sesson-scoped bean. Obviously, it's not going to find one since I'm not executing within a request thread, I'm operating in a background task thread. I get this exception:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 
  'scopedTarget.oauth2ClientContext': Scope 'session' is not active for the current thread; 
  consider defining a scoped proxy for this bean if you intend to refer to it 
  from a singleton

Since I'm using static client credentials for system-to-system authentication, I don't see a good reason to use session-scoped data to handle my access tokens. I would prefer to have a singleton OAuth2ClientContext bean that any thread can use to make requests through an OAuth2RestTemplate.

How can I configure this?

like image 333
RustyTheBoyRobot Avatar asked Aug 18 '16 18:08

RustyTheBoyRobot


1 Answers

It turned out to be pretty simple. I wanted a singleton bean, so I created a singleton bean:

@Primary
@Bean
public OAuth2ClientContext singletonClientContext() {
    return new DefaultOAuth2ClientContext();
}

With that in my @Configuration class, Spring wired it in to my OAuth2RestTemplate and my scheduled tasks were able to call out the Email service. For good measure, I added the @Primary annotation to make sure this bean was preferred over anything that Spring Boot created (not sure if that's required).

like image 200
RustyTheBoyRobot Avatar answered Sep 25 '22 19:09

RustyTheBoyRobot