You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Scenario: A user wants to signup on a website using WebAuthn.
81
-
82
-
#### Explanation
41
+
For a registration ceremony use the following two methods:
83
42
84
-
1. When tapping the "Register" button the client sends a request to
85
-
the backend. The backend responds to this request with a call to `begingRegistration(user:)` which then returns a
86
-
new `PublicKeyCredentialRequestOptions`. This must be send back to the client so it can pass it to
87
-
`navigator.credentials.create()`.
88
-
89
-
2. Whatever `navigator.credentials.create()` returns will be send back to the backend, parsing it into
90
-
`RegistrationCredential`.
91
-
```swift
92
-
let registrationCredential =try req.content.decode(RegistrationCredential.self)
93
-
```
94
-
95
-
3. Next the backend calls `finishRegistration(challenge:credentialCreationData:)` with the previously
96
-
generated challenge and the received `RegistrationCredential`. If `finishRegistration` succeeds a new `Credential`
97
-
object will be returned. This object contains information about the new credential, including an id and the generated public-key. Persist this data in e.g. a database and link the entry to the user.
98
-
99
-
##### Example implementation (using Vapor)
100
-
101
-
```swift
102
-
authSessionRoutes.get("makeCredential") { req -> PublicKeyCredentialCreationOptions in
103
-
let user =try req.auth.require(User.self)
104
-
let options =try req.webAuthn.beginRegistration(user: user)
105
-
req.session.data["challenge"] = options.challenge
106
-
return options
107
-
}
108
-
109
-
authSessionRoutes.post("makeCredential") { req -> HTTPStatus in
Generally, the library makes the following assumptions about how a Relying Party implementing this library will
13
+
interface with a client that will handle calling the WebAuthn API:
14
+
15
+
1. JSON is the preferred data type for transmitting registration and authentication options from the server to
16
+
the client to feed to `navigator.credentials.create()` and `navigator.credentials.get()` respectively.
17
+
18
+
2. JSON is the preferred data type for transmitting WebAuthn responses from the client to the Relying Party.
19
+
20
+
3. Bytes are not directly transmittable in either direction as JSON, and so should be encoded to and decoded
21
+
using Base64 URL encoding. To make life a little bit easier ``URLEncodedBase64`` and ``EncodedBase64`` indicate whether a `String` is currently encoded or not.
22
+
23
+
## Limitations
24
+
25
+
There are a few things this library currently does **not** support:
26
+
27
+
1. Currently RSA public keys are not support, we do however plan to add support for that. RSA keys are necessary for
28
+
compatibility with Microsoft Windows platform authenticators.
29
+
30
+
2. Octet key pairs are not supported.
31
+
32
+
3. Attestation verification is currently not supported, we do however plan to add support for that. Some work has been
33
+
done already, but there are more pieces missing. In most cases attestation verification is not recommended since it
34
+
causes a lot of overhead. [From Yubico](https://developers.yubico.com/WebAuthn/WebAuthn_Developer_Guide/Attestation.html):
35
+
> "If a service does not have a specific need for attestation information, namely a well defined policy for what to
36
+
do with it and why, it is not recommended to verify authenticator attestations"
37
+
38
+
### Setup
39
+
40
+
Configure your backend with a ``WebAuthnManager`` instance:
41
+
42
+
```swift
43
+
app.webAuthn=WebAuthnManager(
44
+
config: WebAuthnConfig(
45
+
relyingPartyDisplayName: "My Fancy Web App",
46
+
relyingPartyID: "example.com",
47
+
relyingPartyOrigin: "https://example.com",
48
+
timeout: 600
49
+
)
50
+
)
51
+
```
52
+
53
+
### Registration
54
+
55
+
Scenario: A user wants to signup on a website using WebAuthn.
56
+
57
+

58
+
59
+
#### Explanation
60
+
61
+
1. When tapping the "Register" button the client sends a request to
62
+
the backend. The backend responds to this request with a call to `begingRegistration(user:)` which then returns a
63
+
new ``PublicKeyCredentialRequestOptions``. This must be send back to the client so it can pass it to
64
+
`navigator.credentials.create()`.
65
+
66
+
2. Whatever `navigator.credentials.create()` returns will be send back to the backend, parsing it into
67
+
``RegistrationCredential``.
68
+
```swift
69
+
let registrationCredential =try req.content.decode(RegistrationCredential.self)
70
+
```
71
+
72
+
3. Next the backend calls `finishRegistration(challenge:credentialCreationData:)` with the previously
73
+
generated challenge and the received ``RegistrationCredential``. If `finishRegistration` succeeds a new ``Credential``
74
+
object will be returned. This object contains information about the new credential, including an id and the generated public-key. Persist this data in e.g. a database and link the entry to the user.
75
+
76
+
##### Example implementation (using Vapor)
77
+
78
+
```swift
79
+
authSessionRoutes.get("makeCredential") { req -> PublicKeyCredentialCreationOptions in
80
+
let user =try req.auth.require(User.self)
81
+
let options =try req.webAuthn.beginRegistration(user: user)
82
+
req.session.data["challenge"] = options.challenge
83
+
return options
84
+
}
85
+
86
+
authSessionRoutes.post("makeCredential") { req -> HTTPStatus in
0 commit comments