[英]How to get oauth2 access token in a spring boot application (not a web application) using spring security 5
I need to get access token (grant_type = client_credentials) in the service layer of my spring boot application to talk to other microservice (service to service interaction).我需要在 Spring Boot 应用程序的服务层中获取访问令牌(grant_type = client_credentials)才能与其他微服务(服务到服务交互)对话。 There is no spring http session or auth at this layer, I just have client_id, client_secret and token url.
在这一层没有 spring http session 或 auth,我只有 client_id、client_secret 和 token url。 These properties are set in application.properties as:
这些属性在 application.properties 中设置为:
spring.security.oauth2.client.registration.auth1.client-id=***
spring.security.oauth2.client.registration.auth1.client-secret=***
spring.security.oauth2.client.registration.auth1.authorization-grant-type=client_credentials
spring.security.oauth2.client.provider.auth1.tokenUri=***
This seemed simple with Spring Security OAuth, but can't figure out with Spring security.这对于 Spring Security OAuth 来说似乎很简单,但在 Spring security 中却无法解决。 Referred the documents for spring security 5, but everything seems to be in context of web interface.
参考了 spring security 5 的文档,但一切似乎都在 Web 界面的上下文中。 I understand I could just make http call to get the token with the info I have, but I wanted to utilize the framework...
我知道我可以通过 http 调用来获取带有我所拥有信息的令牌,但我想利用该框架...
Scenario: Lets call this spring boot app service A. There are other services which might call A to process updates on http or send kafka message on a topic which A listens to.场景:让我们调用这个 Spring Boot 应用程序服务 A。还有其他服务可能会调用 A 来处理 http 上的更新或发送关于 A 侦听的主题的 kafka 消息。 When A processes the update/message, it needs to send some data to service B which requires access token for authz.
当 A 处理更新/消息时,它需要向服务 B 发送一些数据,这需要用于 authz 的访问令牌。 This is where I need the access token.
这是我需要访问令牌的地方。 So the interaction is essentially service-service and is not specific to user.
所以交互本质上是服务-服务,并不特定于用户。
When not in the context of a web interface, you'll want to look at the service layer.如果不在 Web 界面的上下文中,您将需要查看服务层。
From Spring Security's Javadocs for AuthorizedClientServiceOAuth2AuthorizedClientManager
:从 Spring Security 的
AuthorizedClientServiceOAuth2AuthorizedClientManager
的 Javadocs :
An implementation of an {@link OAuth2AuthorizedClientManager} that is capable of operating outside of a {@code HttpServletRequest} context, eg in a scheduled/background thread and/or in the service-tier.
{@link OAuth2AuthorizedClientManager} 的实现,能够在 {@code HttpServletRequest} 上下文之外运行,例如在调度/后台线程和/或服务层中。
Here's a @Bean
definition that may help, which I'll explain below:这是一个可能有帮助的
@Bean
定义,我将在下面解释:
@Bean
OAuth2AuthorizedClientManager authorizedClientManager
(ClientRegistrationRepository clients) {
OAuth2AuthorizedClientService service =
new InMemoryOAuth2AuthorizedClientService(clients);
AuthorizedClientServiceOAuth2AuthorizedClientManager manager =
new AuthorizedClientServiceOAuth2AuthorizedClientManager(clients, service);
OAuth2AuthorizedClientProvider authorizedClientProvider =
OAuth2AuthorizedClientProviderBuilder.builder()
.clientCredentials()
.build();
manager.setAuthorizedClientProvider(authorizedClientProvider);
return manager;
}
An OAuth2AuthorizedClientManager
manages authorizing OAuth 2.0 client definitions. OAuth2AuthorizedClientManager
管理授权 OAuth 2.0 客户端定义。 These definitions are stored in a ClientRegistrationRepository
, and a default instance of ClientRegistrationRepository
is created by Spring Boot via the properties you've already got defined.这些定义存储在一个
ClientRegistrationRepository
,和的默认实例ClientRegistrationRepository
通过你已经有了定义的属性是由Spring启动创建。
The manager typically needs two things to function:经理通常需要两件事才能发挥作用:
The first is an OAuth2AuthorizedClientService
, which is handy if you are wanting to store tokens in a database - in Spring Security 5.2, the only implementation is an in-memory one;第一个是
OAuth2AuthorizedClientService
,如果您想将令牌存储在数据库中,它会很方便 - 在 Spring Security 5.2 中,唯一的实现是内存中的; however, it appears that 5.3 will ship with a JDBC implementation .但是,似乎 5.3 将附带JDBC 实现。
The second is an OAuth2AuthorizedClientProvider
, which is what actually performs the token requests, like the client credentials one you want to make.第二个是
OAuth2AuthorizedClientProvider
,它实际执行令牌请求,就像您想要制作的客户端凭据一样。
With this manager created, you can wire it into your web client:创建此管理器后,您可以将其连接到您的 Web 客户端:
@Bean
WebClient webClient(OAuth2AuthorizedClientManager authorizedClientManager) {
ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2 =
new ServletOAuth2AuthorizedClientExchangeFilterFunction
(authorizedClientManager);
oauth2.setDefaultClientRegistrationId("auth1");
return WebClient.builder()
.apply(oauth2.oauth2Configuration())
.build();
}
The exchange filter function used above is the thing that adds the bearer token to the Authorization
header.上面使用的交换过滤器功能是将承载令牌添加到
Authorization
标头的东西。 It calls the manager to ask it for a token, the manager pulls it from the service.它调用管理器向其请求令牌,管理器将其从服务中拉出。 If it's expired, the manager asks the provider to refresh it.
如果它已过期,管理器会要求提供者刷新它。 Now, with a fresh token, the manager hands it back to the filter to get it added into the request.
现在,有了新的令牌,管理器将其交还给过滤器以将其添加到请求中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.