编码密码看起来不像BCrypt

我正在使用Spring启动,Spring安全性,oauth2和jwt来validation我的应用程序,但我不断得到这个令人讨厌的错误,我没有想到有什么问题。 希望有人可以帮助我。

我的CustomDetailsS​​ervice类:

@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 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 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(); } } 

没有错误消息,除了:

 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] oaccC[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet' 2018-03-31 01:42:03.255 INFO 4088 --- [nio-8072-exec-2] osweb.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started 2018-03-31 01:42:03.281 INFO 4088 --- [nio-8072-exec-2] osweb.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 26 ms 2018-03-31 01:42:03.489 WARN 4088 --- [nio-8072-exec-2] osscbcrypt.BCryptPasswordEncoder : Encoded password does not look like BCrypt 

我的模型是:

 @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 userRoles; '''''' setters and getters } 

角色实体:

 @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 userRoles; //getters and setters } 

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 } 

我在数据库中的密码是正确加密的Spring安全BCrypt和它的数据类型是varchar(255),大于60.提前感谢

你能仔细检查你的客户端密码是否已经编码?

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

PasswordEncoder应该像这样设置:

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

当oauth2 dependecncies迁移到云时,我开始面对这个问题。 之前它是安全框架的一部分:

  org.springframework.security.oauth spring-security-oauth2 

现在它是云框架的一部分:

  org.springframework.cloud spring-cloud-starter-oauth2  

因此,如果您正在使用云依赖(Finchley.RELEASE),那么您可能需要对秘密进行编码,如下所示:

 @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")); } 

BCryptPasswordEncoder在无法将原始密码与编码密码匹配时显示此警告。

哈希密码现在可能是“$ 2b”或“$ 2y”。

并且Spring Security中有一个错误,它有一个正则表达式总是在寻找“$ 2a”。在BCryptPasswordEncoder.class中的matches()函数中设置一个调试点。

您可能在安全配置SecurityConfig缺少此bean

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

我有同样的错误,因为密码列的数据类型,此列的长度为空白固定(CHARACTER),因此请确保您使用的是VARCHAR数据类型,或者将密码列的长度更改为60。

请检查您的方法UserDetails loadUserByUsername(String username)返回有效的UserDetail对象。 如果返回的对象为null /具有无效值的对象,那么您也将看到此错误。