@@ -68,18 +68,26 @@ You can easily construct an instance of `DelegatingPasswordEncoder` using `Pass
68
68
69
69
.Create Default DelegatingPasswordEncoder
70
70
====
71
- [source,java]
71
+ .Java
72
+ [source,java,role="primary"]
72
73
----
73
74
PasswordEncoder passwordEncoder =
74
75
PasswordEncoderFactories.createDelegatingPasswordEncoder();
75
76
----
77
+
78
+ .Kotlin
79
+ [source,kotlin,role="secondary"]
80
+ ----
81
+ val passwordEncoder: PasswordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder()
82
+ ----
76
83
====
77
84
78
85
Alternatively, you may create your own custom instance. For example:
79
86
80
87
.Create Custom DelegatingPasswordEncoder
81
88
====
82
- [source,java]
89
+ .Java
90
+ [source,java,role="primary"]
83
91
----
84
92
String idForEncode = "bcrypt";
85
93
Map encoders = new HashMap<>();
@@ -92,6 +100,20 @@ encoders.put("sha256", new StandardPasswordEncoder());
92
100
PasswordEncoder passwordEncoder =
93
101
new DelegatingPasswordEncoder(idForEncode, encoders);
94
102
----
103
+
104
+ .Kotlin
105
+ [source,kotlin,role="secondary"]
106
+ ----
107
+ val idForEncode = "bcrypt"
108
+ val encoders: MutableMap<String, PasswordEncoder> = mutableMapOf()
109
+ encoders[idForEncode] = BCryptPasswordEncoder()
110
+ encoders["noop"] = NoOpPasswordEncoder.getInstance()
111
+ encoders["pbkdf2"] = Pbkdf2PasswordEncoder()
112
+ encoders["scrypt"] = SCryptPasswordEncoder()
113
+ encoders["sha256"] = StandardPasswordEncoder()
114
+
115
+ val passwordEncoder: PasswordEncoder = DelegatingPasswordEncoder(idForEncode, encoders)
116
+ ----
95
117
====
96
118
97
119
[[authentication-password-storage-dpe-format]]
@@ -180,7 +202,8 @@ There are convenience mechanisms to make this easier, but this is still not inte
180
202
181
203
.withDefaultPasswordEncoder Example
182
204
====
183
- [source,java,attrs="-attributes"]
205
+ .Java
206
+ [source,java,role="primary",attrs="-attributes"]
184
207
----
185
208
User user = User.withDefaultPasswordEncoder()
186
209
.username("user")
@@ -190,13 +213,26 @@ User user = User.withDefaultPasswordEncoder()
190
213
System.out.println(user.getPassword());
191
214
// {bcrypt}$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG
192
215
----
216
+
217
+ .Kotlin
218
+ [source,kotlin,role="secondary",attrs="-attributes"]
219
+ ----
220
+ val user = User.withDefaultPasswordEncoder()
221
+ .username("user")
222
+ .password("password")
223
+ .roles("user")
224
+ .build()
225
+ println(user.password)
226
+ // {bcrypt}$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG
227
+ ----
193
228
====
194
229
195
230
If you are creating multiple users, you can also reuse the builder.
196
231
197
232
.withDefaultPasswordEncoder Reusing the Builder
198
233
====
199
- [source,java]
234
+ .Java
235
+ [source,java,role="primary"]
200
236
----
201
237
UserBuilder users = User.withDefaultPasswordEncoder();
202
238
User user = users
@@ -210,6 +246,22 @@ User admin = users
210
246
.roles("USER","ADMIN")
211
247
.build();
212
248
----
249
+
250
+ .Kotlin
251
+ [source,kotlin,role="secondary"]
252
+ ----
253
+ val users = User.withDefaultPasswordEncoder()
254
+ val user = users
255
+ .username("user")
256
+ .password("password")
257
+ .roles("USER")
258
+ .build()
259
+ val admin = users
260
+ .username("admin")
261
+ .password("password")
262
+ .roles("USER", "ADMIN")
263
+ .build()
264
+ ----
213
265
====
214
266
215
267
This does hash the password that is stored, but the passwords are still exposed in memory and in the compiled source code.
@@ -273,14 +325,27 @@ The `BCryptPasswordEncoder` implementation uses the widely supported https://en.
273
325
In order to make it more resistent to password cracking, bcrypt is deliberately slow.
274
326
Like other adaptive one-way functions, it should be tuned to take about 1 second to verify a password on your system.
275
327
276
- [source,java]
328
+ .BCryptPasswordEncoder
329
+ ====
330
+ .Java
331
+ [source,java,role="primary"]
277
332
----
278
333
// Create an encoder with strength 16
279
334
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(16);
280
335
String result = encoder.encode("myPassword");
281
336
assertTrue(encoder.matches("myPassword", result));
282
337
----
283
338
339
+ .Kotlin
340
+ [source,kotlin,role="secondary"]
341
+ ----
342
+ // Create an encoder with strength 16
343
+ val encoder = BCryptPasswordEncoder(16)
344
+ val result: String = encoder.encode("myPassword")
345
+ assertTrue(encoder.matches("myPassword", result))
346
+ ----
347
+ ====
348
+
284
349
[[authentication-password-storage-argon2]]
285
350
== Argon2PasswordEncoder
286
351
@@ -290,14 +355,27 @@ In order to defeat password cracking on custom hardware, Argon2 is a deliberatel
290
355
Like other adaptive one-way functions, it should be tuned to take about 1 second to verify a password on your system.
291
356
The current implementation if the `Argon2PasswordEncoder` requires BouncyCastle.
292
357
293
- [source,java]
358
+ .Argon2PasswordEncoder
359
+ ====
360
+ .Java
361
+ [source,java,role="primary"]
294
362
----
295
363
// Create an encoder with all the defaults
296
364
Argon2PasswordEncoder encoder = new Argon2PasswordEncoder();
297
365
String result = encoder.encode("myPassword");
298
366
assertTrue(encoder.matches("myPassword", result));
299
367
----
300
368
369
+ .Kotlin
370
+ [source,kotlin,role="secondary"]
371
+ ----
372
+ // Create an encoder with all the defaults
373
+ val encoder = Argon2PasswordEncoder()
374
+ val result: String = encoder.encode("myPassword")
375
+ assertTrue(encoder.matches("myPassword", result))
376
+ ----
377
+ ====
378
+
301
379
[[authentication-password-storage-pbkdf2]]
302
380
== Pbkdf2PasswordEncoder
303
381
@@ -306,29 +384,55 @@ In order to defeat password cracking PBKDF2 is a deliberately slow algorithm.
306
384
Like other adaptive one-way functions, it should be tuned to take about 1 second to verify a password on your system.
307
385
This algorithm is a good choice when FIPS certification is required.
308
386
309
- [source,java]
387
+ .Pbkdf2PasswordEncoder
388
+ ====
389
+ .Java
390
+ [source,java,role="primary"]
310
391
----
311
392
// Create an encoder with all the defaults
312
393
Pbkdf2PasswordEncoder encoder = new Pbkdf2PasswordEncoder();
313
394
String result = encoder.encode("myPassword");
314
395
assertTrue(encoder.matches("myPassword", result));
315
396
----
316
397
398
+ .Kotlin
399
+ [source,kotlin,role="secondary"]
400
+ ----
401
+ // Create an encoder with all the defaults
402
+ val encoder = Pbkdf2PasswordEncoder()
403
+ val result: String = encoder.encode("myPassword")
404
+ assertTrue(encoder.matches("myPassword", result))
405
+ ----
406
+ ====
407
+
317
408
[[authentication-password-storage-scrypt]]
318
409
== SCryptPasswordEncoder
319
410
320
411
The `SCryptPasswordEncoder` implementation uses https://en.wikipedia.org/wiki/Scrypt[scrypt] algorithm to hash the passwords.
321
412
In order to defeat password cracking on custom hardware scrypt is a deliberately slow algorithm that requires large amounts of memory.
322
413
Like other adaptive one-way functions, it should be tuned to take about 1 second to verify a password on your system.
323
414
324
- [source,java]
415
+ .SCryptPasswordEncoder
416
+ ====
417
+ .Java
418
+ [source,java,role="primary"]
325
419
----
326
420
// Create an encoder with all the defaults
327
421
SCryptPasswordEncoder encoder = new SCryptPasswordEncoder();
328
422
String result = encoder.encode("myPassword");
329
423
assertTrue(encoder.matches("myPassword", result));
330
424
----
331
425
426
+ .Kotlin
427
+ [source,kotlin,role="secondary"]
428
+ ----
429
+ // Create an encoder with all the defaults
430
+ val encoder = SCryptPasswordEncoder()
431
+ val result: String = encoder.encode("myPassword")
432
+ assertTrue(encoder.matches("myPassword", result))
433
+ ----
434
+ ====
435
+
332
436
[[authentication-password-storage-other]]
333
437
== Other PasswordEncoders
334
438
0 commit comments