Login Keyclope-多/2FA因子-OTP-QR码-自定义登录屏幕-Rest API

Login Keyclope-多/2FA因子-OTP-QR码-自定义登录屏幕-Rest API,login,keycloak,user-registration,keycloak-services,multi-factor-authentication,Login,Keycloak,User Registration,Keycloak Services,Multi Factor Authentication,我有自己的登录页面,用户在其中输入用户名/密码。 此用户名/密码用于通过KeyClope Rest API登录 作为响应,我得到访问令牌 现在我希望启用验证器(googleauthenticator)。我已经从后端启用了它。现在,如果用户希望登录我的应用程序,我的登录页面,我需要得到以下详细信息 1.)不知何故,我需要包括出现在KeyClope登录页面上的QR码,在用户输入用户名/密码后,在我的登录屏幕上首次显示用户名/密码验证。那么,我们是否有任何API返回KeyClope二维码图像作为响应

我有自己的登录页面,用户在其中输入用户名/密码。 此用户名/密码用于通过KeyClope Rest API登录

作为响应,我得到
访问令牌

现在我希望启用验证器(
googleauthenticator
)。我已经从后端启用了它。现在,如果用户希望登录我的应用程序,我的登录页面,我需要得到以下详细信息

1.)不知何故,我需要包括出现在KeyClope登录页面上的QR码,在用户输入用户名/密码后,在我的登录屏幕上首次显示用户名/密码验证。那么,我们是否有任何API返回KeyClope二维码图像作为响应

2.)后续登录我将有OTP字段,因此需要一个REST api来传递OTP以及用户名/密码

请帮助RESTAPI,如果Key斗篷有任何。通过Javascript进行集成

用例1中描述的类似流程


只想用keybeave作为数据库,为我做所有的操作,输入将是我的屏幕。我确实希望在登录时重定向URL,但应该是独立部署的。

我知道这是一个老问题,但我最近一直在研究类似的问题,因此我认为将我的发现分享给其他可能正在研究此问题并想知道其可能性的人可能会很有价值


TL;DR
您只能真正使用现有的keydrope操作来执行此操作,或者将https://{keydrope server URL}/auth/realms/{realm name}/account处的用户帐户管理页面嵌入到iframe中。恐怕就这样了。在我看来,目前最好直接向帐户分配操作,或使用凭据重置电子邮件分配操作;如果需要,这两项都可以通过管理API完成:

发送包含指定操作的凭据重置电子邮件:

直接在帐户上设置操作(包括发送到端点的用户JSON的requiredActions部分中的操作):


背景是,作为我一直在从事的一个项目的一部分,我们想看看,当为用户创建新帐户时,我们是否可以为用户提供一种集成的方式来设置他们的初始密码和OTP设备,因为默认方法是使用“凭证重置”从Keyclope向他们发送电子邮件功能具有以下限制:a)除非您覆盖主题,否则它不会提供指向应用程序本身的链接,并且如果您有多个应用程序实例供不同用户使用,您无法知道为哪个实例提供链接,因此可能最终不得不包括一个它们的列表,b)即使主题发生了变化,应用程序通常也感觉不到真正的本地特性。如果你明智的话,我建议你停止使用这个功能——请看TL;详细信息请参见上面的DR部分

因此,简而言之,没有API端点用于接收QR码以设置OTP设备。但是,有两个地方可以检索QR代码-当您作为已将“配置OTP”操作分配给其帐户的用户登录时,OTP设备设置屏幕和用户自己的帐户管理屏幕

配置OTP操作屏幕的第一个选项是非启动选项。它只会在您登录时显示,因此根据定义,用户必须通过keydove登录页面登录到keydove,才能触发显示页面。此时,你已经在一个keydave页面上,而不是你的应用程序页面上,因此,除非你可以通过自定义主题对这些keydave页面进行非常有创意的更改,否则点击该页面实际上不是一个选项

第二种选择更有趣,但远不理想。每个登录的用户都可以访问帐户管理页面,该页面位于https://{keydape server URL}/auth/realms/{realm name}/account。此页面允许您进行更改姓名、密码等操作,还允许您添加OTP设备(如果您还没有),或删除与您的帐户关联的任何现有OTP设备。可以通过https://{keydepot server URL}/auth/realms/{realm name}/account/totp直接访问帐户管理页面的OTP设备选项卡

正如我所提到的,没有API可以让你查看显示在这个页面上的二维码。唯一可以访问它的方法是通过对https://{keydeposerverurl}/auth/realms/{realmname}/account/totp的GET请求,它返回我前面提到的页面的HTML。好的,很好,那么我们可以通过编程刮取二维码,然后将其放在应用程序的我们自己的页面中吗?呃,不,不是真的。您可以看到,虽然许多KeyClope API端点正确地允许您在授权标头中将承载令牌(例如访问令牌)发送到访问和端点,但此页面将不接受承载令牌作为身份验证/授权的手段。相反,它使用一个会话cookie,该cookie被锁定到keydepose URL。此cookie是在您通过KeyClope登录页面登录到应用程序时设置的,因此在您导航到此帐户管理页面(已登录)时,此cookie可用于此帐户管理页面,并且由于帐户管理页面使用与原始KeyClope登录页面相同的服务器和域名,因此它可以访问cookie并允许您进入。您的应用程序无法将此cookie发送到(例如)您自己的REST API,然后以编程方式调用帐户管理页面并刮取二维码,因为出于良好的安全原因,您的应用程序无法访问它。这可能是你可以在某个地方改变的东西,但如果有,我强烈建议不要改变它

所以,如果我们不能从自己的服务器上抓取页面,我们可以在前端做些什么吗?如前所述,您的应用程序无法访问
input - {username,password,grant_type,client_secret,client_id}
@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);
}