public class DelegatingPasswordEncoder extends java.lang.Object implements PasswordEncoder
PasswordEncoderFactories.
Alternatively, you may create your own custom instance. For example:
String idForEncode = "bcrypt"; Mapencoders = new HashMap<>(); encoders.put(idForEncode, new BCryptPasswordEncoder()); encoders.put("noop", NoOpPasswordEncoder.getInstance()); encoders.put("pbkdf2", new Pbkdf2PasswordEncoder()); encoders.put("scrypt", new SCryptPasswordEncoder()); encoders.put("sha256", new StandardPasswordEncoder()); PasswordEncoder passwordEncoder = new DelegatingPasswordEncoder(idForEncode, encoders);
{id}encodedPassword
Such that "id" is an identifier used to look up which PasswordEncoder should
be used and "encodedPassword" is the original encoded password for the selected
PasswordEncoder. The "id" must be at the beginning of the password, start with
"{" and end with "}". If the "id" cannot be found, the "id" will be null.
For example, the following might be a list of passwords encoded using different "id".
All of the original passwords are "password".
{bcrypt}$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG
{noop}password
{pbkdf2}5d923b44a6d129f3ddf3e3c8d29412723dcbde72445e8ef6bf3b508fbf17fa4ed4d6b99ca763d8dc
{scrypt}$e0801$8bWJaSu2IKSn9Z9kM+TPXfOc/9bdYSrN1oD9qfVThWEwdRTnO7re7Ei+fUZRJ68k9lTyuTeUp4of4g24hHnazw==$OAOec05+bXxvuu/1qZ6NUR+xQYvYv7BeL1QxwRpY5Pc=
{sha256}97cde38028ad898ebc02e690819fa220e88c62e0699403e94fff291cfffaf8410849f27605abcbc0
For the DelegatingPasswordEncoder that we constructed above:
PasswordEncoder id of "bcrypt" and
encodedPassword of "$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG".
When matching it would delegate to
BCryptPasswordEncoderPasswordEncoder id of "noop" and
encodedPassword of "password". When matching it would delegate to
NoOpPasswordEncoderPasswordEncoder id of "pbkdf2" and
encodedPassword of
"5d923b44a6d129f3ddf3e3c8d29412723dcbde72445e8ef6bf3b508fbf17fa4ed4d6b99ca763d8dc".
When matching it would delegate to Pbkdf2PasswordEncoderPasswordEncoder id of "scrypt" and
encodedPassword of
"$e0801$8bWJaSu2IKSn9Z9kM+TPXfOc/9bdYSrN1oD9qfVThWEwdRTnO7re7Ei+fUZRJ68k9lTyuTeUp4of4g24hHnazw==$OAOec05+bXxvuu/1qZ6NUR+xQYvYv7BeL1QxwRpY5Pc="
When matching it would delegate to
SCryptPasswordEncoderPasswordEncoder id of "sha256" and
encodedPassword of
"97cde38028ad898ebc02e690819fa220e88c62e0699403e94fff291cfffaf8410849f27605abcbc0".
When matching it would delegate to StandardPasswordEncoderidForEncode passed into the constructor determines which
PasswordEncoder will be used for encoding passwords. In the
DelegatingPasswordEncoder we constructed above, that means that the result of
encoding "password" would be delegated to BCryptPasswordEncoder and be prefixed
with "{bcrypt}". The end result would look like:
{bcrypt}$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG
PasswordEncoder provided in the constructor. Our example in "Password Storage
Format" provides a working example of how this is done.
By default the result of invoking matches(CharSequence, String) with a
password with an "id" that is not mapped (including a null id) will result in an
IllegalArgumentException. This behavior can be customized using
setDefaultPasswordEncoderForMatches(PasswordEncoder).PasswordEncoderFactories| Constructor and Description |
|---|
DelegatingPasswordEncoder(java.lang.String idForEncode,
java.util.Map<java.lang.String,PasswordEncoder> idToPasswordEncoder)
Creates a new instance
|
| Modifier and Type | Method and Description |
|---|---|
java.lang.String |
encode(java.lang.CharSequence rawPassword)
Encode the raw password.
|
boolean |
matches(java.lang.CharSequence rawPassword,
java.lang.String prefixEncodedPassword)
Verify the encoded password obtained from storage matches the submitted raw
password after it too is encoded.
|
void |
setDefaultPasswordEncoderForMatches(PasswordEncoder defaultPasswordEncoderForMatches)
Sets the
PasswordEncoder to delegate to for
matches(CharSequence, String) if the id is not mapped to a
PasswordEncoder. |
boolean |
upgradeEncoding(java.lang.String encodedPassword)
Returns true if the encoded password should be encoded again for better security,
else false.
|
public DelegatingPasswordEncoder(java.lang.String idForEncode,
java.util.Map<java.lang.String,PasswordEncoder> idToPasswordEncoder)
idForEncode - the id used to lookup which PasswordEncoder should be
used for encode(CharSequence)idToPasswordEncoder - a Map of id to PasswordEncoder used to determine
which PasswordEncoder should be used for matches(CharSequence, String)public void setDefaultPasswordEncoderForMatches(PasswordEncoder defaultPasswordEncoderForMatches)
PasswordEncoder to delegate to for
matches(CharSequence, String) if the id is not mapped to a
PasswordEncoder.
The encodedPassword provided will be the full password
passed in including the {"id"} portion.* For example, if the password of
"{notmapped}foobar" was used, the "id" would be "notmapped" and the encodedPassword
passed into the PasswordEncoder would be "{notmapped}foobar".
defaultPasswordEncoderForMatches - the encoder to use. The default is to
throw an IllegalArgumentExceptionpublic java.lang.String encode(java.lang.CharSequence rawPassword)
PasswordEncoderencode in interface PasswordEncoderpublic boolean matches(java.lang.CharSequence rawPassword,
java.lang.String prefixEncodedPassword)
PasswordEncodermatches in interface PasswordEncoderrawPassword - the raw password to encode and matchprefixEncodedPassword - the encoded password from storage to compare withpublic boolean upgradeEncoding(java.lang.String encodedPassword)
PasswordEncoderupgradeEncoding in interface PasswordEncoderencodedPassword - the encoded password to check