Spring security 桌面OIDC Spring应用程序安全性:使用初始令牌配置客户端
我们有一个JavaSpring桌面应用程序,我们现在正在将其迁移到一个OIDC安全性中(目前使用KeyClope)。 为此,我们在Java应用程序中集成了一个浏览器,以运行身份验证并获取所提供的令牌集(访问、刷新、id) 现在,我们希望将这些令牌与Spring安全性集成,以便我们可以在WebClient(调用服务器)上使用过滤器,并且Spring可以处理访问令牌刷新过程 我们正在努力找到实现这一目标的最佳途径 到目前为止,我们有一个解析访问和刷新令牌以生成授权客户端的解决方案。在这种情况下,我们将创建AuthorizedClientProvider,如下所示:Spring security 桌面OIDC Spring应用程序安全性:使用初始令牌配置客户端,spring-security,Spring Security,我们有一个JavaSpring桌面应用程序,我们现在正在将其迁移到一个OIDC安全性中(目前使用KeyClope)。 为此,我们在Java应用程序中集成了一个浏览器,以运行身份验证并获取所提供的令牌集(访问、刷新、id) 现在,我们希望将这些令牌与Spring安全性集成,以便我们可以在WebClient(调用服务器)上使用过滤器,并且Spring可以处理访问令牌刷新过程 我们正在努力找到实现这一目标的最佳途径 到目前为止,我们有一个解析访问和刷新令牌以生成授权客户端的解决方案。在这种情况下,我们
var authorizedClientProvider = ReactiveOAuth2AuthorizedClientProviderBuilder.builder()
.refreshToken()
.provider(context -> {
if (context.getAuthorizedClient() != null) {
return Mono.empty();
}
ObjectMapper objMapper = new ObjectMapper();
TypeReference<Map<String, Object>> type = new TypeReference<Map<String, Object>>() {//
};
Map<String, Object> jsonMap = null;
try {
jsonMap = objMapper.readValue(accessTokenValue, type);
}
catch (JsonProcessingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
AccessTokenResponse parsedAccessToken = null;
try {
parsedAccessToken = (AccessTokenResponse) TokenResponse.parse(new JSONObject(jsonMap));
}
catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
OAuth2AccessTokenResponse accessTokenResponse = oauth2AccessTokenResponse(parsedAccessToken);
return Mono.just(
new OAuth2AuthorizedClient(
context.getClientRegistration(),
context.getPrincipal().getName(),
accessTokenResponse.getAccessToken(),
accessTokenResponse.getRefreshToken()));
})
.build();
因此,尽管这种方法允许我们维护访问令牌(并刷新它),但它不允许我们使用这些令牌(在全局策略上)为应用程序创建身份验证。我希望能够使用ID令牌以某种方式生成它
我们已经看到,Spring在登录流(我们不使用)接收令牌时在内部创建了OAuth2AuthorizationCodeAuthenticationToken。
这看起来像是我们应该创建的身份验证对象,但它需要包含我们在用例中没有的消息交换信息。
然后我们可以看到,这个交换对象在Spring安全代码的更多地方使用,所以我们不能忽略它
我们还看到,在InMemoryReactivioAuth2AuthorizedClient服务中,我们有一个将OAuth2AuthorizedClient与身份验证对象关联的方法。
但我们不确定这是否是一条道路,或者究竟需要做些什么
我们是否应该使用适当的身份验证对象来保持对应用程序上令牌(ec:ID令牌)的引用
有人知道如何配置/提供此功能以使此集成浏览器解决方案正常工作吗
提前感谢您的帮助
问候
João只是提醒一下,反应式OAuth 2.0客户机文档已经过时,并且缺少信息。我建议查看完整的Servlet文档。对于服务帐户(客户端证书授予),这里是Servlet文档。注意:为客户端\u凭据授权配置的客户端将不会收到刷新令牌(根据规范不允许)。但是,当访问令牌过期时,客户端将通过获取新的访问令牌来自动“续订”过期的访问令牌。您好,我已经阅读了文档,但在任何地方都没有提到在外部(集成浏览器)执行授权码时该怎么办,我们只有令牌。在12.2.4中提到setDefaultOAuth2AuthorizedClient(true),它将使用现有的OAuth2AuthenticationToken。有没有关于如何手动创建它而不是运行HttpSecurity.oauth2Login()的文档?如果缺省值不为true,那么在更新2中,我们将描述如何从检索到的令牌创建初始AuthorizedClient并维护refreshToken。不确定这是不是一个正确的方法。我不知道你所说的“当授权代码在外部(集成浏览器)执行时,我们只有令牌”是什么意思?这对我来说没有意义?另外,我也不清楚“是否有关于如何手动创建它而不是运行HttpSecurity.oauth2Login()的文档?”。手动创建什么?我很困惑,因为您最初的评论提到了服务帐户,即
client\u-credentials
grant和HttpSecurity。oauth2Login()
是使用authorization\u-code
grant实现的。因此,我尝试用当前的知识重新表述整个问题,并将重点放在开放点上@JoeGrandja,请检查第一句。我们在这个桌面应用程序上有一个集成的浏览器,它执行授权代码流并提供令牌。因此,我们试图了解如何将这些令牌与Spring安全性集成。目前,我们已经解决了如何联系服务器(并保持令牌刷新),但没有解决如何在桌面Spring应用程序中拥有全局身份验证对象。希望这能澄清整个问题。您可以通过GitHub存储库整理一个最小的示例->,这样我就可以看到您的内容了。这将是帮助您完成下一步工作的最有效方法。请注意,反应式OAuth 2.0客户端文档已经过时,并且缺少信息。我建议查看完整的Servlet文档。对于服务帐户(客户端证书授予),这里是Servlet文档。注意:为客户端\u凭据授权配置的客户端将不会收到刷新令牌(根据规范不允许)。但是,当访问令牌过期时,客户端将通过获取新的访问令牌来自动“续订”过期的访问令牌。您好,我已经阅读了文档,但在任何地方都没有提到在外部(集成浏览器)执行授权码时该怎么办,我们只有令牌。在12.2.4中提到setDefaultOAuth2AuthorizedClient(true),它将使用现有的OAuth2AuthenticationToken。有没有关于如何手动创建它而不是运行HttpSecurity.oauth2Login()的文档?如果缺省值不为true,那么在更新2中,我们将描述如何从检索到的令牌创建初始AuthorizedClient并维护refreshToken。不确定这是不是一个正确的方法。我不知道你所说的“当授权代码在外部(集成浏览器)执行时,我们只有令牌”是什么意思?这对我来说没有意义?另外,我也不清楚“是否有关于如何手动创建它而不是运行HttpSecurity.oauth2Login()的文档?”。手动创建什么?我很困惑,因为您最初的评论提到了服务帐户,它是客户\ u凭证
授权和Http
String baseUrl = theOpts.getAuthServiceBaseUrl();
if (baseUrl == null) {
baseUrl = theOpts.getAuthServiceIssuerUrl();
}
clientRegistration = ClientRegistration.withRegistrationId(AUTHSERVICE_REGISTRATION_ID)
.userNameAttributeName(IdTokenClaimNames.SUB)
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
.clientAuthenticationMethod(ClientAuthenticationMethod.POST)
.clientId("myClientId")
.jwkSetUri(theAuthServiceIssuerUrl + OIDC_CERTS_ENDPOINT)
.tokenUri(theAuthServiceIssuerUrl + OIDC_TOKEN_ENDPOINT)
.build();
ReactiveClientRegistrationRepository inMemoryReactiveClientRegistrationRepository = new InMemoryReactiveClientRegistrationRepository(clientRegistration);
ReactiveOAuth2AuthorizedClientService authorizedClientService = new InMemoryReactiveOAuth2AuthorizedClientService(inMemoryReactiveClientRegistrationRepository);
AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager authorizedClientManager = new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(
inMemoryReactiveClientRegistrationRepository,
authorizedClientService);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
ServerOAuth2AuthorizedClientExchangeFilterFunction oauthFilter = new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
oauthFilter.setDefaultOAuth2AuthorizedClient(true);
oauthFilter.setDefaultClientRegistrationId(AUTHSERVICE_REGISTRATION_ID);
return oauthFilter;