mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-05-30 16:52:13 +00:00
Add password storage Kotlin samples to docs
Issue gh-8172
This commit is contained in:
parent
10c66d282a
commit
2c103f34e3
@ -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
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user