首页 > 解决方案 > WebAuthn:无法在子域上登录

问题描述

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

注册工作很简单,我从 (WebAuthn4J) 后端收到挑战,并使用以下内容创建凭据:

...

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)显示“无法识别身份验证器”(不完全正确,因为消息是德语)。

我所做的只是将有效的 credentialIds(我从后端收到)交给导航器。

...

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时:

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

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

我阅读了规范,虽然我认为它相当普遍,但它对这个设置非常不具体:https ://www.w3.org/TR/webauthn/#relying-party-identifier

在一个类似的 SO question 中,它说我在这里的设置应该可以工作(虽然没有任何来源):WebAuthn across multiple subdomain

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

我不知道在哪里研究。我使用的 WebAuthn4J 实现(https://github.com/webauthn4j/webauthn4j)工作得很好,证明我可以从上面的两个设置中登录。

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

任何提示(甚至只指向我链接的其他规格)

标签: javaangularwebauthn

解决方案


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


推荐阅读