gpt4 book ai didi

authentication - Keycloak:使用自定义 JWT 对用户进行身份验证

转载 作者:行者123 更新时间:2023-12-04 12:39:26 47 4
gpt4 key购买 nike

情况:我们使用 keycloak 通过使用 JavaScript 适配器的正常浏览器身份验证流程对我们的 Web 应用程序 (A) 中的用户进行身份验证。这完美!

目标:现在,一组新用户应该能够访问 A。但是他们在没有 Keycloak 的受信任的第三方应用程序 (B) 中使用用户名和密码登录。在 B 中,他们有一个指向 A 的链接,其中包含自定义 JWT(基本上包含用户名和角色)作为查询参数。因此,当用户单击链接时,他会到达我们的应用程序入口点,我们可以在此处从 URL 中读取 JWT。现在需要发生的是某种代币交换。我们希望将此自定义 JWT 发送到 Keycloak,后者将类似于正常登录过程的访问 token 发送回。

问题: Keycloak 中是否有针对此类用例的内置支持?

尝试:

我尝试按照文档中的建议创建一个“签名 JWT”作为“Client Authenticator”的 secret 客户端。经过一些测试,我认为这不是正确的轨道,即使这个名字很有希望。

另一个轨道是“Client suggested identity provider”,通过实现自定义身份提供者。但我没有看到,如何在请求中发送 JWT。

目前我正在尝试使用 Autentication SPI使用自定义身份验证器扩展身份验证流程。

也许它比我想象的要简单得多。谁能带领我朝着正确的方向前进?

最佳答案

所以我终于能够用问题中提到的 Authentication SPI 来解决它。

在 Keycloak 中,我复制了“浏览器”身份验证流程(因为您无法修改内置流程)并引入了一个附加步骤“Portal JWT”(见下图)。然后我将它绑定(bind)到“绑定(bind)”选项卡中的“浏览器流”

Custom Authentication Flow

在“Portal JWT”后面是我的自定义身份验证器,它从重定向 uri 中的查询参数中提取 JWT,并对其进行解析以从中获取用户名和角色。然后使用自定义属性“isExternal”将用户添加到 keycloak。这是它的摘录:

public class JwtAuthenticator implements Authenticator {

private final JwtReader reader;

JwtAuthenticator(JwtReader reader) {
this.reader = reader;
}

@Override
public void authenticate(AuthenticationFlowContext context) {
Optional<String> externalCredential = hasExternalCredential(context);
if (externalCredential.isPresent()) {
ExternalUser externalUser = reader.read(context.getAuthenticatorConfig(), externalCredential.get());
String username = externalUser.getUsername();
UserModel user = context.getSession().users().getUserByUsername(username, context.getRealm());
if (user == null) {
user = context.getSession().users().addUser(context.getRealm(), username);
user.setEnabled(true);
user.setSingleAttribute("isExternal", "true");
}
for (String roleName : externalUser.getRoles()) {
RoleModel role = context.getRealm().getRole(roleName);
if (role == null) {
role = context.getRealm().addRole(roleName);
}
user.grantRole(role);
}
context.setUser(user);
context.success();
} else {
context.attempted();
}
}

private Optional<String> hasExternalCredential(AuthenticationFlowContext context) {
String redirectUri = context.getUriInfo().getQueryParameters().getFirst("redirect_uri);
try {
List<NameValuePair> queryParams = URLEncodedUtils.parse(new URI(redirectUri), "UTF-8");
Optional<NameValuePair> jwtParam = queryParams.stream()
.filter(nv -> "jwt".equalsIgnoreCase(nv.getName())).findAny();
if (jwtParam.isPresent()) {
String jwt = jwtParam.get().getValue();
if (LOG.isDebugEnabled()) {
LOG.debug("JWT found: " + jwt);
}
return Optional.of(jwt);
}
} catch (URISyntaxException e) {
LOG.error("Redirect URL not as expected: " + redirectUri);
}
return Optional.empty();
}

关于authentication - Keycloak:使用自定义 JWT 对用户进行身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48638584/

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