title: Migration to Spring Boot 2 - Security Encoded password does not look like BCrypt
body: <p>I had a Spring Boot 1.5.9 authorization server that uses BCrypt for password storage. I am attempting to migrate to 2.0 However, I am not no longer able to retrieve a token for authorization.</p>
  
  <p>The response from the server is:</p>
  
  <pre><code>    "timestamp": "2018-03-09T15:22:06.576+0000",
      "status": 401,
      "error": "Unauthorized",
      "message": "Unauthorized",
      "path": "/oauth/token"
  }
  </code></pre>
  
  <p>with the console outputting the following: <code>2018-03-09 09:22:06.553  WARN 20976 --- [nio-8090-exec-1] o.s.s.c.bcrypt.BCryptPasswordEncoder     : Encoded password does not look like BCrypt</code>.</p>
  
  <p>This piece of the application worked fine before. The only changes I made were to the build.gradle file (changing <code>springBootVersion</code>, adding the <code>io.spring.dependency-management</code> plugin and adding <code>runtime('org.springframework.boot:spring-boot-devtools')</code>.</p>
  
  <pre><code>buildscript {
      ext {
          springBootVersion = '2.0.0.RELEASE'
      }
      repositories {
          mavenCentral()
      }
      dependencies {
          classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
      }
  }
  
  apply plugin: 'java'
  apply plugin: 'eclipse'
  apply plugin: 'org.springframework.boot'
  apply plugin: 'io.spring.dependency-management'
  
  group = 'com.midamcorp'
  version = '0.0.1-SNAPSHOT'
  sourceCompatibility = 1.8
  
  repositories {
      mavenCentral()
  }
  
  
  
  dependencies {
      compile('org.springframework.boot:spring-boot-starter-data-rest')
      compile('org.springframework.boot:spring-boot-starter-jdbc')
          compile('org.springframework.boot:spring-boot-starter-data-jpa')
      compile('org.springframework.boot:spring-boot-starter-security')
      compile('commons-io:commons-io:2.5')    
      compile('org.springframework.security:spring-security-jwt:1.0.7.RELEASE')
      compile('org.springframework.security.oauth:spring-security-oauth2:2.2.1.RELEASE')
      compile 'com.microsoft.sqlserver:mssql-jdbc:6.2.2.jre8'   
      runtime('org.springframework.boot:spring-boot-devtools')
  
      testCompile('org.springframework.boot:spring-boot-starter-test')
      testCompile('org.springframework.security:spring-security-test')
  testCompile('com.h2database:h2:1.4.196')
  
  }
  </code></pre>
  
  <p>The logic to hash the passwords in found in two separate configuration files:</p>
  
  <pre><code>package com.midamcorp.auth_server.config;
  
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.security.authentication.AuthenticationManager;
  import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
  import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
  import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  import org.springframework.security.config.http.SessionCreationPolicy;
  import org.springframework.security.crypto.password.PasswordEncoder;
  
  import com.midamcorp.auth_server.service.OAuthUserDetailsService;
  
  @Configuration
  @EnableGlobalMethodSecurity(prePostEnabled = true)
  @EnableWebSecurity
  public class SecurityConfig extends WebSecurityConfigurerAdapter {
  
      @Autowired
      private OAuthUserDetailsService userService;
  
      @Autowired
      private PasswordEncoder passwordEncoder;
  
      @Bean
      @Override
      protected AuthenticationManager authenticationManager() throws Exception {
          return super.authenticationManager();
  }
  
      // Hash password
      @Override
      protected void configure(AuthenticationManagerBuilder auth) throws Exception {
          auth.userDetailsService(userService)
          .passwordEncoder(passwordEncoder);
      }
  
      @Override
      protected void configure(HttpSecurity http) throws Exception {
         http
                 .sessionManagement()
                 .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                 .and()
                 .httpBasic()
                 .realmName("test")
                 .and()
                 .csrf()
                 .disable();
  
      }
  }
  </code></pre>
  
  <p>and </p>
  
  <pre><code>package com.midamcorp.auth_server.config;
  
  import javax.sql.DataSource;
  
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.beans.factory.annotation.Value;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.core.io.ClassPathResource;
  import org.springframework.jdbc.datasource.DriverManagerDataSource;
  import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
  import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  import org.springframework.security.crypto.password.PasswordEncoder;
  import org.springframework.security.oauth2.provider.token.TokenStore;
  import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
  import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
  import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
  import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory;
  
  
  // Contains properties common to both authorization and resource servers
  @Configuration
  public class AppConfig {
  
  
          @Value("${spring.datasource.url}")
          private String datasourceUrl;
  
          @Value("${spring.datasource.driverClassName}")
          private String dbDriverClassName;
  
          @Value("${spring.datasource.username}")
          private String dbUsername;
  
          @Value("${spring.datasource.password}")
          private String dbPassword;
  
          @Bean
          public PasswordEncoder passwordEncoder() {
              return new BCryptPasswordEncoder();
          }
  
          @Bean
          public DataSource dataSource() {
              final DriverManagerDataSource dataSource = new DriverManagerDataSource();
  
              dataSource.setDriverClassName(dbDriverClassName);
              dataSource.setUrl(datasourceUrl);
              dataSource.setUsername(dbUsername);
              dataSource.setPassword(dbPassword);
  
              return dataSource;
          }    
  
          // Refrence: http://www.baeldung.com/spring-security-oauth-jwt
  
          /* !!!!!!!!!!!!!!!!!!!!!!!!!! 
          ** TODO 
          * Secure key file for deployment.
          !!!!!!!!!!!!!!!!!!!! */
             @Bean
             public JwtAccessTokenConverter accessTokenConverter() {
                JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
                KeyStoreKeyFactory keyStoreKeyFactory = 
                        new KeyStoreKeyFactory(new ClassPathResource("mytest.jks"), "mypass".toCharArray());
                      converter.setKeyPair(keyStoreKeyFactory.getKeyPair("mytest"));
                return converter;
             }
  
  
             @Bean
             public TokenStore tokenStore() {
                return new JwtTokenStore(accessTokenConverter());
             }
  
  
  }
  </code></pre>
  
  <p>OAuthUser class:</p>
  
  <pre><code>    package com.midamcorp.auth_server.model;
  
  
  import java.util.List;
  
  import javax.persistence.*;
  
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.security.crypto.password.PasswordEncoder;
  
  import com.fasterxml.jackson.annotation.JsonIgnore;
  
  
  @Entity
  @Table(name="auth_user")
  public class OAuthUser {
  
  //    @Autowired 
  //    @Transient
  //    private PasswordEncoder passwordEncoder;
  //    
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      private Long id;
  
      @Column(name= "username")
      private String userName;
  
      @Column(name="password")
      @JsonIgnore
      private String password;
  
      @Column(name="first_name")
      private String firstName;
  
      @Column(name="last_name")
      private String lastName;
  
      @Column(name="email")
      private String email;
  
      @Column(name="is_enabled")
      private boolean isEnabled;
  
       /**
        * Reference: https://github.com/nydiarra/springboot-jwt/blob/master/src/main/java/com/nouhoun/springboot/jwt/integration/domain/User.java
       * Roles are being eagerly loaded here because
       * they are a fairly small collection of items for this example.
       */
      @ManyToMany(fetch = FetchType.EAGER)
      @JoinTable(name = "user_role", joinColumns
              = @JoinColumn(name = "user_id",
              referencedColumnName = "id"),
              inverseJoinColumns = @JoinColumn(name = "role_id",
                      referencedColumnName = "id"))
  private List&lt;Role&gt; roles;
  
  
      public OAuthUser() {};
      public OAuthUser(String firstName, String lastName, String user, String pass) {
          this.firstName = firstName;
          this.lastName = lastName;
          this.userName = user;
          this.password = pass;
      }
      public Long getId() {
          return id;
      }
  
      public void setId(Long id) {
          this.id = id;
      }
  
      public String getUserName() {
          return userName;
      }
  
      public void setUserName(String userName) {
          this.userName = userName;
      }
  
      public String getPassword() {
          return password;
      }
  
      public void setPassword(String password) {
          this.password = password;
      }
  
      public String getFirstName() {
          return firstName;
      }
  
      public void setFirstName(String firstName) {
          this.firstName = firstName;
      }
  
      public String getLastName() {
          return lastName;
      }
  
      public void setLastName(String lastName) {
          this.lastName = lastName;
      }
  
      public String getEmail() {
          return email;
      }
  
      public void setEmail(String email) {
          this.email = email;
      }
  
      public List&lt;Role&gt; getRoles() {
          return roles;
      }
  
      public void setRoles(List&lt;Role&gt; roles) {
          this.roles = roles;
      }
  
      public boolean isEnabled() {
          return isEnabled;
      }
  
      public void setEnabled(boolean isEnabled) {
          this.isEnabled = isEnabled;
      }
  }
  </code></pre>
  
  <p>I understand there were significant changes made to Spring Security, but I am not sure to approach resolving this issue. Any guidance would be appreciated.</p>
  
  <p>Thanks.</p>
  
  <p>EDIT</p>
  
  <p>Just some further details in case they help. Even if I add a new user while running Spring Boot 2.0:</p>
  
  <pre><code>OAuthUser user = new OAuthUser();   
  
              user.setFirstName("K");
              user.setLastName("M");
              user.setPassword(passwordEncoder.encode("L"));
              user.setUserName("KLM");
  
  repository.save(user);
  </code></pre>
  
  <p>it and make a request using the new username and password, I still receive the error.</p>
  
  <p>EDIT TWO:</p>
  
  <p>Request the results in error:</p>
  
  <pre><code>curl --request POST \
    --url http://web:secret@localhost:8090/oauth/token \
    --header 'content-type: multipart/form-data; boundary=---011000010111000001101001' \
    --form grant_type=password \
    --form username=KLM \
    --form password=L
  </code></pre>
  
  <p>Authorization Server config:</p>
  
  <pre><code>    package com.midamcorp.auth_server.config;
  
  import java.util.Arrays;
  
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.context.annotation.Primary;
  import org.springframework.security.authentication.AuthenticationManager;
  import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
  import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
  import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
  import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
  import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
  import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
  import org.springframework.security.oauth2.provider.token.AccessTokenConverter;
  import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
  import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
  import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
  import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
  import org.springframework.security.oauth2.provider.token.TokenStore;
  import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
  import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
  
  // Reference: https://dazito.com/java/spring-boot-and-oauth2-with-jdbc
  
  @EnableAuthorizationServer
  @Configuration
  public class AuthServerConfig extends AuthorizationServerConfigurerAdapter{
      @Autowired
      private TokenStore tokenStore;
  
      @Autowired
      private AccessTokenConverter converter;
  
       private final AppConfig appConfig; 
  
      private AuthenticationManager authenticationManager;
  
      @Autowired
      public AuthServerConfig(AuthenticationManager authenticationManager, AppConfig appConfig) {
          this.authenticationManager = authenticationManager;
          this.appConfig = appConfig;
      }
  
      @Override
      public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
          security.checkTokenAccess("permitAll()");
          security.tokenKeyAccess("permitAll()");
      }
  
      @Override
      public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
  
      JdbcClientDetailsService details = new JdbcClientDetailsService(appConfig.dataSource());
  
          configurer.jdbc(appConfig.dataSource());
      }
  
      @Override
      public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
          TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
          endpoints.tokenStore(tokenStore)
                  .accessTokenConverter(converter)
              .authenticationManager(authenticationManager);
      }
  
  
  
         @Bean
         @Primary //Making this primary to avoid any accidental duplication with another token service instance of the same name
         public DefaultTokenServices tokenServices() {
            DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
            defaultTokenServices.setTokenStore(tokenStore);
            defaultTokenServices.setSupportRefreshToken(true);
            return defaultTokenServices;
         }       
  
  
  
  }
  </code></pre>
  
  <p>I am using the following properties:</p>
  
  <pre><code> spring.datasource.url=jdbc:sqlserver://localhost;databaseName=API
  spring.datasource.username=**
  spring.datasource.password=**
  spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
  server.port=8090
  </code></pre>