Skip to content

Commit 71b78cb

Browse files
authored
update docc documentation (#29)
1 parent a823806 commit 71b78cb

File tree

3 files changed

+28
-33
lines changed

3 files changed

+28
-33
lines changed

Sources/WebAuthn/Docs.docc/Example Implementation.md

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,16 @@ Explains how to use this library in a server <-> website scenario.
44

55
The library exposes four methods through ``WebAuthnManager``:
66

7-
- ``WebAuthnManager/beginRegistration(user:timeout:attestation:publicKeyCredentialParameters:)``
7+
- ``WebAuthnManager/beginRegistration(user:timeoutInSeconds:attestation:publicKeyCredentialParameters:)``
88
- ``WebAuthnManager/finishRegistration(challenge:credentialCreationData:requireUserVerification:supportedPublicKeyAlgorithms:pemRootCertificatesByFormat:confirmCredentialIDNotRegisteredYet:)``
9-
- ``WebAuthnManager/beginAuthentication(challenge:timeout:allowCredentials:userVerification:)``
9+
- ``WebAuthnManager/beginAuthentication(timeout:allowCredentials:userVerification:)``
1010
- ``WebAuthnManager/finishAuthentication(credential:expectedChallenge:credentialPublicKey:credentialCurrentSignCount:requireUserVerification:)``
1111

12-
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.
12+
> Important information in advance:
13+
Because bytes are not directly transmittable in either direction as JSON this library provides custom `Codable` implementations for a few types.
14+
When using `Codable` to encode ``PublicKeyCredentialCreationOptions`` and ``PublicKeyCredentialRequestOptions`` byte array properties will be encoded to base64url strings.
15+
When using `Codable` to decode ``RegistrationCredential`` and ``AuthenticationCredential`` base64url encoded strings will be decoded to byte arrays.
16+
When data transmission happens without JSON (e.g. through GRPC) the byte arrays can be transmitted directly. In that case don't use the default `Codable` implementation provided by this library.
2217

2318
## Limitations
2419

@@ -31,21 +26,20 @@ There are a few things this library currently does **not** support:
3126

3227
3. Attestation verification is currently not supported, we do however plan to add support for that. Some work has been
3328
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
29+
causes a lot of overhead.
30+
> [From Yubico](https://developers.yubico.com/WebAuthn/WebAuthn_Developer_Guide/Attestation.html): "If a service does not have a specific need for attestation information, namely a well defined policy for what to
3631
do with it and why, it is not recommended to verify authenticator attestations"
3732

3833
### Setup
3934

4035
Configure your backend with a ``WebAuthnManager`` instance:
4136

4237
```swift
43-
app.webAuthn = WebAuthnManager(
44-
config: WebAuthnConfig(
45-
relyingPartyDisplayName: "My Fancy Web App",
38+
let webAuthnManager = WebAuthnManager(
39+
config: .init(
4640
relyingPartyID: "example.com",
47-
relyingPartyOrigin: "https://example.com",
48-
timeout: 600
41+
relyingPartyName: "My Fancy Web App",
42+
relyingPartyOrigin: "https://example.com"
4943
)
5044
)
5145
```
@@ -59,18 +53,18 @@ Scenario: A user wants to signup on a website using WebAuthn.
5953
#### Explanation
6054

6155
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
56+
the backend. The relying party responds to this request with a call to ``WebAuthnManager/beginRegistration(user:timeoutInSeconds:attestation:publicKeyCredentialParameters:)`` which then returns a
6357
new ``PublicKeyCredentialRequestOptions``. This must be send back to the client so it can pass it to
6458
`navigator.credentials.create()`.
6559

66-
2. Whatever `navigator.credentials.create()` returns will be send back to the backend, parsing it into
60+
2. Whatever `navigator.credentials.create()` returns will be send back to the relying party, parsing it into
6761
``RegistrationCredential``.
6862
```swift
69-
let registrationCredential = try req.content.decode(RegistrationCredential.self)
63+
let registrationCredential = try JSONDecoder().decode(RegistrationCredential.self)
7064
```
7165

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``
66+
3. Next the backend calls ``WebAuthnManager/finishRegistration(challenge:credentialCreationData:requireUserVerification:supportedPublicKeyAlgorithms:pemRootCertificatesByFormat:confirmCredentialIDNotRegisteredYet:)`` with the previously
67+
generated challenge and the received ``RegistrationCredential``. If no error are thrown a new ``Credential``
7468
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.
7569

7670
##### Example implementation (using Vapor)
@@ -113,13 +107,13 @@ Scenario: A user wants to log in on a website using WebAuthn.
113107
#### Explanation
114108

115109
1. When tapping the "Login" button the client sends a request to
116-
the backend. The backend responds to this request with a call to `beginAuthentication()` which then in turn
110+
the relying party. The relying party responds to this request with a call to ``WebAuthnManager/beginAuthentication(timeout:allowCredentials:userVerification:)`` which then in turn
117111
returns a new ``PublicKeyCredentialRequestOptions``. This must be sent back to the client so it can pass it to
118112
`navigator.credentials.get()`.
119-
2. Whatever `navigator.credentials.get()` returns will be sent back to the backend, parsing it into
113+
2. Whatever `navigator.credentials.get()` returns will be sent back to the relying party, parsing it into
120114
``AuthenticationCredential``.
121115
```swift
122-
let authenticationCredential = try req.content.decode(AuthenticationCredential.self)
116+
let authenticationCredential = try JSONDecoder().decode(AuthenticationCredential.self)
123117
```
124118
3. Next the backend calls
125119
``WebAuthnManager/finishAuthentication(credential:expectedChallenge:credentialPublicKey:credentialCurrentSignCount:requireUserVerification:)``.
@@ -134,7 +128,7 @@ Scenario: A user wants to log in on a website using WebAuthn.
134128
will return a `VerifiedAuthentication` with the updated sign count and a few other pieces of information to be
135129
persisted. Use this to update the credential in the database.
136130

137-
#### Example implementation
131+
#### Example implementation (using Vapor)
138132

139133
```swift
140134
// this endpoint will be called on clicking "Login"
@@ -155,10 +149,13 @@ authSessionRoutes.post("authenticate") { req -> HTTPStatus in
155149
let verifiedAuthentication = try req.webAuthn.finishAuthentication(
156150
credential: data,
157151
expectedChallenge: challenge,
158-
credentialPublicKey: [UInt8](credential.publicKey.base64URLDecodedData!),
159-
credentialCurrentSignCount: 0
152+
credentialPublicKey: credential.publicKey,
153+
credentialCurrentSignCount: credential.currentSignCount
160154
)
161155

156+
credential.currentSignCount = verifiedAuthentication.newSignCount
157+
try await credential.save(on: req.db)
158+
162159
req.auth.login(credential.user)
163160

164161
return .ok

Sources/WebAuthn/Docs.docc/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ the corresponding user in a database.
2323
### Essentials
2424

2525
- ``WebAuthnManager``
26-
- ``WebAuthnConfig``
26+
- ``WebAuthnManager/Config``
2727
- ``PublicKeyCredentialUserEntity``
2828

2929
### Responses

Sources/WebAuthn/WebAuthnManager.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,6 @@ public struct WebAuthnManager {
132132
/// Generate options for retrieving a credential via navigator.credentials.get()
133133
///
134134
/// - Parameters:
135-
/// - challenge: Optionally generate a challenge on your own. Defaults to `nil` which will let the library
136-
/// generate it.
137135
/// - timeout: How long the browser should give the user to choose an authenticator. This value
138136
/// is a *hint* and may be ignored by the browser. Defaults to 60 seconds.
139137
/// - allowCredentials: A list of credentials registered to the user.

0 commit comments

Comments
 (0)