我正在使用Spring Boot,Spring Security,OAuth2和JWT对我的应用程序进行身份验证,但是我一直收到这个讨厌的错误,我不知道出什么问题了。我的CustomDetailsService课:
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:
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:
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] 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
我的实体模型类是:
@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 }
Role 实体:
Role
@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 }
UserRole 实体:
UserRole
@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 security BCrypt,其数据类型是varchar(255),大于60。
如果BCryptPasswordEncoder无法将原始密码与编码密码匹配,则会显示此警告。
哈希密码现在可能是“ $ 2b”或“ $ 2y”。
而且,Spring Security中有一个错误,它的正则表达式总是在寻找“ $ 2a”。在中的matches()函数上放置一个调试点BCryptPasswordEncoder.class。
matches()
BCryptPasswordEncoder.class