Spring Security中的AuthenticationManagerBuilder无法正常工作,为什么?

时间:2017-01-07 11:56:33

标签: java spring security spring-mvc spring-security

我将在春季启动应用程序上实现spring security。为此,我通常会关注Spring boot and Spring Security integration for Rest API's并在SpringSecurity : Authenticate User with Custom UserDetailsService处获得详细信息。

  

实体: UserRole在数据库中创建3个表(userrole& user_roles

User

package com.maxpro.entity;

import javax.persistence.*;
import java.util.Set;


@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    private String username;
    private String password;
    private boolean enabled;

    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinTable(joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
    private Set<Role> roles;

    // getters, setters & toString
}

Role

package com.maxpro.entity;

import javax.persistence.*;
import java.util.Set;


@Entity
public class Role {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    private String role;

    @ManyToMany(mappedBy = "roles", fetch = FetchType.LAZY)
    private Set<User> users;

    // getters, setters & toString
}
  

存储库: UserRepository

package com.maxpro.repository;

import com.maxpro.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;


@Repository("userRepository")
public interface UserRepository extends JpaRepository<User, Long> {

    User findByUsername(String username);

}
  

配置: WebSecurityConfigurer使用WebUserDetailsService自定义身份验证构建器

WebSecurityConfigurer

package com.maxpro.security;

import com.maxpro.repository.UserRepository;
import com.maxpro.security.service.WebUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;


@Configuration
@EnableWebSecurity
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserRepository userRepository;

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

    @Override
    public UserDetailsService userDetailsServiceBean() throws Exception {
        return new WebUserDetailsService(userRepository);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                    .antMatchers("/css/**", "/img/**", "/js/**").permitAll()
                    .antMatchers("/", "/home").permitAll()
                    .antMatchers("/admin/**").hasAuthority("ADMIN")
                    .antMatchers("/user/**").hasAuthority("USER")
                    .anyRequest().authenticated()
                .and()
                    .formLogin()
                        .loginPage("/login")
                            .usernameParameter("username").passwordParameter("password").permitAll()
                .and()
                    .logout()
                        .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                        .logoutSuccessUrl("/")
//                .and()
//                    .exceptionHandling().accessDeniedPage("/403")
//                .and()
//                    .csrf();
        ;
    }

}

WebUserDetailsService

package com.maxpro.security.service;

import com.maxpro.entity.Role;
import com.maxpro.entity.User;
import com.maxpro.repository.UserRepository;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import javax.transaction.Transactional;
import java.util.HashSet;
import java.util.Set;


@Transactional
public class WebUserDetailsService implements UserDetailsService {

    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(WebUserDetailsService.class);

    private UserRepository userRepository;

    public WebUserDetailsService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        try {
            User user = userRepository.findByUsername(username);
            if (user == null) {
                LOGGER.debug("user not found with the provided username");
                return null;
            }
            LOGGER.debug(" user from username " + user.toString());
            return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), getAuthorities(user));
        }
        catch (Exception e){
            throw new UsernameNotFoundException("User not found");
        }
    }

    private Set<GrantedAuthority> getAuthorities(User user){
        Set<GrantedAuthority> authorities = new HashSet<>();
        for(Role role : user.getRoles()) {
            GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(role.getRole());
            authorities.add(grantedAuthority);
        }
        LOGGER.debug("user authorities are " + authorities.toString());
        return authorities;
    }

}

问题:有时可以进行身份​​验证,有时则无法进行身份验证。为什么呢?

问题: loadUserByUsername()自定义身份验证构建器中的WebUserDetailsService是否有任何问题?

注意:我发现username已传递到loadUserByUsername()课程中的WebUserDetailsService。我认为即使我将正确的用户名传递给存储库,UserRepository也会返回null User

资源:这是Github上的代码。

0 个答案:

没有答案