web-dev-qa-db-fra.com

Le mot de passe encodé ne ressemble pas à BCrypt

J'utilise Spring Boot, Spring Security, oauth2 et jwt pour authentifier mon application, mais je continue à avoir cette méchante erreur et je n'ai aucune idée de ce qui ne va pas. J'espère que quelqu'un pourra m'aider.

ma classe CustomDetailsService: 

 @Service
    public class CustomDetailsService implements UserDetailsService {

        private static final Logger logger = LoggerFactory.getLogger(CustomDetailsService.class);

        @Autowired
        private UserBO userBo;

        @Autowired
        private RoleBO roleBo;

        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            AppUsers appUsers = null;
            try {
                appUsers = this.userBo.loadUserByUsername(username);
                System.out.println("========|||=========== "+appUsers.getUsername());
            }catch(IndexOutOfBoundsException e){
                throw new UsernameNotFoundException("Wrong username");
            }catch(DataAccessException e){
                e.printStackTrace();
                throw new UsernameNotFoundException("Database Error");
            }catch(Exception e){
                e.printStackTrace();
                throw new UsernameNotFoundException("Unknown Error");
            }

            if(appUsers == null){
                throw new UsernameNotFoundException("Bad credentials");
            }
            logger.info("Username: "+appUsers.getUsername());
            return buildUserFromUserEntity(appUsers);
        }

        private User buildUserFromUserEntity(AppUsers authUsers) {
            Set<UserRole> userRoles = authUsers.getUserRoles();

            boolean enabled = true;
            boolean accountNotExpired = true;
            boolean credentialsNotExpired = true;
            boolean accountNotLocked = true;

            if (authUsers.getAccountIsActive()) {
                try {
                    if(authUsers.getAccountExpired()){
                        accountNotExpired = true;
                    } else if (authUsers.getAccountIsLocked()) {
                        accountNotLocked = true;
                    } else {
                        if (containsRole((userRoles), roleBo.findRoleByName("FLEX_ADMIN"))){
                            accountNotLocked = false;
                        }
                    }
                }catch(Exception e){
                    enabled = false;
                    e.printStackTrace();
                }
            }else {
                accountNotExpired = false;
            }
            // convert model user to spring security user
            String username = authUsers.getUsername();
            String password = authUsers.getPassword();

            List<GrantedAuthority> authorities = buildUserAuthority(userRoles);

            User springUser = new User(username, password,enabled, accountNotExpired, credentialsNotExpired, accountNotLocked, authorities);
            return springUser;
        }

OAuth2Config:

@Configuration
public class OAuth2Config extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Bean
    public JwtAccessTokenConverter tokenConverter() {
        JwtAccessTokenConverter tokenConverter = new JwtAccessTokenConverter();
        tokenConverter.setSigningKey(PRIVATE_KEY);
        tokenConverter.setVerifierKey(PUBLIC_KEY);
        return tokenConverter;
    }

    @Bean
    public JwtTokenStore tokenStore() {
        return new JwtTokenStore(tokenConverter());
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpointsConfigurer) throws Exception {
        endpointsConfigurer.authenticationManager(authenticationManager)
                .tokenStore(tokenStore())
                .accessTokenConverter(tokenConverter());
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer securityConfigurer) throws Exception {
        securityConfigurer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient(CLIENT_ID)
                .secret(CLIENT_SECRET)
                .scopes("read","write")
                .authorizedGrantTypes("password","refresh_token")
                .accessTokenValiditySeconds(20000)
                .refreshTokenValiditySeconds(20000);
    }
}

SecurityConfig: 

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    CustomDetailsService customDetailsService;

    @Bean
    public PasswordEncoder encoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    @Autowired
    protected void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
        authenticationManagerBuilder.userDetailsService(customDetailsService).passwordEncoder(encoder());
        System.out.println("Done...finito");
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.NEVER);
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManagerBean();
    }
}

NO Message d'erreur sauf:

