Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebAuthn across multiple subdomain

I'm trying to set up a WebAuthn authentication flow on my website, but I'm bumping into an issue. I want my users to be able to register their devices on the main website (www.domain.com) so it's easily accessible through their user settings. Authentication itself happens on a different subdomain through an IdP (sso.domain.com). This is where trouble began.

There's a couple of things I've tried:

  • Registration and authentication on www.scoutswechel.be, passing 'www.scoutswechel.be' as the rp.id for both => works.
  • Registration on www.scoutswechel.be, authentication on sso.scoutswechel.be, passing 'www.scoutswechel.be' as the rp.id for both => the authentication step fails as authenticator doesn't return any keys.
  • Registration on www.scoutswechel.be, authentication on sso.scoutswechel, passing those domains respectively as the rp.id => the authentication step fails as authenticator doesn't return any keys.
  • Registration on www.scoutswechel.be, authentication on sso.scoutswechel.be, passing 'scoutswechel.be' as rp.id for both => registration step already fails with differing errors for different browsers (eg 'key returned something unexpected (2)' in chrome).

If I understand the spec correctly, passing 'scoutswechel.be' should actually work as both domains are subdomains of the main domain (correct me if I'm wrong here).

I prepare my challenges with PHP and pass them to the page with ajax calls. My PHP scripts returns for example following value:

{
   "publicKey":{
      "challenge":[105,107,101,103,105,49,119,115,98,108,119,109,48,109,105,53],
      "user":{
         "name":"walter",
         "displayName":"Wouter Henderickx",
         "id":[49,48,51]
      },
      "rp":{
         "id":"scoutswechel.be",
         "name":"scoutswechel.be"
      },
      "pubKeyCredParams":[
         {
            "alg":-7,
            "type":"public-key"
         }
      ],
      "authenticatorSelection":{
         "authenticatorAttachment":"cross-platform",
         "requireResidentKey":false,
         "userVerification":"preferred"
      },
      "attestation":null,
      "timeout":60000,
      "excludeCredentials":[],
      "extensions":{
         "exts":true
      }
   },
   "b64challenge":"aWtlZ2kxd3NibHdtMG1pNQ"
}

I then convert the challenge and user.id to Uint8Array and pass the publickey part to:

navigator.credentials.create({publicKey: key.publicKey}).
	then(function (aNewCredentialInfo) {
		do.stuff()
	})

How should I go about this? What values can I pass to the rp.id to get this working across both subdomains?

like image 459
vixducis Avatar asked Nov 17 '22 13:11

vixducis


1 Answers

In the end, I figured it out. These were all implementation issues on my end:

  • In the library I based my project of (https://github.com/davidearl/webauthn), there was a piece of javascript that compared the value of the rp.name to the origin. Since I was passing a non-domain name, this check was blocking further execution.
  • I was passing 'rpid' for the relying party identifier. However, this should have been 'rpId'. Since my authenticator couldn't find any credentials without an rpid, it didn't return anything and I wasn't authenticated.
like image 130
vixducis Avatar answered Jan 04 '23 04:01

vixducis