我有两个资源服务器:一个具有用于通过电子邮件发送通知的API,另一个用于运行计划任务。当计划任务开始时,我想呼叫电子邮件服务以通知用户他们的任务正在启动。两种服务都使用OAuth2进行身份验证。计划任务服务已设置客户端凭据,以便通过提供客户端凭据来获取访问令牌:
为了实现这一点,我使用Spring Boot和Spring Security OAuth2。任务服务有一个OAuth2RestTemplate来调用电子邮件服务。当计划任务启动并尝试使用OAuth2RestTemplate时,它会尝试将OAuth2ClientContext作为sesson范围的bean。显然,它不会找到一个,因为我没有在请求线程中执行,我正在后台任务线程中运行。我得到了这个例外:
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
由于我使用静态客户端凭据进行系统到系统身份验证,因此我认为没有充分的理由使用会话范围的数据来处理我的访问令牌。我希望有一个单独的OAuth2ClientContext bean,任何线程都可以使用它来通过OAuth2RestTemplate发出请求。
我该如何配置?
答案 0 :(得分:6)
事实证明这很简单。我想要一个单例bean,所以我创建了一个单例bean:
@Primary
@Bean
public OAuth2ClientContext singletonClientContext() {
return new DefaultOAuth2ClientContext();
}
在我的@Configuration类中,Spring将它连接到我的OAuth2RestTemplate,我的计划任务能够调出电子邮件服务。为了更好的衡量,我添加了@Primary注释,以确保这个bean比Spring Boot创建的任何东西更受欢迎(不确定是否需要)。