java - 实施 Bcrypt PasswordEncoder 后无法使用身份验证
问题描述
实施 Bcrypt 密码编码器后,我无法进行身份验证(凭据无效)。这是我要添加的用户:
userRepository.save(new User("First", "Last", "user", "user" , "email@email.com", "12345", superRoles));
当我查看页面的 JSON 时,我看到密码是散列的。但是,当我尝试输入密码“用户”时,我无法进行身份验证:
..."password": "$2a$10$ZwUxEGVDAgI4qgkas0bEO.BmU1WrMXk1zQA5Jc70m.e6reiL3M7BG"...
谁能发现我做错了什么?代码贴在下面。先感谢您!
用户等级:
@Entity
public class User {
public static final PasswordEncoder PASSWORD_ENCODER = new BCryptPasswordEncoder();
private long userId;
private String userFirstName;
private String userLastName;
private String username;
private String password;
private String userPhone;
private String userEmail;
//others, such as List for roles, etc.
public User() { }
public User(String userFirstName, String userLastName, String username, String password, String userPhone, String userEmail, Map<String, Boolean> userRoles) {
this.userFirstName = userFirstName;
this.userLastName = userLastName;
this.username = username;
setPassword(password);
this.userPhone = userPhone;
this.userEmail = userEmail;
this.userRoles = userRoles;
}
public void setPassword(String password) {
this.password = PASSWORD_ENCODER.encode(password);
}
// other getters and setters
}
网络安全配置:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
DetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(User.PASSWORD_ENCODER);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers(
"/login"
).permitAll()
...
// taken out for brevity
}
}
详情服务:
@Component
public class DetailsService implements UserDetailsService {
@Autowired
UserRepository users;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = users.findByUsername(username);
// Roles are implemented in the entity in a Map<String, Boolean>, e.g. "ROLE_ADMIN" : true, to help with easily setting new permissions on the front end
List<String> roles = new ArrayList<>();
for (Map.Entry<String, Boolean> entry : user.getUserRoles().entrySet()) {
if (entry.getValue().equals(true)) {
roles.add(entry.getKey());
}
}
String[] permissions = roles.toArray(new String[roles.size()]);
if (user == null) {
throw new UsernameNotFoundException(username + " was not found");
}
return new org.springframework.security.core.userdetails.User(
user.getUsername(),
user.getPassword(),
AuthorityUtils.createAuthorityList(permissions)
);
}
}
编辑2:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers(
"/login",
"/home",
"/visitor-area",
"/site.css",
"/app.js",
"/create-account",
"/css/*",
"/saveUser",
"/users"
).permitAll()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/user-dashboard")
.and()
.logout()
.permitAll()
.logoutSuccessUrl("/home")
.and()
.csrf().disable();
}
解决方案
解决了:
当我加密User
实体上的密码时,它不会进行身份验证。为了解决这个问题,我在构造函数中恢复了常规String password
的 getter/setter setPassword(password)
。然后,在实现的类中ApplicationRunner
,我在那里对密码进行了编码:
String password = "user";
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String hashedPassword = passwordEncoder.encode(password);
userRepository.save(new User("First", "Last", "user", hashedPassword , "email@email.com", "12345", superRoles));
推荐阅读
- c# - Generate call to generic method in runtime
- c# - Unresolved package name even though everything is fine
- linux - 从 PCAP 中提取信息
- sql - Aggregating over multiple groups in Postgres
- javascript - How to compare values in two array of objects
- linux - Merged code from repo not updating in production server after push
- xml - Follow Up on question that got solvend using Muenchian Grouping
- javascript - V8之后是JS解释还是编译?
- excel - How to chose specific rows in worksheet
- angularjs - AngularJS - 如何将数据从视图(HTML)传递到控制器(JS)