gpt4 book ai didi

spring-boot - 如何使用 Spring boot keycloak 适配器 + spring security 强制更新 oAuth token (访问 token + 刷新 token )?

转载 作者:行者123 更新时间:2023-12-02 02:12:13 27 4
gpt4 key购买 nike

我有一个由 Keycloak 保护的 Multi-Tenancy 应用程序(springboot keycloak 适配器 + spring security)。考虑到该项目的 Multi-Tenancy 性质,我编写了一个运行良好的多客户端连接器。

在官方 Keycloak 文档中,建议(对于 Multi-Tenancy 应用程序)将每个租户建模为一个新领域,但对我来说,在同一领域内拥有多个客户端效果更好。这是由于以下优点:

  • 可以共享客户端范围、组和其他配置
  • 用户不需要在 N 个不同的领域重复
  • SSO 登录在同一领域客户端中完美运行(通过使用不记名服务+CORS)

所以,除了一件事之外,一切正常,我的初始 SSO access_token (然后通过 CORS 在所有仅承载服务之间共享)有点大(它显示了所有资源- 租户 - 及其在每个资源/租户中的角色)。

我想限制 access_token 的大小,方法是使用“范围”将 token 中的角色限制为仅对我登录的租户有意义的角色那时。为此,我手动向身份验证服务器发出请求(在 springboot/spring security 提供的标准功能之外),目的是手动覆盖我的应用程序中存在的任何访问 token ,并使用我的额外生成的新访问 token 请求。

我的"new" token 请求看起来与此类似:

    SimpleKeycloakAccount currentUserAccount = (SimpleKeycloakAccount) auth.getDetails();
String authServerUrl = currentUserAccount.getKeycloakSecurityContext().getDeployment().getAuthServerBaseUrl();
String realm = currentUserAccount.getKeycloakSecurityContext().getDeployment().getRealm();
String resource = currentUserAccount.getKeycloakSecurityContext().getDeployment().getResourceName();
String refreshToken = currentUserAccount.getKeycloakSecurityContext().getRefreshToken();
String token = currentUserAccount.getKeycloakSecurityContext().getTokenString();


Http http = new Http( new Configuration(authServerUrl, realm, resource,
currentUserAccount.getKeycloakSecurityContext().getDeployment().getResourceCredentials()
, null),
(params, headers) -> {});

String url = authServerUrl + "/realms/" + realm + "/protocol/openid-connect/token";

AccessTokenResponse response = http.<AccessTokenResponse>post(url)
.authentication()
.client()
.form()
.param("grant_type", "refresh_token")
.param("refresh_token", refreshToken)
.param("client_id", resource)
.param("client_secret", "SOME_SECRET")
.param("scope", "SOME_SCOPE_TO_RESTRICT_ROLES")
.response()
.json(AccessTokenResponse.class)
.execute();

// :) - response.getToken() and response.getRefreshToken(), contain new successfully generated tokens

我的问题是,如何使用这些“自定义创建” token 强制我的应用程序更改/重置通过通常方式获得的标准访问 token 和刷新 token ?或者这有可能吗?

感谢您的任何反馈!

更多信息

为了澄清更多信息,让我们分析一下与 Keycloak 集成的典型 springboot/spring security 项目的行为:

  • 您可以通过配置(在 application.properties 或 SecurityContext 上)使用“角色”保护您的端点
  • 你知道这个 Spring 应用程序在后台 channel 中与 Keycloak 授权服务器进行对话,这就是你成为 access_token 的方式(但是这一切对于开发人员来说都是一个黑匣子,你只知道创建了一个主体,一个安全上下文,凭据等 - 一切都发生在幕后)

考虑到上面的两点,想象一下您使用 Http 库基本上向身份验证服务器 token 端点请求一个新 token ,如上面的代码所示(是的,按范围和所有内容进行过滤)。所以现在的情况是,尽管您已经创建了有效的 access_token(和refresh_token);由于它们是通过向 token 端点发出请求“手动”创建的,因此这个新 token 尚未“合并”到应用程序中,因为没有创建新的主体,没有生成新的安全上下文等。换句话说,对于 springboot 应用程序来说这个新 token 是不存在的。

我想要完成的是告诉 sprinboot/spring security:“嘿 friend ,我知道你没有自己生成这个 token ,但请接受它并表现得就像你创建了它一样”。

我希望这能澄清我的问题的意图。

最佳答案

您可以使用 org.springframework.security.oauth2.provider.token.ConsumerTokenServices#revokeToken 撤销 token 方法。

在授权服务器上:

@Resource(name="tokenServices")
ConsumerTokenServices tokenServices;

@RequestMapping(method = RequestMethod.POST, value = "/tokens/revoke/{tokenId:.*}")
@ResponseBody
public String revokeToken(@PathVariable String tokenId) {
tokenServices.revokeToken(tokenId);
return tokenId;
}

当然,您必须保护此方法,因为它是一个非常敏感的方法。

关于spring-boot - 如何使用 Spring boot keycloak 适配器 + spring security 强制更新 oAuth token (访问 token + 刷新 token )?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58338063/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com