Spring MVC — Getting a user to login

0 投票
最新提问 用户: (120 分)

I can't get login to work using the User I've pre-loaded into the db. Below, I've included my DatabaseLoader, WebSecurityConfig, and User classes. I suspect that the issue has to do with password encryption (I've left out LoginController and login.html since I think the problem is else where).

I'm a mobile developer and web security is new and overwhelming. Aside from my, "why is this not working" question, what are some effective approaches to debugging issues like this?

I'm loading a user into the db at application launch using this DatabaseLoader:

@Component
public class DatabaseLoader implements ApplicationRunner {

    private final UserRepository userRepository;

    @Autowired
    public DatabaseLoader(SubmissionRepository submissionRepository, UserRepository userRepository, RoleRepository roleRepository) {
        this.submissionRepository = submissionRepository;
        this.userRepository = userRepository;
        this.roleRepository = roleRepository;
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {

        User user = new User("user1234", "user@gmail.com","password", new Role(Role.USER));
        userRepository.save(user);
    }
}

I've configured WebSecruityConfig this way. If I use the credentials defined above, the loginFailureHandler() is hit, and I'm not sure why.

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private static final int BC_ENCODER_STRENGTH = 10;

    @Autowired
    private UserServiceDetails userServiceDetails;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userServiceDetails).passwordEncoder(passwordEncoder());
    }

    @Bean
    public static PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(BC_ENCODER_STRENGTH); }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                    .anyRequest().hasRole("COORDINATOR")
                    .and()
                .formLogin()
                    .loginPage("/login")
                    .successHandler(loginSuccessHandler())
                    .failureHandler(loginFailureHandler())
                    .permitAll()
                    .and()
                .logout()
                    .permitAll()
                    .logoutSuccessUrl("/login")
                    .and()
                .csrf();
    }

    public AuthenticationSuccessHandler loginSuccessHandler() {
        return (request, response, authentication) -> response.sendRedirect("/home");
    }

    public AuthenticationFailureHandler loginFailureHandler() {
        return (request, response, exception) -> {
            request.getSession().setAttribute("flash",
                            new FlashMessage("Incorrect username and/or password. Please try again.",
                            FlashMessage.Status.FAILURE));
            response.sendRedirect("/login");
        };
    }

}

Here is my User class:

@Entity
public class User extends BaseEntity implements UserDetails {

    @Column(unique = true)
    @Size(min = 8, max = 20)
    private String username;

    @Column(unique = true)
    @Email
    private String email;

    @Column(length = 100)
    private String password;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "role_id")
    private Role role;

    public User() {
        super();
    }

    public User(String username, String email, String password, Role role) {
        super();

        this.username = username;
        this.email = email;
        setPassword(password);
        this.role = role;
    }

    private void setPassword(String password) {
        this.password = WebSecurityConfig.passwordEncoder().encode(password);
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority(role.getName()));
        return authorities;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public String getUsername() {
        return username;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}

登录 或者 注册 后回答这个问题。

欢迎来到 Security Q&A ,有什么不懂的可以尽管在这里提问,你将会收到社区其他成员的回答。
...