Hibernate: select appusers0_.id as id1_2_, appusers0_.account_expired as account_2_2_, appusers0_.account_is_active as account_3_2_, appusers0_.account_is_locked as account_4_2_, appusers0_.bank_acct as bank_acc5_2_, appusers0_.branch_id as branch_i6_2_, appusers0_.bvn as bvn7_2_, appusers0_.create_date as create_d8_2_, appusers0_.created_by as created_9_2_, appusers0_.email as email10_2_, appusers0_.email_verified_code as email_v11_2_, appusers0_.gender as gender12_2_, appusers0_.gravatar_url as gravata13_2_, appusers0_.is_deleted as is_dele14_2_, appusers0_.lastname as lastnam15_2_, appusers0_.middlename as middlen16_2_, appusers0_.modified_by as modifie17_2_, appusers0_.modified_date as modifie18_2_, appusers0_.orgnization_id as orgniza19_2_, appusers0_.password as passwor20_2_, appusers0_.phone_no as phone_n21_2_, appusers0_.surname as surname22_2_, appusers0_.token_expired as token_e23_2_, appusers0_.username as usernam24_2_ from users appusers0_ where appusers0_.username=?
Tinubu
2018-03-31 01:42:03.255  INFO 4088 --- [nio-8072-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
2018-03-31 01:42:03.255  INFO 4088 --- [nio-8072-exec-2] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2018-03-31 01:42:03.281  INFO 4088 --- [nio-8072-exec-2] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 26 ms
2018-03-31 01:42:03.489  WARN 4088 --- [nio-8072-exec-2] o.s.s.c.bcrypt.BCryptPasswordEncoder     : Encoded password does not look like BCrypt

Mon modèle sont:

@Entity
@Table(name="USERS")
@DynamicUpdate
public class AppUsers {

    @Id
    @Column(name="ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @ApiModelProperty(notes = "The user auto generated identity", required = true)
    private Long id;

    @Column(name="username")
    @ApiModelProperty(notes = "The username parameter", required = true)
    private String username;

    @Column(name="password")
    @ApiModelProperty(notes = "The password parameter", required = true)
    private String password;

    @JsonManagedReference
    @OneToMany(mappedBy="appUsers")
    private Set<UserRole> userRoles;

'''''' setters and getters
}

Entité de rôle:

@Entity
@Table(name="ROLE")
public class Role {

    @javax.persistence.Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "role_id", unique = true, nullable = false)
    private Long Id;

    @Column(name = "name")
    private String roleName;

   @JsonManagedReference
    @OneToMany(mappedBy="role")
    private Set<UserRole> userRoles;

   //getters and setters

}

Entité User_Rple:

@Entity
@Table(name="USER_ROLE")
@DynamicUpdate
public class UserRole   implements Serializable {

    private static final long serialVersionUID = 6128016096756071383L;

    @Id
    @Column(name="ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @ApiModelProperty(notes = "The userrole auto generated identity", required = true)
    private long id;

    @JsonBackReference
    @ManyToOne//(fetch=FetchType.LAZY)
    private AppUsers appUsers;

    @JsonBackReference
    @ManyToOne//(fetch=FetchType.LAZY)
    private Role role;

   // getters and setters
}

Mon mot de passe dans la base de données est correctement crypté avec le code de sécurité BCrypt et son type de données est varchar (255), dont la taille est supérieure à 60 . Merci d'avance.

11
Kunle Ajiboye

BCryptPasswordEncoder affiche cet avertissement lorsqu'il ne correspond pas à un mot de passe brut avec un mot de passe codé. 

Le mot de passe haché pourrait être «$ 2b» ou «$ 2y» maintenant. 

Et il y a un bogue dans Spring Security qui a une expression régulière qui recherche toujours «2 $». Placez un point de débogage à la fonction matches() dans le BCryptPasswordEncoder.class.

7
Nikhil

Pouvez-vous vérifier que le secret de votre client est codé?

@Override
public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
    configurer
            .inMemory()
            .withClient(clientId)
            .secret(passwordEncoder.encode(clientSecret))
            .authorizedGrantTypes(grantType)
            .scopes(scopeRead, scopeWrite)
            .resourceIds(resourceIds);
}
14

Lorsque oauth2 dependecncies a migré vers le cloud, j'ai commencé à faire face à ce problème. Auparavant, cela faisait partie du cadre de sécurité:

<dependency>
        <groupId>org.springframework.security.oauth</groupId>
        <artifactId>spring-security-oauth2</artifactId></dependency>

Maintenant, cela fait partie du framework cloud:

<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-oauth2</artifactId>
    </dependency>

Donc, si vous utilisez la dépendance au cloud (Finchley.RELEASE), vous devrez peut-être encoder le secret comme ci-dessous:

@Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
         clients
                .inMemory()
                .withClient("clientapp")
                .authorizedGrantTypes("password","refresh_token")
                .authorities("USER")
                .scopes("read", "write")
                .resourceIds(RESOURCE_ID)
                .secret(passwordEncoder.encode("SECRET"));
    }
8
PKumar

Le PasswordEncoder devrait être défini comme ceci:

@Bean
    public PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }
5
Pascal Joret

Veuillez vérifier si votre méthode UserDetails loadUserByUsername(String username) renvoie un objet UserDetail valide. Si l'objet renvoyé est null/objet avec des valeurs non valides, vous verrez également cette erreur.

1
sandeep pandey

Ce bean est probablement absent de votre configuration de sécurité SecurityConfig

@Bean
public DaoAuthenticationProvider getAuthenticationProvider() {
    DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
    authenticationProvider.setUserDetailsService(customDetailsService);
    authenticationProvider.setPasswordEncoder(encoder());
    return authenticationProvider;
}
0
bitscanbyte

BCryptPasswordEncoder ne supprime pas l'identifiant {bcrypt}, mais DelegatingPasswordEncoder le fait. Lorsque je définis explicitement BCryptPasswordEncoder en tant qu'encodeur pour DaoAuthenticationProvider, il appelle la méthode de correspondance sur BCryptPasswordEncoder (sans bande d'identification), mais pas sur DelegatingPasswordEncoder (avec bande d'identification).

0
Zagrebin Victor

J'ai eu la même erreur et c'était à cause du type de données de la colonne password, Cette colonne était de longueur fixe (CHARACTER), alors assurez-vous que vous utilisez un type de données VARCHAR ou changez la longueur à 60 pour votre mot de passe colonne.