如何在Spring Security中创建自定义UserDetail对象

时间:2014-10-19 05:45:23

标签: java spring spring-mvc spring-security

我为Spring Security构建了自定义的Authenticaton Manager,就像这样

   public class AccountAuthenticationProvider implements  AuthenticationProvider{

    @Autowired
    private AuthenticationService authService;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

        String userName = authentication.getName();
        String password = (String)authentication.getCredentials();

        if(authService.isValid(userName,password)){
            List<GrantedAuthority> grantedAuthorityList = new ArrayList<GrantedAuthority>();
            grantedAuthorityList.add(new SimpleGrantedAuthority("ROLE_USER"));
            SecurityContext securityContext = new SecurityContextImpl();
            return  new UsernamePasswordAuthenticationToken(userName,password);
        }

        return null;
    }


    public void setAuthService(AuthenticationService authService) {
        this.authService = authService;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return true;
    }

}

但是如何创建自己的自定义UserDetail对象?我将使用它来存储与帐户相关的值

3 个答案:

答案 0 :(得分:5)

您需要实现UserDetailsS​​ervice并覆盖loadUserByUsername方法以返回自定义的UserDetails类。

检查以下链接:

http://www.javaroots.com/2013/03/how-to-use-custom-dao-classe-in-spring.html http://www.javacodegeeks.com/2012/08/spring-security-implementing-custom.html

答案 1 :(得分:4)

您需要实现UserDetailsS​​ervice并覆盖loadUserByUsername方法以返回自定义的UserDetails类。像这样 -

public class UserServiceImpl implements UserDetailsService {`

@Autowired
UserDaoImpl userDao;

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    System.out.println(username);
    Users user = (Users) userDao.findByUserName(username);
    List<GrantedAuthority> authorities = buildUserAuthority(user.getUserRoles());
    System.out.println("after....");
    return buildUserForAuthentication(user, authorities);
}

private List<GrantedAuthority> buildUserAuthority(Set<UserRole> userRoles) {
    Set<GrantedAuthority> setAuths = new HashSet<GrantedAuthority>(); 
    for(UserRole userRole  : userRoles){
        System.out.println("called buildUserAuthority(Set<UserRole> userRoles) method.....");
        setAuths.add(new SimpleGrantedAuthority(userRole.getRole()));
    }

    List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>(setAuths);
    return grantedAuthorities;
}

private User buildUserForAuthentication(Users user, List<GrantedAuthority> authorities) {
    //accountNonExpired, credentialsNonExpired, accountNonLocked, authorities properties
    System.out.println("called buildUserForAuthentication(Users user, List<GrantedAuthority> authorities) method....");
    return new User(user.getUsername(), user.getPassword(), user.getEnabled(), true, true, true, authorities);
}}

答案 2 :(得分:3)

你几乎拥有它!

if(authService.isValid(userName,password)) {
    List<GrantedAuthority> grantedAuthorityList = new ArrayList<GrantedAuthority>();
    grantedAuthorityList.add(new SimpleGrantedAuthority("ROLE_USER"));
    MyObject myObj = new MyObject(userName, password, otherInfo);
    return  new UsernamePasswordAuthenticationToken(mjObj,"", grantedAuthorityList);
}

UsernamePasswordAuthenticationToken的第一个参数是原则。原则是系统中表示刚刚登录的人(或事物)的对象。

在认证之前,原则只是(字符串)用户名,因为那是您在那时获得的所有信息。登录后,您可以收集与用户一起使用的其他信息。

Spring提供界面:UserUserDetailsUserDetailsService来帮助管理用户并为用户执行Springy内容,因此如果您MyObject实施UserDetails那么你可以从Spring环境中获得一些额外的好处,但是没有必要只使用你的MyObject

在你的控制器中(在Spring 4中)你可以使用@AuthenticationPrincipal将用户对象注入到调用中,例如:

@RequestMapping(method = RequestMethod.GET, value = "/foo/{bar}")
public SomeObject myCommand(@AuthenticationPrincipal MyObject user, @PathVariable String bar);