Recipe Name:
Spring Security recommends DelegatingPasswordEncoder for best practices (Bean)
Description:
DelegatingPasswordEncoder allows more flexibility when using several encoders, for code changes, and for migrating
Level:
info
Language:
  • java
  • kotlin
Tags:
  • Spring
  • security
  • framework specific
  • Spring Security
Documentation
Best practices for password encoding are bound to change. Spring Security provides DelegatingPasswordEncoder to facilitate implementing the recommended password storage practices. It allows easy upgrading to a newer encoding, and at the same time permit legacy encoding that cannot be migrated, to remain in the code base.
Before:@Bean public Argon2PasswordEncoder Argon2PasswordEncoder() { return new Argon2PasswordEncoder(); }
After:@Bean public PasswordEncoder delegatingPasswordEncoder() { Map encoders = new HashMap<>(); encoders.put("argon2", new Argon2PasswordEncoder()); DelegatingPasswordEncoder delegatingPasswordEncoder = new DelegatingPasswordEncoder("argon2", encoders); delegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(new Argon2PasswordEncoder()); return delegatingPasswordEncoder; }

Resources

Recipe
id: scw:spring:security:DelegatingPasswordEncoder-bean-other
version: 10
metadata:
  name: Spring Security recommends DelegatingPasswordEncoder for best practices (Bean)
  shortDescription: DelegatingPasswordEncoder allows more flexibility when using several encoders, for code changes, and for migrating
  level: info
  language: java; kotlin
  enabled: true
  descriptionFile: descriptions/SpringSecurityrecommendsDelegatePasswordEncoderforbestpracticesBean.html
  tags: Spring;security;framework specific;Spring Security
search:
  method:
    annotation:
      type: Bean
    returnType:
      reference:
        caseSensitive: false
        matches: SCryptPasswordEncoder|Pbkdf2PasswordEncoder|Argon2PasswordEncoder
      checkInheritance: true
availableFixes:
- name: Create a custom instance of DelegatingPasswordEncoder
  actions:
  - rewrite:
      to: |-
        {{{ modifierList }}} PasswordEncoder delegatingPasswordEncoder() {
        java.util.Map<String, org.springframework.security.crypto.password.PasswordEncoder> encoders = new java.util.HashMap<>();
        encoders.put("{{#sed}}s/passwordencoder//g,{{#lowerCase}}{{{ returnTypeElement }}}{{/lowerCase}}{{/sed}}", new {{{ returnType }}}());

        DelegatingPasswordEncoder delegatingPasswordEncoder = new org.springframework.security.crypto.password.DelegatingPasswordEncoder("{{#sed}}s/passwordencoder//g,{{#lowerCase}}{{{ returnTypeElement }}}{{/lowerCase}}{{/sed}}", encoders);
        delegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(new {{{ returnTypeElement }}}());

        return delegatingPasswordEncoder;
        }