Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make create() and get() abortable #544

Merged
merged 44 commits into from
Nov 8, 2017
Merged
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
ed25b6c
do not call authenticatorMakeCredential() with separate |rpId| fixes …
Jun 16, 2017
31a8f85
credID returned by authnrGetAssn() is optional if allowCreds has exac…
Jun 16, 2017
9c3940f
fixup global object reference per domenic, improves #472
Jun 20, 2017
be43665
indent 4.1.4 step 18et al to clarify relation to prior step
Jun 28, 2017
9ce4331
fix line indent
Jun 28, 2017
78d6d2c
Merge branch 'master' into jeffh-fixup-algs-contd-3
Jul 5, 2017
9ddf29d
Merge branch 'master' into jeffh-fixup-algs-contd-3
Aug 4, 2017
5f543b8
do not call authenticatorMakeCredential() with separate |rpId| fixes …
Jun 16, 2017
d8fd53b
credID returned by authnrGetAssn() is optional if allowCreds has exac…
Jun 16, 2017
c9b40d5
fixup global object reference per domenic, improves #472
Jun 20, 2017
d492a50
indent 4.1.4 step 18et al to clarify relation to prior step
Jun 28, 2017
2934f9e
fix line indent
Jun 28, 2017
a1be0f6
post rebase-on-master, fix dangling MakeCredentialOptions
Aug 18, 2017
28f52af
fix error in resolving rebase conflicts
Aug 18, 2017
5fada18
further rebase conflict resolution error fixups
Aug 18, 2017
6a011d2
merge with this remote branch via pull, somehow they were out of sync
Aug 18, 2017
5fb2f8c
convert switch steps to colon-denotation
Aug 22, 2017
51706b3
tag 'while'
Aug 24, 2017
5e4a7b0
primary changes for improving #472 mostly complete
Aug 25, 2017
d6d6c19
further issue #472 cleanups
Aug 25, 2017
a76de0b
del 'cancel the timer' from #creatCredential fixes #535
Aug 25, 2017
97f0ae2
polish constructResultantCredentialCallback method description
Aug 25, 2017
8622aea
marked authenticator model section as non-normative
AngeloKai Aug 31, 2017
e8ca2be
marked relying party operation section as non-normative
AngeloKai Aug 31, 2017
84c12bb
fix proper subset tweak
AngeloKai Aug 31, 2017
2263888
Added abort signal object and steps to webauthn
AngeloKai Sep 5, 2017
12c943b
Merge branch 'master' of https://github.com/w3c/webauthn
AngeloKai Oct 12, 2017
4750a54
merge upstream master
AngeloKai Oct 12, 2017
30a5690
synced with upstream master
AngeloKai Oct 20, 2017
fa7c06b
fixed a minor issue with linking
AngeloKai Oct 25, 2017
f21e17d
sync upstream master
AngeloKai Oct 26, 2017
6181caf
add minor edits to focus on the main things
AngeloKai Oct 26, 2017
0d5bba1
getting the blank line correct
AngeloKai Oct 26, 2017
352223c
Added a example section to explain how abort should be used
AngeloKai Oct 30, 2017
298677f
fix up example
AngeloKai Nov 1, 2017
549e659
committing before computer dies
AngeloKai Nov 1, 2017
ad5a888
updated grammars of the example based on feedback
AngeloKai Nov 2, 2017
c142b5a
update example text
AngeloKai Nov 2, 2017
3fa4a3f
Updated with the section on switching tab; complete the PR
AngeloKai Nov 3, 2017
14a7659
minor tweak
AngeloKai Nov 3, 2017
2cb344c
finished polishing the spec
AngeloKai Nov 3, 2017
2430dcd
whoops one leftover
AngeloKai Nov 3, 2017
ad85e75
finally figured out how to remove last two linking errors
AngeloKai Nov 3, 2017
78b0912
take out abortsignal from extension; edit promise rejection
AngeloKai Nov 3, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 97 additions & 3 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,20 @@ spec: credential-management-1; urlPrefix: https://w3c.github.io/webappsec-creden
for: CredentialsContainer
type: method
text: create(); url: dom-credentialscontainer-create
type: dfn
text: signal

