Skip to content

Commit 42f5a2d

Browse files
committed
Release 1.0.0
- First stable release - Improved documentation
2 parents 5ef8581 + fe56a7b commit 42f5a2d

File tree

9 files changed

+715
-18
lines changed

9 files changed

+715
-18
lines changed

.travis.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
language: java
22

3+
branches:
4+
except:
5+
- tmp
6+
37
env:
48
global:
59
secure: sX5sJd2EUgzIT7uQN0YxA3faVHymBG/QPZ/St5IPqoQIXjZAMYBM0D1MrVOYaSOhgVKOJt+5vwCYU7MlY9Ha0rUPJgUPT+6CkVgUVCsQ1e8srAzaYp4ceIYaW2XpUIwhKHPBezulV3nLANRs0FibEN+eqTgL5A/qKtsU49BtQ1iUAVFFOzGcR48avo1UYxS0FLw+7MRLgH5NA6KJVHiGChx9P3oLYAhPylgDzRv6iFf5H5v9azQI4eLo6bSQwm++j0UpH4t8m+at7eGuzNsadYY0M9SoUwuJxQZiwtImYJJtGJD92QtV9m+yny4+RocXchgZDj3e9vx06ZqXaeF3U3o49YUX5ACerVV12yOxGZsuuxfevaQa9Mk4xEOwGkhva5I+8vfo8MRxm7ymelExn25zpsMlmj6GjBio3z1q/FGYdyXrcGoVNrvAgozs+0yW2jYtDVo7DNu8J2mur/C/gmi+xA6rkuEJQIQ3hWuWYVe7DUzdii5MG9/9AdwI14b3uyezh1EJ8tza5MScDQijTvD9sGxarruKS59VuJapqrJSU5E87CnlU6gQx7qXJVGvpTXZOw7ZzsdszSDQ3Jc9uNBSdtBQ2i7egEyTE+RQWsdtje/H0s3ZYyIw8qrQ1kIUDQKk7jl8Uvwf+zn/36JBgZMVIIO0hmDFnyB9wBGd7lk=

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
== Version 1.0.0 ==
22

33
* Fixed URL in artifact POM
4+
* Improved a few javadoc wordings
45

56

67
== Version 0.8.0 ==

README

Lines changed: 286 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
== java-webauthn-server
2-
3-
_Note: This is a work in progress. The https://www.w3.org/TR/webauthn/[Web
4-
Authentication standard] is not yet finished, and additional pre-1.0 releases of
5-
this library may introduce breaking API changes._
1+
java-webauthn-server
2+
====================
3+
:toc:
4+
:toc-placement: macro
5+
:toc-title:
66

77
image:https://travis-ci.org/Yubico/java-webauthn-server.svg?branch=master["Build Status", link="https://travis-ci.org/Yubico/java-webauthn-server"]
88
image:https://coveralls.io/repos/github/Yubico/java-webauthn-server/badge.svg["Coverage Status", link="https://coveralls.io/github/Yubico/java-webauthn-server"]
@@ -14,18 +14,293 @@ for a server to support Web Authentication. This includes registering
1414
authenticators and authenticating registered authenticators.
1515

1616

