我正在尝试创建一个 java spring 安全网站,但登录时遇到问题。第一次登录尝试时一切正常,我被重定向到正确的页面。但是,当我关闭浏览器窗口,转到登录页面并尝试再次使用同一用户登录时,我被重定向到登录页面。我无法再次使用同一用户登录,但可以使用不同的用户登录。所以我总是可以使用特定用户登录一次,但不能登录两次。
第二次登录尝试时显示以下错误:
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
这是我的安全配置:
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();
}
}
我的成功处理程序:
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
PasswordEncodermapped for the id "null"
)并没有多大帮助,但这意味着您忘记了指定密码编码器。
例如,如果您使用 BCrypt,则需要在 SecurityConfiguration
中定义以下 bean。
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
您可以在我写的博客文章中找到更详细的解释:https://www.marcobehler.com/guides/spring-security#_authentication_with_spring_security
关于Java Spring Security 第一次登录成功,第二次尝试失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61799065/