[英]There is no PasswordEncoder mapped for the id “null” with database authentication
I successfully build in-memory authentication. 我成功地建立了内存中身份验证。 But when I going to build it with database comes this error.
但是,当我要用数据库构建它时,会出现此错误。
There is no PasswordEncoder mapped for the id "null"
没有为id“ null”映射的PasswordEncoder
This is followed tutorial - Spring Boot Tutorial for Beginners, 10 - Advanced Authentication using Spring Security | 接下来是教程- 初学者Spring Boot教程,10-使用Spring Security的高级身份验证| Mighty Java
强大的Java
There are classes 有班
@Configuration
@EnableWebSecurity
public class SpringSecurityConfiguration extends
WebSecurityConfigurerAdapter{
@Autowired
private AuthenticationEntryPoint entryPoint;
@Autowired
private MyUserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated().and().httpBasic()
.authenticationEntryPoint(entryPoint);
}
}
@Configuration
public class AuthenticationEntryPoint extends BasicAuthenticationEntryPoint{
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
response.addHeader("WWW-Authenticate", "Basic realm -" +getRealmName());
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
PrintWriter writer = response.getWriter();
writer.println("Http Status 401 "+authException.getMessage());
}
@Override
public void afterPropertiesSet() throws Exception {
setRealmName("MightyJava");
super.afterPropertiesSet();
}
} }
@Service
public class MyUserDetailsService implements UserDetailsService{
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if(user == null){
throw new UsernameNotFoundException("User Name "+username +"Not Found");
}
return new org.springframework.security.core.userdetails.User(user.getUserName(),user.getPassword(),getGrantedAuthorities(user));
}
private Collection<GrantedAuthority> getGrantedAuthorities(User user){
Collection<GrantedAuthority> grantedAuthority = new ArrayList<>();
if(user.getRole().getName().equals("admin")){
grantedAuthority.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
}
grantedAuthority.add(new SimpleGrantedAuthority("ROLE_USER"));
return grantedAuthority;
}
}
public interface UserRepository extends JpaRepository<User, Long>{
@Query("FROM User WHERE userName =:username")
User findByUsername(@Param("username") String username);
}
@Entity
public class Role extends AbstractPersistable<Long>{
private String name;
@OneToMany(targetEntity = User.class , mappedBy = "role" , fetch = FetchType.LAZY ,cascade = CascadeType.ALL)
private Set<User> users;
//getter and setter
}
@Entity
public class User extends AbstractPersistable<Long>{
//AbstractPersistable class ignore primary key and column annotation(@Column)
private String userId;
private String userName;
private String password;
@ManyToOne
@JoinColumn(name = "role_id")
private Role role;
@OneToMany(targetEntity = Address.class, mappedBy = "user",fetch= FetchType.LAZY ,cascade =CascadeType.ALL)
private Set<Address> address; //Instead of Set(Unordered collection and not allow duplicates) we can use list(ordered and allow duplicate values) as well
//getter and setter}
If you have any idea plese inform. 如果您有任何想法请告知。 Thank you.
谢谢。
I changed MyUserDetailsService class adding passwordEncoder
method. 我更改了MyUserDetailsService类,添加了
passwordEncoder
方法。
Added lines 增加线
BCryptPasswordEncoder encoder = passwordEncoder();
Changed Line 换线
//changed, user.getPassword() as encoder.encode(user.getPassword())
return new org.springframework.security.core.userdetails.User(--)
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
BCryptPasswordEncoder encoder = passwordEncoder();
User user = userRepository.findByUsername(username);
if(user == null){
throw new UsernameNotFoundException("User Name "+username +"Not Found");
}
return new org.springframework.security.core.userdetails.User(user.getUserName(),encoder.encode(user.getPassword()),getGrantedAuthorities(user));
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
As from Spring Security 5.x, Spring Security enforces you to use a password encoder if you're working with other than in-memory (production) databases. 从Spring Security 5.x开始,如果您使用的不是内存(生产)数据库,Spring Security会强制您使用密码编码器。
Spring Security enforces this by activating the default DelegatingPasswordEncoder
, which looks for PasswordEncoder
beans. Spring Security通过激活默认的
DelegatingPasswordEncoder
执行此操作,默认的DelegatingPasswordEncoder
查找PasswordEncoder
bean。 By adding a BCryptPasswordEncoder
, the DelegatingPasswordEncoder
will return that instance to encrypt passwords. 通过添加
BCryptPasswordEncoder
, DelegatingPasswordEncoder
将返回该实例以加密密码。
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
I don't recommend you to do this, but if you really want to, you can override password encoding by adding
{noop}
to the password value.我不建议您这样做,但是如果您确实愿意,可以通过在密码值上添加
{noop}
来覆盖密码编码。 This will treat the password by activating theNoOpPasswordEncoder
instead of the defaultDelegatingPasswordEncoder
and will treat your password as plain text.这将通过激活
NoOpPasswordEncoder
而不是默认的DelegatingPasswordEncoder
来处理密码,并将您的密码视为纯文本。
Please note that this is not recommended if you deploy your app to a production environment!请注意,如果您将应用程序部署到生产环境,则不建议这样做!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.