Add password storage Kotlin samples to docs

Issue gh-8172
This commit is contained in:
Eleftheria Stein 2020-03-24 10:29:11 -04:00
parent 10c66d282a
commit 2c103f34e3

View File

@ -68,18 +68,26 @@ You can easily construct an instance of `DelegatingPasswordEncoder` using `Pass
.Create Default DelegatingPasswordEncoder .Create Default DelegatingPasswordEncoder
==== ====
[source,java] .Java
[source,java,role="primary"]
---- ----
PasswordEncoder passwordEncoder = PasswordEncoder passwordEncoder =
PasswordEncoderFactories.createDelegatingPasswordEncoder(); PasswordEncoderFactories.createDelegatingPasswordEncoder();
---- ----
.Kotlin
[source,kotlin,role="secondary"]
----
val passwordEncoder: PasswordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder()
----
==== ====
Alternatively, you may create your own custom instance. For example: Alternatively, you may create your own custom instance. For example:
.Create Custom DelegatingPasswordEncoder .Create Custom DelegatingPasswordEncoder
==== ====
[source,java] .Java
[source,java,role="primary"]
---- ----
String idForEncode = "bcrypt"; String idForEncode = "bcrypt";
Map encoders = new HashMap<>(); Map encoders = new HashMap<>();
@ -92,6 +100,20 @@ encoders.put("sha256", new StandardPasswordEncoder());
PasswordEncoder passwordEncoder = PasswordEncoder passwordEncoder =
new DelegatingPasswordEncoder(idForEncode, encoders); new DelegatingPasswordEncoder(idForEncode, encoders);
---- ----
.Kotlin
[source,kotlin,role="secondary"]
----
val idForEncode = "bcrypt"
val encoders: MutableMap<String, PasswordEncoder> = mutableMapOf()
encoders[idForEncode] = BCryptPasswordEncoder()
encoders["noop"] = NoOpPasswordEncoder.getInstance()
encoders["pbkdf2"] = Pbkdf2PasswordEncoder()
encoders["scrypt"] = SCryptPasswordEncoder()
encoders["sha256"] = StandardPasswordEncoder()
val passwordEncoder: PasswordEncoder = DelegatingPasswordEncoder(idForEncode, encoders)
----
==== ====
[[authentication-password-storage-dpe-format]] [[authentication-password-storage-dpe-format]]
@ -180,7 +202,8 @@ There are convenience mechanisms to make this easier, but this is still not inte
.withDefaultPasswordEncoder Example .withDefaultPasswordEncoder Example
==== ====
[source,java,attrs="-attributes"] .Java
[source,java,role="primary",attrs="-attributes"]
---- ----
User user = User.withDefaultPasswordEncoder() User user = User.withDefaultPasswordEncoder()
.username("user") .username("user")
@ -190,13 +213,26 @@ User user = User.withDefaultPasswordEncoder()
System.out.println(user.getPassword()); System.out.println(user.getPassword());
// {bcrypt}$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG // {bcrypt}$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG
---- ----
.Kotlin
[source,kotlin,role="secondary",attrs="-attributes"]
----
val user = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("user")
.build()
println(user.password)
// {bcrypt}$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG
----
==== ====
If you are creating multiple users, you can also reuse the builder. If you are creating multiple users, you can also reuse the builder.
.withDefaultPasswordEncoder Reusing the Builder .withDefaultPasswordEncoder Reusing the Builder
==== ====
[source,java] .Java
[source,java,role="primary"]
---- ----
UserBuilder users = User.withDefaultPasswordEncoder(); UserBuilder users = User.withDefaultPasswordEncoder();
User user = users User user = users
@ -210,6 +246,22 @@ User admin = users
.roles("USER","ADMIN") .roles("USER","ADMIN")
.build(); .build();
---- ----
.Kotlin
[source,kotlin,role="secondary"]
----
val users = User.withDefaultPasswordEncoder()
val user = users
.username("user")
.password("password")
.roles("USER")
.build()
val admin = users
.username("admin")
.password("password")
.roles("USER", "ADMIN")
.build()
----
==== ====
This does hash the password that is stored, but the passwords are still exposed in memory and in the compiled source code. This does hash the password that is stored, but the passwords are still exposed in memory and in the compiled source code.
@ -273,7 +325,10 @@ The `BCryptPasswordEncoder` implementation uses the widely supported https://en.
In order to make it more resistent to password cracking, bcrypt is deliberately slow. In order to make it more resistent to password cracking, bcrypt is deliberately slow.
Like other adaptive one-way functions, it should be tuned to take about 1 second to verify a password on your system. Like other adaptive one-way functions, it should be tuned to take about 1 second to verify a password on your system.
[source,java] .BCryptPasswordEncoder
====
.Java
[source,java,role="primary"]
---- ----
// Create an encoder with strength 16 // Create an encoder with strength 16
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(16); BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(16);
@ -281,6 +336,16 @@ String result = encoder.encode("myPassword");
assertTrue(encoder.matches("myPassword", result)); assertTrue(encoder.matches("myPassword", result));
---- ----
.Kotlin
[source,kotlin,role="secondary"]
----
// Create an encoder with strength 16
val encoder = BCryptPasswordEncoder(16)
val result: String = encoder.encode("myPassword")
assertTrue(encoder.matches("myPassword", result))
----
====
[[authentication-password-storage-argon2]] [[authentication-password-storage-argon2]]
== Argon2PasswordEncoder == Argon2PasswordEncoder
@ -290,7 +355,10 @@ In order to defeat password cracking on custom hardware, Argon2 is a deliberatel
Like other adaptive one-way functions, it should be tuned to take about 1 second to verify a password on your system. Like other adaptive one-way functions, it should be tuned to take about 1 second to verify a password on your system.
The current implementation if the `Argon2PasswordEncoder` requires BouncyCastle. The current implementation if the `Argon2PasswordEncoder` requires BouncyCastle.
[source,java] .Argon2PasswordEncoder
====
.Java
[source,java,role="primary"]
---- ----
// Create an encoder with all the defaults // Create an encoder with all the defaults
Argon2PasswordEncoder encoder = new Argon2PasswordEncoder(); Argon2PasswordEncoder encoder = new Argon2PasswordEncoder();
@ -298,6 +366,16 @@ String result = encoder.encode("myPassword");
assertTrue(encoder.matches("myPassword", result)); assertTrue(encoder.matches("myPassword", result));
---- ----
.Kotlin
[source,kotlin,role="secondary"]
----
// Create an encoder with all the defaults
val encoder = Argon2PasswordEncoder()
val result: String = encoder.encode("myPassword")
assertTrue(encoder.matches("myPassword", result))
----
====
[[authentication-password-storage-pbkdf2]] [[authentication-password-storage-pbkdf2]]
== Pbkdf2PasswordEncoder == Pbkdf2PasswordEncoder
@ -306,7 +384,10 @@ In order to defeat password cracking PBKDF2 is a deliberately slow algorithm.
Like other adaptive one-way functions, it should be tuned to take about 1 second to verify a password on your system. Like other adaptive one-way functions, it should be tuned to take about 1 second to verify a password on your system.
This algorithm is a good choice when FIPS certification is required. This algorithm is a good choice when FIPS certification is required.
[source,java] .Pbkdf2PasswordEncoder
====
.Java
[source,java,role="primary"]
---- ----
// Create an encoder with all the defaults // Create an encoder with all the defaults
Pbkdf2PasswordEncoder encoder = new Pbkdf2PasswordEncoder(); Pbkdf2PasswordEncoder encoder = new Pbkdf2PasswordEncoder();
@ -314,6 +395,16 @@ String result = encoder.encode("myPassword");
assertTrue(encoder.matches("myPassword", result)); assertTrue(encoder.matches("myPassword", result));
---- ----
.Kotlin
[source,kotlin,role="secondary"]
----
// Create an encoder with all the defaults
val encoder = Pbkdf2PasswordEncoder()
val result: String = encoder.encode("myPassword")
assertTrue(encoder.matches("myPassword", result))
----
====
[[authentication-password-storage-scrypt]] [[authentication-password-storage-scrypt]]
== SCryptPasswordEncoder == SCryptPasswordEncoder
@ -321,7 +412,10 @@ The `SCryptPasswordEncoder` implementation uses https://en.wikipedia.org/wiki/Sc
In order to defeat password cracking on custom hardware scrypt is a deliberately slow algorithm that requires large amounts of memory. In order to defeat password cracking on custom hardware scrypt is a deliberately slow algorithm that requires large amounts of memory.
Like other adaptive one-way functions, it should be tuned to take about 1 second to verify a password on your system. Like other adaptive one-way functions, it should be tuned to take about 1 second to verify a password on your system.
[source,java] .SCryptPasswordEncoder
====
.Java
[source,java,role="primary"]
---- ----
// Create an encoder with all the defaults // Create an encoder with all the defaults
SCryptPasswordEncoder encoder = new SCryptPasswordEncoder(); SCryptPasswordEncoder encoder = new SCryptPasswordEncoder();
@ -329,6 +423,16 @@ String result = encoder.encode("myPassword");
assertTrue(encoder.matches("myPassword", result)); assertTrue(encoder.matches("myPassword", result));
---- ----
.Kotlin
[source,kotlin,role="secondary"]
----
// Create an encoder with all the defaults
val encoder = SCryptPasswordEncoder()
val result: String = encoder.encode("myPassword")
assertTrue(encoder.matches("myPassword", result))
----
====
[[authentication-password-storage-other]] [[authentication-password-storage-other]]
== Other PasswordEncoders == Other PasswordEncoders