login - Keycloak - Multi/2FA Factor - OTP - QR Code - 自定义登录屏幕 - Rest API
问题描述
我有自己的登录页面,用户在其中输入用户名/密码。 此用户名/密码用于通过 Keycloak Rest API 登录。
http://localhost:8080/auth/realms/Demo/protocol/openid-connect/token
input - {username,password,grant_type,client_secret,client_id}
作为回应,我得到了access token
。
现在我希望启用 Authenticator ( Google Authenticator
)。我已经从后端启用了它。现在,如果用户希望通过我的应用程序登录,我的登录页面需要获取以下详细信息。
1.)不知何故,一旦用户输入用户名/密码,我需要包含出现在 keycloak 登录页面上的用户名/密码验证后的 QR 码,以便在我的登录屏幕上显示第一次登录。那么我们是否有任何 API 可以返回 Keycloak QR 码图像作为响应。
2.)后续登录我将有 OTP 字段,因此需要一个 REST api 来传递 OTP 以及用户名/密码。
如果 keycloak 有,请帮助使用 REST API。通过 Javascript 集成。
与此处用例 1 中描述的类似流程
只想把keycloak当做数据库,为我做所有的操作,输入就是我的屏幕。我确实希望在登录时重定向 URL,但应该独立部署。
解决方案
我已经设法通过 Keycloak 的其余 API 实现了这一点。要实现这一点,您需要自己使用 SPI 扩展 Keycloak。为此,请创建您自己的 Java 项目并扩展org.keycloak.services.resource.RealmResourceProvider
和org.keycloak.services.resource.RealmResourceProviderFactory
. 您可以在官方文档 ( https://www.keycloak.org/docs/latest/server_development/#_extensions)、github示例和其他堆栈溢出帖子中找到如何执行此操作的更多信息。
一旦你启动并运行它,你可以像这样实现它:
@GET
@Path("your-end-point-to-fetch-the-qr")
@Produces({MediaType.APPLICATION_JSON})
public YourDtoWithSecretAndQr get2FASetup(@PathParam("username") final String username) {
final RealmModel realm = this.session.getContext().getRealm();
final UserModel user = this.session.users().getUserByUsername(username, realm);
final String totpSecret = HmacOTP.generateSecret(20);
final String totpSecretQrCode = TotpUtils.qrCode(totpSecret, realm, user);
return new YourDtoWithSecretAndQr(totpSecret, totpSecretQrCode);
}
@POST
@Path("your-end-point-to-setup-2fa")
@Consumes("application/json")
public void setup2FA(@PathParam("username") final String username, final YourDtoWithData dto) {
final RealmModel realm = this.session.getContext().getRealm();
final UserModel user = this.session.users().getUserByUsername(username, realm);
final OTPCredentialModel otpCredentialModel = OTPCredentialModel.createFromPolicy(realm, dto.getSecret(), dto.getDeviceName());
CredentialHelper.createOTPCredential(this.session, realm, user, dto.getInitialCode(), otpCredentialModel);
}
通过 GET 接收到的秘密必须通过 POST 发回。初始代码是来自您的 2FA 应用程序(例如 Google Authenticator)的代码。二维码是一个字符串,可以img
用 src显示'data:image/png;base64,' + qrCodeString;
推荐阅读
- java - 具有字符串表示的对象数组 (Java)
- string - 为什么 Dart 中的字符串声明是大写的?
- typescript - Typescript 中的强类型转换
- android - 如何从 native-android 小部件调用 react native 的组件?
- python - 哪一种是更快的方法来计算 1 的数量?
- android-studio-3.6 - 无法确定应用程序 ID:com.android.tools.idea.run.ApkProvisionException:变体的主要工件没有输出:调试
- r - 在 R 中使用 dplyr 或 tidyverse 映射多列
- kendo-ui - [Kendo UI Grid (Kendo Validator)]无法读取未定义的属性“验证”
- javascript - 为 newsletter-modal-popup 添加 cookie
- excel - 更新 PowerQuery 函数以从命名表的列和行返回数据,而不仅仅是特定列中的行