本文介绍了WebAuthn:无法在子域上登录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Angular 11(前端)和Kotlin(后端)项目,我在其中实施了WebAuthn登录.

I have an Angular 11 (Frontend) and Kotlin (Backend) Project where I have implemented a WebAuthn Login.

作品的注册非常简单,我从(WebAuthn4J)后端遇到了挑战,并使用以下方法创建了凭据:

The registration of works straightforward, I get a challenge from the (WebAuthn4J) Backend and create the credentials with this:

...

const credentialOptions: CredentialCreationOptions = {
   publicKey: {
     attestation: 'direct',
     user: {
       name: 'UsernameXYZ',
       displayName: 'UsernameXYZ',
       id: decodeUrlSafeB64(btoa('<uuid-from-db>'))
     },
     rp: {
       id: 'my-company.com',
       name: 'My Company'
     },
     challenge: challenge, // Challenge from Backend as B64
     pubKeyCredParams: [
       {
         type: 'public-key',
         alg: -257 // RS256
       },
       {
         type: 'public-key',
         alg: -7 // ES256
       }
     ],
     authenticatorSelection: undefined // All options possible
   }
 };
 const credentials: Credential = await navigator.credentials.create(credentialOptions);

 ...

现在,我可以顺利登录 my-company.com 了.但是我不能登录 other.my-company.com ,但我不明白为什么.WebAuthn对话框(来自Win10)说未识别身份验证器".(不完全是,因为该消息是德语).

Now, I can login at my-company.com with no problems. But I CANNOT login at other.my-company.com and I do not understand why. The WebAuthn dialogue (from Win10) says "Authenticator not recognized" (not exactly, as the message is german).

我要做的就是将有效的credentialIds(我从后端接收到的)交给导航器.

All I do is hand valid credentialIds (which I receive from the backend) to the navigator.

...

const credIds: Array<PublicKeyCredentialDescriptor> = [];
credentialIds.forEach((credentialId) => {
  credIds.push({
    type: 'public-key',
    id: decodeUrlSafeB64(credentialId)
  });
});

// my-company.com --> WebAuthn Dialog as expected
// other.my-company.com --> WebAuthnDialog does not recognize key
navigator.credentials.get({
  publicKey: {
    challenge: challenge, // Challenge for Login from Backend
    allowCredentials: credIds,
    userVerification: 'preferred'
  }
});

...

但是,当我通过 other.my-company.com 进行注册时:

However, when I make the registration from other.my-company.com with:

rp: {
  id: 'other.my-company.com',
  name: 'My Company'
},

我现在可以从 my-company.com other.my-company.com 登录.这将适用于现在的设置,但是当我计划扩展项目并在 another.my-company.com 上登录时,此操作将无效.

I can now login from my-company.com AND other.my-company.com. This would work for the setup I have now, but when I ever plan to extend my project and make a login at another.my-company.com this won't work.

我阅读了规范,尽管我认为它相当普遍,但它对此设置非常不确定: https://www.w3.org/TR/webauthn/#relying-party-identifier

I read the spec, and it is very unspecific about this setup, though I think its fairly common: https://www.w3.org/TR/webauthn/#relying-party-identifier

在类似的问题中,它说我在这里的设置应该可以工作(尽管没有任何来源):

In a similar SO question, it said that the setup I have here should work (without any source though): WebAuthn across multiple subdomain

在实现逻辑时,我也遵循了这一点: https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Authentication_API

I also followed this when implementing the logic: https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API

我对研究地点一无所知.我使用的WebAuthn4J实现( https://github.com/webauthn4j/webauthn4j )工作正常,证明我可以从上方登录两个设置.

I am out of ideas on where to research. The WebAuthn4J implementation I use (https://github.com/webauthn4j/webauthn4j) works just fine, as proven that I can login in the two settings from above.

我想到的唯一其他选择是将整个登录/注册过程与应用程序的其余部分分开,以便每次登录都重定向到 sso.my-company.com 与WebAuthn一起使用,获取JWT并重定向回原始应用程序.但这真的是我唯一的选择吗?对于我想做的事情,即注册域并允许所有子域",看来太过分了.

The only other option I came up with is to seperate the whole login/registration process from the rest of the app, so that every login gets redirected to sso.my-company.com, logs in with WebAuthn, gets a JWT and redirects back to the original app. But is that really the only option I have? It seems so overkill for what I want to do, namely "Register a domain and allow all subdomains."

任何提示(即使仅指向我链接的其他规范)

Any hint (even only pointing to othe specs as the one I linked)

推荐答案

您需要设置 RP ID 在声明期间与创建期间使用的相同RP ID相同.如果您不设置它,它将默认为当前来源,并包含子域,因此它将不再匹配.

You need to set the RP ID during assertion to the same RP ID used during creation. If you leave it unset, it will default to the current origin and include the subdomain so it will no longer match.

这篇关于WebAuthn:无法在子域上登录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-09 04:07