我正在尝试创建一个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");
        }
    }
}


和我的UserDetailsS​​ervice:

@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”吗?

- - 编辑 - - -

我终于找到了解决方案,我不得不将类MyUserDetailsS​​ervice的以下行更改为:

    @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/

10-17 02:43