Recipe Name:
Spring Security recommends DelegatingPasswordEncoder for best practices (Bean - BCrypt)
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. PasswordEncoderFactories.createDelegatingPasswordEncoder() will create an instance of DelegatingPasswordEncoder that will default to the use of BCrypt.
Before:@Bean public BCryptPasswordEncoder bCryptPasswordEncoder() { return new BCryptPasswordEncoder(); }
After:@Bean public PasswordEncoder delegatingPasswordEncoder() { return PasswordEncoderFactories.createDelegatingPasswordEncoder(); }

Resources

Recipe
id: scw:spring:security:DelegatingPasswordEncoder-bean-return
version: 10
metadata:
  name: Spring Security recommends DelegatingPasswordEncoder for best practices (Bean - BCrypt)
  shortDescription: DelegatingPasswordEncoder allows more flexibility when using several encoders, for code changes, and for migrating
  level: info
  language: java; kotlin
  enabled: true
  descriptionFile: descriptions/SpringSecurityrecommendsDelegatePasswordEncoderforbestpracticesBeanBCrypt.html
  tags: Spring;security;framework specific;Spring Security
search:
  method:
    annotation:
      type: Bean
    returnType:
      reference:
        caseSensitive: false
        is: org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
      checkInheritance: true
availableFixes:
- name: Create a customizable 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;
        }
- name: 'Create a DelegatingPasswordEncoder instance using PasswordEncoderFactories (default: bcrypt)'
  actions:
  - rewrite:
      to: |-
        {{{ modifierList }}} org.springframework.security.crypto.password.PasswordEncoder delegatingPasswordEncoder() {
        return org.springframework.security.crypto.factory.PasswordEncoderFactories.createDelegatingPasswordEncoder();
        }