From accd9a8f5f52f4e7fdb22b840f19cafbef7ecc8c Mon Sep 17 00:00:00 2001 From: JeffH Date: Thu, 18 Feb 2021 15:02:18 -0800 Subject: [PATCH] conditional UI flow rework see also https://github.com/w3c/webappsec-credential-management/pull/155 and [Explainer: WebAuthn Conditional/Hinted UI](https://docs.google.com/document/d/11hWpUPAnblPtkn1f7AIQW0ujoiu_BAKzlMVhZKQPiW8/) --- index.bs | 53 +++++++++++++++++------------------------------------ 1 file changed, 17 insertions(+), 36 deletions(-) diff --git a/index.bs b/index.bs index 93d1807ba..548961763 100644 --- a/index.bs +++ b/index.bs @@ -1446,20 +1446,6 @@ that are returned to the caller when a new credential is created, or a new asser implementation of {{PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)}}, {{PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)}}, and {{Credential/[[Store]](credential, sameOriginWithAncestors)}}. -### ConditionalPublicKeyCredential Interface ### {#iface=cpkcredential} - -{{ConditionalPublicKeyCredential}} inherits from {{PublicKeyCredential}} and is identical except for a different {{Credential/[[type]]}} in order to support the [=Conditional UI Flow=]. - - - [SecureContext, Exposed=Window] - interface ConditionalPublicKeyCredential : PublicKeyCredential { - }; - -
- : {{Credential/[[type]]}} - :: The {{ConditionalPublicKeyCredential}} [=interface object=]'s {{Credential/[[type]]}} [=internal slot=]'s value is the string - "`conditionalPublicKey`". -
### `CredentialCreationOptions` Dictionary Extension ### {#sctn-credentialcreationoptions-extension} @@ -1480,7 +1466,6 @@ To support obtaining assertions via {{CredentialsContainer/get()|navigator.crede partial dictionary CredentialRequestOptions { PublicKeyCredentialRequestOptions publicKey; - PublicKeyCredentialRequestOptions conditionalPublicKey; }; @@ -1941,14 +1926,16 @@ to indicate what [=credential sources=] are acceptable to it. The [=client platf matching the specified criteria, and guides the user to pick one that the script will be allowed to use. The user may choose to decline the entire interaction even if a [=credential source=] is present, for example to maintain privacy. If the user picks a [=credential source=], the user agent then uses -[[#sctn-op-get-assertion]] to sign a [=[RP]=]-provided challenge and other collected data into an assertion, which is used as a +[[#sctn-op-get-assertion]] to sign a [=[RP]=]-provided challenge and other collected data into an [=assertion=], which is used as a [=credential=]. -The {{CredentialsContainer/get()}} implementation [[!CREDENTIAL-MANAGEMENT-1]] calls +The {{CredentialsContainer/get()|navigator.credentials.get()}} implementation [[!CREDENTIAL-MANAGEMENT-1]] calls PublicKeyCredential.{{PublicKeyCredential/[[CollectFromCredentialStore]]()}} to collect any [=credentials=] that should be available without [=user mediation=] (roughly, this specification's [=authorization gesture=]), and if it does not find -exactly one of those, it then calls PublicKeyCredential.{{PublicKeyCredential/[[DiscoverFromExternalSource]]()}} to have -the user select a [=credential source=]. +exactly one of those, it then calls PublicKeyCredential.{{PublicKeyCredential/[[DiscoverFromExternalSource]]()}} to have the user select a [=credential source=]. + +In any case, the user agent SHOULD show some UI to the user to guide them in selecting and +authorizing an authenticator with which to complete the operation. [=[RPS]=] can provide a hint that a prominent, modal UI should not be used for this process by setting |options|.{{CredentialRequestOptions/mediation}} to "conditional". This is known as a Conditional UI Flow. [=[RP]=] script SHOULD first check that navigator.credentials.{{CredentialsContainer/conditionalMediationSupported}} is [TRUE] in order to avoid the possiblity of causing a user-visible error to be returned if the user agent does not support [=conditional UI flow=]. Since this specification requires an [=authorization gesture=] to create any [=credentials=], the PublicKeyCredential.\[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors) [=internal method=] inherits the default behavior of @@ -1972,7 +1959,7 @@ This [=internal method=] accepts three arguments: : options :: This argument is a {{CredentialRequestOptions}} object whose - |options|.{{CredentialRequestOptions/publicKey}} or |options|.{{CredentialRequestOptions/conditionalPublicKey}} member contains a {{PublicKeyCredentialRequestOptions}} + |options|.{{CredentialRequestOptions/publicKey}} member contains a {{PublicKeyCredentialRequestOptions}} object specifying the desired attributes of the [=public key credential=] to discover. : sameOriginWithAncestors @@ -1993,20 +1980,19 @@ by the buffer source=] and use that copy for relevant portions of the algorithm. When this method is invoked, the user agent MUST execute the following algorithm: -1. Assert: |options|.{{CredentialRequestOptions/publicKey}} or |options|.{{CredentialRequestOptions/conditionalPublicKey}} are present. +1. Assert: |options|.{{CredentialRequestOptions/publicKey}} is present. + +1. Let |options| be the value of |options|.{{CredentialRequestOptions/publicKey}}. -1. If |options|.{{CredentialRequestOptions/publicKey}} and |options|.{{CredentialRequestOptions/conditionalPublicKey}} are present, return - a {{DOMException}} whose name is "{{NotSupportedError}}", and terminate this algorithm. +1. If |options|.{{CredentialRequestOptions/mediation}} +
+ : is present with the value "conditional" + :: If |options|.{{PublicKeyCredentialRequestOptions/allowCredentials}} is empty then let |conditionalFlow| be [TRUE], otherwise return a {{DOMException}} whose name is "{{NotAllowedError}}", and terminate this algorithm. -1. If |options|.{{CredentialRequestOptions/publicKey}} is present: - 1. Let |options| be the value of |options|.{{CredentialRequestOptions/publicKey}}. - 1. Let |conditionalFlow| be [FALSE]. + : is present with a value other than "conditional" or is not present + :: let |conditionalFlow| be [FALSE]. +
-1. If |options|.{{CredentialRequestOptions/conditionalPublicKey}} is present: - 1. If |options|.{{PublicKeyCredentialRequestOptions/allowCredentials}} is not empty, return - a {{DOMException}} whose name is "{{NotSupportedError}}", and terminate this algorithm. - 1. Let |options| be the value of |options|.{{CredentialRequestOptions/conditionalPublicKey}}. - 1. Let |conditionalFlow| be [TRUE]. 1. If the {{PublicKeyCredentialRequestOptions/timeout}} member of |options| is present, check if its value lies within a reasonable range as defined by the [=client=] and if not, correct it to the closest value lying within that range. @@ -2312,11 +2298,6 @@ When this method is invoked, the user agent MUST execute the following algorithm user without [=user consent|consent=], this step MUST NOT be executed before |lifetimeTimer| has expired. See [[#sctn-assertion-privacy]] for details. -During the above process, the user agent SHOULD show some UI to the user to guide them in the process of selecting and -authorizing an authenticator with which to complete the operation. [=[RPS]=] can provide a hint that a prominent UI should -not be displayed if no |authenticator| will become available for any [=public key credentials=] by setting -|options|.{{CredentialRequestOptions/conditionalPublicKey}} to the desired {{PublicKeyCredentialRequestOptions}}. -This is known as a Conditional UI Flow.