Recipe Name:
Spring Security recommends DelegatingPasswordEncoder for best practices
Description:
DelegatingPasswordEncoder allows more flexibility when using several encoders, for code changes, and for migrating
Level:
info
Language:
  • java
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:Argon2PasswordEncoder passwordEncoder = new Argon2PasswordEncoder();
After:Map encoders = new HashMap<>(); encoders.put("argon2", new Argon2PasswordEncoder()); PasswordEncoder argon2PasswordEncoder = new DelegatingPasswordEncoder("argon2", encoders);

Resources

Recipe
id: scw:spring:security:DelegatingPasswordEncoder
version: 10
metadata:
  name: Spring Security recommends DelegatingPasswordEncoder for best practices
  shortDescription: DelegatingPasswordEncoder allows more flexibility when using several encoders, for code changes, and for migrating
  level: info
  language: java
  enabled: true
  descriptionFile: descriptions/SpringSecurityrecommendsDelegatePasswordEncoderforbestpractices.html
  tags: Spring;security;framework specific;Spring Security
search:
  assignment:
    not:
      in:
        method:
          annotation:
            type: Bean
          returnType: '{{{ type }}}'
    anyOf:
    - expressionType: org.springframework.security.crypto.password.Pbkdf2PasswordEncoder
    - expressionType: org.springframework.security.crypto.scrypt.SCryptPasswordEncoder
    - expressionType: org.springframework.security.crypto.argon2.Argon2PasswordEncoder
availableFixes:
- name: Create a custom instance of DelegatingPasswordEncoder
  actions:
  - rewrite:
      to: |-
        java.util.Map<String, org.springframework.security.crypto.password.PasswordEncoder> encoders = new java.util.HashMap<>();
        encoders.put("{{#sed}}s/passwordencoder//g,{{#lowerCase}}{{{ typeElement }}}{{/lowerCase}}{{/sed}}", {{{ assignedExpression }}});

        org.springframework.security.crypto.password.PasswordEncoder {{{ qualifier }}} = new org.springframework.security.crypto.password.DelegatingPasswordEncoder("{{#sed}}s/passwordencoder//g,{{#lowerCase}}{{{ typeElement }}}{{/lowerCase}}{{/sed}}", encoders);
      target: self