17-
=== Planned breaking changes
17+
== Table of contents
18+
19+
toc::[]
20+
21+
22+
== Dependency configuration
23+
24+
Maven:
25+
26+
----------
27+
<dependency>
28+
<groupId>com.yubico</groupId>
29+
<artifactId>webauthn-server-core</artifactId>
30+
<version>1.0.0-RC2</version>
31+
<scope>compile</scope>
32+
</dependency>
33+
----------
34+
35+
Gradle:
36+
37+
----------
38+
compile 'com.yubico:webauthn-server-core:1.0.0-RC2'
39+
----------
40+
41+
42+
== Features
43+
44+
- Generates request objects suitable as parameters to
45+
`navigator.credentials.create()` and `.get()`
46+
- Performs all necessary
47+
https://www.w3.org/TR/webauthn/#rp-operations[validation logic] on the
48+
response from the client
49+
- Optionally integrates with a "metadata service" to verify
50+
https://www.w3.org/TR/webauthn/#sctn-attestation[authenticator attestations]
51+
and annotate responses with additional authenticator metadata
52+
53+
54+
=== Non-features
55+
56+
This library has no concept of accounts, sessions, permissions or identity
57+
federation, and it's not an authentication framework; it only deals with
58+
executing the WebAuthn authentication mechanism. Sessions, account management
59+
and other higher level concepts can make use of this authentication mechanism,
60+
but the authentication mechanism alone does not make a security system.
61+
62+
63+
== Documentation
64+
65+
See the
66+
link:https://yubico.github.io/java-webauthn-server/webauthn-server-core/com/yubico/webauthn/package-summary.html[Javadoc]
67+
for in-depth API documentation.
68+
69+
70+
== Quick start
71+
72+
Implement the
73+
link:https://yubico.github.io/java-webauthn-server/webauthn-server-core/com/yubico/webauthn/CredentialRepository.html[`CredentialRepository`]
74+
interface with your database access logic. See
75+
link:https://github.com/Yubico/java-webauthn-server/blob/master/webauthn-server-demo/src/main/java/demo/webauthn/InMemoryRegistrationStorage.java[`InMemoryRegistrationStorage`]
76+
for an example.
77+
78+
Instantiate the
79+
link:https://yubico.github.io/java-webauthn-server/webauthn-server-core/com/yubico/webauthn/RelyingParty.html[`RelyingParty`]
80+
class:
81+
82+
[source,java]
83+
----------
84+
RelyingPartyIdentity rpIdentity = RelyingPartyIdentity.builder()
85+
.id("example.com")
86+
.name("Example Application")
87+
.build();
88+
89+
RelyingParty rp = RelyingParty.builder()
90+
.identity(rpIdentity)
91+
.credentialRepository(new MyCredentialRepository())
92+
.build();
93+
----------
94+
95+
96+
=== Registration
97+
98+
Initiate a registration ceremony:
99+
100+
[source,java]
101+
----------
102+
byte[] userHandle = new byte[64];
103+
random.nextBytes(userHandle);
104+
105+
PublicKeyCredentialCreationOptions request = rp.startRegistration(StartRegistrationOptions.builder()
106+
.user(UserIdentity.builder()
107+
.name("alice")
108+
.displayName("Alice Hypothetical")
109+
.id(new ByteArray(userHandle))
110+
.build())
111+
.build());
112+
----------
113+
114+
Serialize `request` to JSON and send it to the client:
115+
116+
[source,java]
117+
----------
118+
import com.fasterxml.jackson.databind.ObjectMapper;
119+
120+
ObjectMapper jsonMapper = new ObjectMapper()
121+
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
122+
.setSerializationInclusion(Include.NON_ABSENT)
123+
.registerModule(new Jdk8Module());
124+
125+
String json = jsonMapper.writeValueAsString(request);
126+
return json;
127+
----------
128+
129+
Get the response from the client:
130+
131+
[source,java]
132+
----------
133+
String responseJson = /* ... */;
134+
PublicKeyCredential<AuthenticatorAttestationResponse, ClientRegistrationExtensionOutputs> pkc =
135+
jsonMapper.readValue(responseJson, new TypeReference<PublicKeyCredential<AuthenticatorAttestationResponse, ClientRegistrationExtensionOutputs>>(){});
136+
----------
137+
138+
Validate the response:
139+
140+
[source,java]
141+
----------
142+
try {
143+
RegistrationResult result = rp.finishRegistration(FinishRegistrationOptions.builder()
144+
.request(request)
145+
.response(pkc)
146+
.build());
147+
} catch (RegistrationFailedException e) { /* ... */ }
148+
----------
149+
150+
Update your database:
151+
152+
[source,java]
153+
----------
154+
storeCredential("alice", result.getKeyId(), result.getPublicKeyCose());
155+
----------
156+
157+
158+
=== Authentication
159+
160+
Initiate an authentication ceremony:
161+
162+
163+
[source,java]
164+
----------
165+
AssertionRequest request = rp.startAssertion(StartAssertionOptions.builder()
166+
.username(Optional.of("alice"))
167+
.build());
168+
String json = jsonMapper.writeValueAsString(request);
169+
return json;
170+
----------
171+
172+
Validate the response:
173+
174+
[source,java]
175+
----------
176+
String responseJson = /* ... */;
177+
178+
PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs> pkc =
179+
jsonMapper.readValue(responseJson, new TypeReference<PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>>() {
180+
});
181+
182+
try {
183+
AssertionResult result = rp.finishAssertion(FinishAssertionOptions.builder()
184+
.request(request)
185+
.response(pkc)
186+
.build());
187+
188+
if (result.isSuccess()) {
189+
return result.getUsername();
190+
}
191+
} catch (AssertionFailedException e) { /* ... */ }
192+
throw new RuntimeException("Authentication failed");
193+
----------
194+
195+
For more detailed example usage, see
196+
link:webauthn-server-demo[`webauthn-server-demo`] for a complete demo server.
197+
198+
199+
== Architecture
200+
201+
The library tries to place as few requirements on the overall application
202+
architecture as possible. For this reason it is stateless and free from side
203+
effects, and does not directly interact with any database. This means it is
204+
database agnostic and thread safe. The following diagram illustrates an example
205+
architecture for an application using the library.
206+
207+
image::https://raw.githubusercontent.com/Yubico/java-webauthn-server/master/docs/img/demo-architecture.svg["Example application architecture",align="center"]
208+
209+
The application manages all state and database access, and communicates with the
210+
library via POJO representations of requests and responses. The following
211+
diagram illustrates the data flow during a WebAuthn registration or
212+
authentication ceremony.
213+
214+
image::https://raw.githubusercontent.com/Yubico/java-webauthn-server/master/docs/img/demo-sequence-diagram.svg["WebAuthn ceremony sequence diagram",align="center"]
215+
216+
In this diagram, the *Client* is the user's browser and the application's
217+
client-side scripts. The *Server* is the application and its business logic, the
218+
*Library* is this library, and the *Users* database stores registered WebAuthn
219+
credentials.
220+
221+
. The client requests to start the ceremony, for example by submitting a form.
222+
The `username` may or may not be known at this point. For example, the user
223+
might be requesting to create a new account, or we might be using
224+
username-less authentication.
225+
226+
. If the user does not already have a
227+
https://www.w3.org/TR/webauthn/#user-handle[user handle], the application
228+
creates one in some application-specific way.
229+
230+
. The application may choose to authenticate the user with a password or the
231+
like before proceeding.
232+
233+
. The application calls one of the library's "start" methods to generate a
234+
parameter object to be passed to `navigator.credentials.create()` or `.get()`
235+
on the client.
236+
237+
. The library generates a random challenge and an assortment of other arguments
238+
depending on configuration set by the application.
239+
240+
. If the `username` is known, the library uses a read-only database adapter
241+
provided by the application to look up the user's credentials.
242+
243+
. The returned list of https://www.w3.org/TR/webauthn/#credential-id[credential
244+
IDs] is used to populate the
245+
https://www.w3.org/TR/webauthn/#dom-publickeycredentialcreationoptions-excludecredentials[`excludeCredentials`]
246+
or
247+
https://www.w3.org/TR/webauthn/#dom-publickeycredentialrequestoptions-allowcredentials[`allowCredentials`]
248+
parameter.
249+
250+
. The library returns a `request` object which can be serialized to JSON and
251+
passed as the `publicKey` argument to `navigator.credentials.create()` or
252+
`.get()`. For registration ceremonies this will be a
253+
https://www.w3.org/TR/webauthn/#dictdef-publickeycredentialcreationoptions[`PublicKeyCredentialCreationOptions`],
254+
and for authentication ceremonies it will be a
255+
https://www.w3.org/TR/webauthn/#dictdef-publickeycredentialrequestoptions[`PublicKeyCredentialRequestOptions`].
256+
The application stores the `request` in temporary storage.
257+
258+
. The application's client-side script runs `navigator.credentials.create()` or
259+
`.get()` with `response` as the `publicKey` argument.
260+
261+
. The user confirms the operation and the client returns a
262+
https://www.w3.org/TR/webauthn/#public-key-credential[`PublicKeyCredential`]
263+
object `response` to the application.
264+
265+
. The application retrieves the `request` from temporary storage and passes
266+
`request` and `response` to one of the library's "finish" methods to run the
267+
response validation logic.
268+
269+
. The library verifies that the `response` contents - challenge, origin, etc. -
270+
are valid.
271+
272+
. If this is an authentication ceremony, the library uses the database adapter
273+
to look up the public key for the credential named in `response.id`.
274+
275+
. The database adapter returns the public key.
276+
277+
. The library verifies the authentication signature.
278+
279+
. The library returns a POJO representation of the result of the ceremony. For
280+
registration ceremonies, this will include the credential ID and public key of
281+
the new credential. The application may also opt in to also getting
282+
information about the authenticator model and whether the authenticator
283+
attestation is trusted. For authentication ceremonies, this will include the
284+
username and user handle, the credential ID of the credential used, and the
285+
new https://www.w3.org/TR/webauthn/#signature-counter[signature counter] value
286+
for the credential.
287+
288+
. The application inspects the result object and takes any appropriate actions
289+
as defined by its business logic.
18290

19-
None.
291+
. If the result is not satisfactory, the application reports failure to the
292+
client.
20293

294+
. If the result is satisfactory, the application proceeds with storing the new
295+
credential if this is a registration ceremony.
21296

22-
=== Example Usage
297+
. If this is an authentication ceremony, the application updates the signature
298+
counter stored in the database for the credential.
23299

24-
See link:webauthn-server-demo[`webauthn-server-demo`] for a complete demo
25-
server, which stores authenticator registrations temporarily in memory.
300+
. Finally, the application reports success and resumes its business logic.
26301

27302

28-
=== Building
303+
== Building
29304

30305
Use the included
31306
https://docs.gradle.org/current/userguide/gradle_wrapper.html[Gradle wrapper] to

0 commit comments

Comments
 (0)