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
1 changed files with 112 additions and 8 deletions

View File

@ -68,18 +68,26 @@ You can easily construct an instance of `DelegatingPasswordEncoder` using `Pass
.Create Default DelegatingPasswordEncoder
====
[source,java]
.Java
[source,java,role="primary"]
----
PasswordEncoder passwordEncoder =
PasswordEncoderFactories.createDelegatingPasswordEncoder();
----
.Kotlin
[source,kotlin,role="secondary"]
----
val passwordEncoder: PasswordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder()
----
====
Alternatively, you may create your own custom instance. For example:
.Create Custom DelegatingPasswordEncoder
====
[source,java]
.Java
[source,java,role="primary"]
----
String idForEncode = "bcrypt";
Map encoders = new HashMap<>();
@ -92,6 +100,20 @@ encoders.put("sha256", new StandardPasswordEncoder());
PasswordEncoder passwordEncoder =
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]]
@ -180,7 +202,8 @@ There are convenience mechanisms to make this easier, but this is still not inte
.withDefaultPasswordEncoder Example
====
[source,java,attrs="-attributes"]
.Java
[source,java,role="primary",attrs="-attributes"]
----
User user = User.withDefaultPasswordEncoder()
.username("user")
@ -190,13 +213,26 @@ User user = User.withDefaultPasswordEncoder()
System.out.println(user.getPassword());
// {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.
.withDefaultPasswordEncoder Reusing the Builder
====
[source,java]
.Java
[source,java,role="primary"]
----
UserBuilder users = User.withDefaultPasswordEncoder();
User user = users
@ -210,6 +246,22 @@ User admin = users
.roles("USER","ADMIN")
.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.
@ -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.
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
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(16);
@ -281,6 +336,16 @@ String result = encoder.encode("myPassword");
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]]
== 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.
The current implementation if the `Argon2PasswordEncoder` requires BouncyCastle.
[source,java]
.Argon2PasswordEncoder
====
.Java
[source,java,role="primary"]
----
// Create an encoder with all the defaults
Argon2PasswordEncoder encoder = new Argon2PasswordEncoder();
@ -298,6 +366,16 @@ String result = encoder.encode("myPassword");
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]]
== 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.
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
Pbkdf2PasswordEncoder encoder = new Pbkdf2PasswordEncoder();
@ -314,6 +395,16 @@ String result = encoder.encode("myPassword");
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]]
== 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.
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
SCryptPasswordEncoder encoder = new SCryptPasswordEncoder();
@ -329,6 +423,16 @@ String result = encoder.encode("myPassword");
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]]
== Other PasswordEncoders