spc*_*670 6 spring spring-security oauth-2.0 spring-security-oauth2
我正在尝试使用最新版本的 Spring Security - 5.2 中的密码流对用户进行身份验证。
该文档似乎建议如何做到这一点。
@Bean
public OAuth2AuthorizedClientManager passwordFlowAuthorizedClientManager(
HttpClient httpClient,
ClientRegistrationRepository clientRegistrationRepository,
OAuth2AuthorizedClientRepository authorizedClientRepository) {
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
DefaultPasswordTokenResponseClient c = new DefaultPasswordTokenResponseClient();
RestTemplate client = new RestTemplate(requestFactory);
client.setMessageConverters(Arrays.asList(
new FormHttpMessageConverter(),
new OAuth2AccessTokenResponseHttpMessageConverter()));
client.setErrorHandler(new OAuth2ErrorResponseErrorHandler());
c.setRestOperations(client);
OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
.password(configurer -> configurer.accessTokenResponseClient(c))
.refreshToken()
.build();
DefaultOAuth2AuthorizedClientManager authorizedClientManager =
new DefaultOAuth2AuthorizedClientManager(
clientRegistrationRepository, authorizedClientRepository);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
authorizedClientManager.setContextAttributesMapper(authorizeRequest -> {
Map<String, Object> contextAttributes = new HashMap<>();
String username = authorizeRequest.getAttribute(OAuth2ParameterNames.USERNAME);
String password = authorizeRequest.getAttribute(OAuth2ParameterNames.PASSWORD);
contextAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
return contextAttributes;
});
return authorizedClientManager;
}
Run Code Online (Sandbox Code Playgroud)
我执行请求,可以看到 HTTP 标头中返回的访问令牌,但 SecurityContext 未填充,并且会话用户保持匿名。
String username = "joe";
String password = "joe";
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
ClientRegistration r = clientRegistrationRepository.findByRegistrationId("keycloak");
OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(r.getRegistrationId())
.principal(authentication)
.attributes(attrs -> {
attrs.put(OAuth2ParameterNames.USERNAME, username);
attrs.put(OAuth2ParameterNames.PASSWORD, password);
})
.build();
OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest);
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
在阅读了更多文档后,我认为 Spring Security 5.2 中的 Oauth 2 密码流不受与授权流相同的支持。Spring Security 5.2 为 http 客户端提供了密码流支持,可以缓存授权请求并在令牌过期之前刷新令牌 - 但没有最终用户密码流支持,其中客户端将凭证代理到授权服务器。
当然,完全可以通过获取凭据来对最终用户进行身份验证,实现一个自定义的 AuthenticationProvider,该 AuthenticationProvider 将凭据与授权服务器交换为令牌,并返回持久保存到上下文的 OAuth2AuthenticationToken。
| 归档时间: |
|
| 查看次数: |
3783 次 |
| 最近记录: |