How to get oauth2 access token in a spring boot application (not a web application) using spring security 5
我需要在我的Spring Boot应用程序的服务层中获取访问令牌(grant_type = client_credentials),以便与其他微服务(服务到服务的交互)进行对话。在这一层上没有spring http会话或auth,我只有client_id,client_secret和令牌url。这些属性在application.properties中设置为:
1 2 3 4 | 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=*** |
对于Spring Security OAuth来说,这似乎很简单,但是对于Spring Security却无法弄清。请参阅有关Spring Security 5的文档,但所有内容似乎都在Web界面的上下文中。我了解我可以通过http调用来获取具有我所拥有信息的令牌,但是我想利用该框架...
场景:
让我们将此称为Spring启动应用服务A。还有其他服务可能会调用A来处理http上的更新或发送有关A侦听的主题的kafka消息。当A处理更新/消息时,它需要向服务B发送一些数据,该服务需要authz的访问令牌。这是我需要访问令牌的地方。因此,交互本质上是服务-服务,并不特定于用户。
如果不在Web界面的上下文中,则需要查看服务层。
来自Spring Security的Javadocs中的
An implementation of an {@link OAuth2AuthorizedClientManager} that is capable of operating outside of a {@code HttpServletRequest} context, e.g. in a scheduled/background thread and/or in the service-tier.
这是一个可能有用的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | @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; } |
经理通常需要执行以下两项操作:
-
第一个是
OAuth2AuthorizedClientService ,如果您想将令牌存储在数据库中,则非常方便-在Spring Security 5.2中,唯一的实现是内存中的实现。但是,似乎5.3将附带JDBC实现。 -
第二个是
OAuth2AuthorizedClientProvider ,它实际上是执行令牌请求的对象,就像您要创建的客户端凭据一样。
创建此管理器后,您可以将其连接到Web客户端:
1 2 3 4 5 6 7 8 9 10 | @Bean WebClient webClient(OAuth2AuthorizedClientManager authorizedClientManager) { ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2 = new ServletOAuth2AuthorizedClientExchangeFilterFunction (authorizedClientManager); oauth2.setDefaultClientRegistrationId("auth1"); return WebClient.builder() .apply(oauth2.oauth2Configuration()) .build(); } |
上面使用的交换过滤器功能是将承载令牌添加到