我正在尝试创建一个Java Spring Security网站,但登录时遇到麻烦。第一次登录尝试一切正常,我被重定向到正确的页面。但是,当我关闭浏览器窗口时,转到登录页面并尝试再次使用同一用户登录,我将被重定向到登录页面。我无法再次使用同一用户登录,但能够使用其他用户登录。因此,我始终可以使用特定用户登录一次,但不能两次。
在第二次登录尝试时,显示以下错误:
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
这是我的SecurityConfiguration:
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
MySimpleUrlAuthenticationSuccessHandler successHandler;
@Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.permitAll()
.successHandler(successHandler)
.and()
.logout();
}
}
我的SuccessHandler:
public class MySimpleUrlAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
Set<String> roles = AuthorityUtils.authorityListToSet(authentication.getAuthorities());
if (roles.contains("ROLE_ADMIN")) {
response.sendRedirect("consultantIndex.html");
}
if (roles.contains("ROLE_USER")) {
response.sendRedirect("index.html");
}
}
}
和我的UserDetailsService:
@Service
public class MyUserDetailsService implements UserDetailsService {
private Map<String, User> roles = new HashMap<>();
@PostConstruct
public void init() {
roles.put("admin", new User("admin", "{noop}pass", getAuthority("ROLE_ADMIN")));
roles.put("user", new User("user", "{noop}pass", getAuthority("ROLE_USER")));
}
@Override
public UserDetails loadUserByUsername(String username) {
return roles.get(username);
}
private List<GrantedAuthority> getAuthority(String role) {
return Collections.singletonList(new SimpleGrantedAuthority(role));
}
}
有人可以启发我为什么在与特定用户的第二次登录尝试中id为“ null”吗?
- - 编辑 - - -
我终于找到了解决方案,我不得不将类MyUserDetailsService的以下行更改为:
@Override
public UserDetails loadUserByUsername(String username) {
User user = roles.get(username);
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), user.getAuthorities());
}
最佳答案
我不知道为什么只在第二次发生这种情况,但是在任何情况下,您都需要定义一个PasswordEncoder
来让Spring Security知道它需要哪种哈希函数来比较密码。
错误消息(java.lang.IllegalArgumentException: There is no
PasswordEncoder mapped for the id "null"
)并没有真正的帮助,但是这意味着您忘记了指定PasswordEncoder。
例如,如果使用的是BCrypt,则需要在SecurityConfiguration
中定义以下bean。
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
您可以在我写的博客文章中找到更详细的解释:https://www.marcobehler.com/guides/spring-security#_authentication_with_spring_security
关于java - Java Spring Security登录第一次成功,第二次尝试失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61799065/