spec: mixed-content; urlPrefix: www.w3.org/TR/mixed-content/
type: dfn
text: a priori authenticated

spec: page-visibility; urlPrefix: https://www.w3.org/TR/page-visibility/
type: dfn
text: visibility states

spec: WHATWG HTML; urlPrefix: https://html.spec.whatwg.org/
type: dfn
text: focus
</pre> <!-- class=anchors -->

<pre class="link-defaults">
Expand Down Expand Up @@ -570,7 +580,9 @@ To support obtaining assertions via {{CredentialsContainer/get()|navigator.crede
{{CredentialsContainer/create()|navigator.credentials.create()}} to request the creation of a new [=credential key pair=]
and {{PublicKeyCredential}}, managed by an [=authenticator=].
On success, the returned {{promise}} will be resolved with a {{PublicKeyCredential}} containing an
{{AuthenticatorAttestationResponse}} object.
{{AuthenticatorAttestationResponse}} object. This {{CredentialsContainer/create()|navigator.credentials.create()}}
operation can be aborted by leveraging the {{AbortController}}; see
[[dom#abortcontroller-api-integration]] for detailed instructions.

Note: This algorithm is synchronous; the {{Promise}} resolution/rejection is handled by
{{CredentialsContainer/create()|navigator.credentials.create()}}.
Expand Down Expand Up @@ -688,6 +700,10 @@ When this method is invoked, the user agent MUST execute the following algorithm

1. Let |clientDataHash| be the [=hash of the serialized client data=] represented by |clientDataJSON|.

1. If the <code>|options|.{{CredentialCreationOptions/signal}}</code> is [=present=] and its
[=AbortSignal/aborted flag=] is set to true, return a {{DOMException}} whose name is "{{AbortError}}"
and terminate this algorithm.

1. Start |lifetimeTimer|.

1. Let |issuedRequests| be a new [=ordered set=].
Expand Down Expand Up @@ -735,6 +751,12 @@ When this method is invoked, the user agent MUST execute the following algorithm
:: [=set/For each=] |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation on |authenticator|
and [=set/remove=] |authenticator| from |issuedRequests|.

: If the <code>|options|.{{CredentialCreationOptions/signal}}</code> is [=present=] and its
[=AbortSignal/aborted flag=] is set to true,
:: [=set/For each=] |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=]
operation on |authenticator| and [=set/remove=] |authenticator| from |issuedRequests|. Then return a {{DOMException}}
whose name is "{{AbortError}}" and terminate this algorithm.

: If any |authenticator| returns a status indicating that the user cancelled the operation,
:: 1. [=set/Remove=] |authenticator| from |issuedRequests|.
2. [=set/For each=] remaining |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation on
Expand Down Expand Up @@ -906,6 +928,10 @@ method is invoked, the user agent MUST:

1. Let |clientDataHash| be the [=hash of the serialized client data=] represented by |clientDataJSON|.

1. If the <code>|options|.{{CredentialRequestOptions/signal}}</code> is [=present=] and its
[=AbortSignal/aborted flag=] is set to true, return a {{DOMException}} whose name is "{{AbortError}}"
and terminate this algorithm.

1. Let |issuedRequests| be a new [=ordered set=].

1. Let |authenticator| be a platform-specific handle whose value identifies an [=authenticator=].
Expand Down Expand Up @@ -985,6 +1011,12 @@ method is invoked, the user agent MUST:
:: [=set/For each=] |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation on
|authenticator| and [=set/remove=] |authenticator| from |issuedRequests|.

: If the {{CredentialRequestOptions/signal}} member is [=present=] and the [=AbortSignal/aborted flag=] is set to
true,
:: [=set/For each=] |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation on |authenticator|
and [=set/remove=] |authenticator| from |issuedRequests|. Then
return a {{DOMException}} whose name is "{{AbortError}}" and terminate this algorithm.

: If any |authenticator| returns a status indicating that the user cancelled the operation,
:: 1. [=set/Remove=] |authenticator| from |issuedRequests|.
2. [=set/For each=] remaining |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation
Expand Down Expand Up @@ -1089,7 +1121,6 @@ but short enough that the dangling promise will still be resolved in a reasonabl

</div>


## Authenticator Responses (interface <dfn interface>AuthenticatorResponse</dfn>) ## {#iface-authenticatorresponse}

[=Authenticators=] respond to [=[RP]=] requests by returning an object derived from the
Expand Down Expand Up @@ -1418,14 +1449,41 @@ an assertion. Its {{PublicKeyCredentialRequestOptions/challenge}} member must be
:: This optional member contains a list of {{PublicKeyCredentialDescriptor}} object representing [=public key credentials=]
acceptable to the caller, in decending order of the caller's preference (the first item in the list is the most
preferred credential, and so on down the list).

: <dfn>extensions</dfn>
:: This optional member contains additional parameters requesting additional processing by the client and authenticator.
For example, if transaction confirmation is sought from the user, then the prompt string might be included as an
extension.
</dl>


## Abort operations with `AbortSignal` ## {#abortoperation}

Developers are encouraged to leverage the {{AbortController}} to manage the
{{PublicKeyCredential/[[Create]](options)}} and {{PublicKeyCredential/[[DiscoverFromExternalSource]](options)}} operations.
See [[dom#abortcontroller-api-integration]] section for detailed instructions.

Note: [[dom#abortcontroller-api-integration]] section specifies that web platform APIs integrating with the
{{AbortController}} must reject the promise immediately once the [=AbortSignal/aborted flag=] is set.
Given the complex inheritance and parallelization structure of the {{PublicKeyCredential/[[Create]](options)}}
and {{PublicKeyCredential/[[DiscoverFromExternalSource]](options)}} methods, the algorithms for the two APIs fulfills this
requirement by checking the [=AbortSignal/aborted flag=] in three places. In the case of
{{PublicKeyCredential/[[Create]](options)}}, the aborted flag is checked first in
[[credential-management-1#algorithm-create]] right before calling {{Credential/[[Create]](options)}},
then in [[#createCredential]] right before authenticator sessions start, and finally
during authenticator sessions. The same goes for
{{PublicKeyCredential/[[DiscoverFromExternalSource]](options)}}.

The [=visibility states|visibility=] and [=focus=] state of the [=Window=] object determines whether the
{{PublicKeyCredential/[[Create]](options)}} and {{PublicKeyCredential/[[DiscoverFromExternalSource]](options)}} operations
should continue. When the [=Window=] object associated with the [[=Document=] loses focus,
{{PublicKeyCredential/[[Create]](options)}} and {{PublicKeyCredential/[[DiscoverFromExternalSource]](options)}} operations
SHOULD be aborted.

Issue: The WHATWG HTML WG is discussing whether to provide a hook when a browsing context gains or
loses focuses. If a hook is provided, the above paragraph will be updated to include the hook.
See [WHATWG HTML WG Issue #2711](https://github.com/whatwg/html/issues/2711) for more details.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

above is helpful (nice!) but will need updating per however we end up polishing this abort functionality between webauthn & credman.

## Authentication Extensions (typedef <dfn>AuthenticationExtensions</dfn>) ## {#iface-authentication-extensions}

<pre class="idl">
Expand Down Expand Up @@ -3754,6 +3812,42 @@ extension for transaction authorization.
});
</pre>

## Aborting Authentication Operations ## {#sample-aborting}

The below example shows how a developer may use the AbortSignal parameter to abort a
credential registration operation. A similiar procedure applies to an authentication operation.

<pre class="example" highlight="js">
const authAbortController = new AbortController();
const authAbortSignal = authAbortController.signal;

authAbortSignal.onabort = function () {
// Once the page knows the abort started, inform user it is attempting to abort.
}

var options = {
// A list of options.
}

navigator.credentials.create({
publicKey: options,
signal: authAbortSignal})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

signal is a part of options yes?
so this would be..

     navigator.credentials.create({
         publicKey: options
     })

..?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the current design is that the signal can be a separate field (as described in the example and in my other comment).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, doh, nevermind, sorry.

.then(function (attestation) {
// Register the user.
}).catch(function (error) {
if (error == "AbortError") {
// Inform user the credential hasn't been created.
// Let the server know a key hasn't been created.
}
});

// Assume widget shows up whenever auth occurs.
if (widget == "disappear") {
authAbortSignal.abort();

}
</pre>


## Decommissioning ## {#sample-decommissioning}

Expand Down