37
37
38
38
/**
39
39
* A combination of a {@link PublicKeyCredentialRequestOptions} and, optionally, a {@link
40
- * #getUsername() username}.
40
+ * #getUsername() username} or {@link #getUserHandle() user handle} .
41
41
*/
42
42
@ Value
43
43
@ Builder (toBuilder = true )
@@ -52,26 +52,58 @@ public class AssertionRequest {
52
52
/**
53
53
* The username of the user to authenticate, if the user has already been identified.
54
54
*
55
- * <p>If this is absent, this indicates that this is a request for an assertion by a <a
55
+ * <p>This is mutually exclusive with {@link #getUserHandle() userHandle}; setting this will unset
56
+ * {@link #getUserHandle() userHandle}. When parsing from JSON, {@link #getUserHandle()
57
+ * userHandle} takes precedence over this.
58
+ *
59
+ * <p>If both this and {@link #getUserHandle() userHandle} are empty, this indicates that this is
60
+ * a request for an assertion by a <a
56
61
* href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#client-side-discoverable-public-key-credential-source">client-side-resident
57
62
* credential</a>, and identification of the user has been deferred until the response is
58
63
* received.
59
64
*/
60
65
private final String username ;
61
66
67
+ /**
68
+ * The user handle of the user to authenticate, if the user has already been identified.
69
+ *
70
+ * <p>This is mutually exclusive with {@link #getUsername() username}; setting this will unset
71
+ * {@link #getUsername() username}. When parsing from JSON, this takes precedence over {@link
72
+ * #getUsername() username}.
73
+ *
74
+ * <p>If both this and {@link #getUsername() username} are empty, this indicates that this is a
75
+ * request for an assertion by a <a
76
+ * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#client-side-discoverable-public-key-credential-source">client-side-resident
77
+ * credential</a>, and identification of the user has been deferred until the response is
78
+ * received.
79
+ */
80
+ private final ByteArray userHandle ;
81
+
62
82
@ JsonCreator
63
83
private AssertionRequest (
64
84
@ NonNull @ JsonProperty ("publicKeyCredentialRequestOptions" )
65
85
PublicKeyCredentialRequestOptions publicKeyCredentialRequestOptions ,
66
- @ JsonProperty ("username" ) String username ) {
86
+ @ JsonProperty ("username" ) String username ,
87
+ @ JsonProperty ("userHandle" ) ByteArray userHandle ) {
67
88
this .publicKeyCredentialRequestOptions = publicKeyCredentialRequestOptions ;
68
- this .username = username ;
89
+
90
+ if (userHandle != null ) {
91
+ this .username = null ;
92
+ this .userHandle = userHandle ;
93
+ } else {
94
+ this .username = username ;
95
+ this .userHandle = null ;
96
+ }
69
97
}
70
98
71
99
/**
72
100
* The username of the user to authenticate, if the user has already been identified.
73
101
*
74
- * <p>If this is absent, this indicates that this is a request for an assertion by a <a
102
+ * <p>This is mutually exclusive with {@link #getUserHandle()}; if this is present, then {@link
103
+ * #getUserHandle()} will be empty.
104
+ *
105
+ * <p>If both this and {@link #getUserHandle()} are empty, this indicates that this is a request
106
+ * for an assertion by a <a
75
107
* href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#client-side-discoverable-public-key-credential-source">client-side-resident
76
108
* credential</a>, and identification of the user has been deferred until the response is
77
109
* received.
@@ -80,6 +112,22 @@ public Optional<String> getUsername() {
80
112
return Optional .ofNullable (username );
81
113
}
82
114
115
+ /**
116
+ * The user handle of the user to authenticate, if the user has already been identified.
117
+ *
118
+ * <p>This is mutually exclusive with {@link #getUsername()}; if this is present, then {@link
119
+ * #getUsername()} will be empty.
120
+ *
121
+ * <p>If both this and {@link #getUsername()} are empty, this indicates that this is a request for
122
+ * an assertion by a <a
123
+ * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#client-side-discoverable-public-key-credential-source">client-side-resident
124
+ * credential</a>, and identification of the user has been deferred until the response is
125
+ * received.
126
+ */
127
+ public Optional <ByteArray > getUserHandle () {
128
+ return Optional .ofNullable (userHandle );
129
+ }
130
+
83
131
/**
84
132
* Serialize this {@link AssertionRequest} value to JSON suitable for sending to the client.
85
133
*
@@ -140,6 +188,7 @@ public static AssertionRequestBuilder.MandatoryStages builder() {
140
188
141
189
public static class AssertionRequestBuilder {
142
190
private String username = null ;
191
+ private ByteArray userHandle = null ;
143
192
144
193
public static class MandatoryStages {
145
194
private final AssertionRequestBuilder builder = new AssertionRequestBuilder ();
@@ -161,7 +210,10 @@ public AssertionRequestBuilder publicKeyCredentialRequestOptions(
161
210
/**
162
211
* The username of the user to authenticate, if the user has already been identified.
163
212
*
164
- * <p>If this is absent, this indicates that this is a request for an assertion by a <a
213
+ * <p>This is mutually exclusive with {@link #userHandle(ByteArray)}; setting this to non-empty
214
+ * will unset {@link #userHandle(ByteArray)}.
215
+ *
216
+ * <p>If this is empty, this indicates that this is a request for an assertion by a <a
165
217
* href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#client-side-discoverable-public-key-credential-source">client-side-resident
166
218
* credential</a>, and identification of the user has been deferred until the response is
167
219
* received.
@@ -173,13 +225,55 @@ public AssertionRequestBuilder username(@NonNull Optional<String> username) {
173
225
/**
174
226
* The username of the user to authenticate, if the user has already been identified.
175
227
*
176
- * <p>If this is absent, this indicates that this is a request for an assertion by a <a
228
+ * <p>This is mutually exclusive with {@link #userHandle(ByteArray)}; setting this to non-<code>
229
+ * null</code> will unset {@link #userHandle(ByteArray)}.
230
+ *
231
+ * <p>If this is empty, this indicates that this is a request for an assertion by a <a
177
232
* href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#client-side-discoverable-public-key-credential-source">client-side-resident
178
233
* credential</a>, and identification of the user has been deferred until the response is
179
234
* received.
180
235
*/
181
236
public AssertionRequestBuilder username (String username ) {
182
237
this .username = username ;
238
+ if (username != null ) {
239
+ this .userHandle = null ;
240
+ }
241
+ return this ;
242
+ }
243
+
244
+ /**
245
+ * The user handle of the user to authenticate, if the user has already been identified.
246
+ *
247
+ * <p>This is mutually exclusive with {@link #username(String)}; setting this to non-empty will
248
+ * unset {@link #username(String)}.
249
+ *
250
+ * <p>If both this and {@link #username(String)} are empty, this indicates that this is a
251
+ * request for an assertion by a <a
252
+ * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#client-side-discoverable-public-key-credential-source">client-side-resident
253
+ * credential</a>, and identification of the user has been deferred until the response is
254
+ * received.
255
+ */
256
+ public AssertionRequestBuilder userHandle (@ NonNull Optional <ByteArray > userHandle ) {
257
+ return this .userHandle (userHandle .orElse (null ));
258
+ }
259
+
260
+ /**
261
+ * The user handle of the user to authenticate, if the user has already been identified.
262
+ *
263
+ * <p>This is mutually exclusive with {@link #username(String)}; setting this to non-<code>null
264
+ * </code> will unset {@link #username(String)}.
265
+ *
266
+ * <p>If both this and {@link #username(String)} are empty, this indicates that this is a
267
+ * request for an assertion by a <a
268
+ * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#client-side-discoverable-public-key-credential-source">client-side-resident
269
+ * credential</a>, and identification of the user has been deferred until the response is
270
+ * received.
271
+ */
272
+ public AssertionRequestBuilder userHandle (ByteArray userHandle ) {
273
+ if (userHandle != null ) {
274
+ this .username = null ;
275
+ }
276
+ this .userHandle = userHandle ;
183
277
return this ;
184
278
}
185
279
}
0 commit comments