How can I use an OAuth2RestTemplate in a scheduled task?
Asked Answered
O

1

8

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?

Og answered 18/8, 2016 at 18:41 Comment(1)
I need to do something similar - a Quartz scheduler needs to invoke a job which will access an OAuth2 protected REST service. I cannot use username/password based OAuth2 flow but a client id based flow. Can you share your code? Or help?Redshank
O
8

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).

Og answered 18/8, 2016 at 18:41 Comment(1)
You don't need @Primary. A "normal" bean is enough to switch off Boot's auto-configured equivalent (should it have one).Reptilian

© 2022 - 2024 — McMap. All rights reserved.