Spring安全性获取User对象

use*_*896 12 spring spring-security

我已经通过Spring Security Framework实现了用户身份验证,一切正常.我可以登录并注销,我可以获取登录的用户名,例如:

String userName = ((UserDetails) auth.getPrincipal()).getUsername();
Run Code Online (Sandbox Code Playgroud)

现在我想让用户像数据库中的对象(我需要用户ID和其他用户属性).

这是我迄今为止的尝试:

User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
Run Code Online (Sandbox Code Playgroud)

此后我得到以下异常:

Request processing failed; nested exception is java.lang.ClassCastException: org.springframework.security.core.userdetails.User cannot be cast to net.viralpatel.contact.model.User
Run Code Online (Sandbox Code Playgroud)

这是一个问题 - 我如何将User作为对象,我应该如何修改我的类UserDetailsS​​erviceImpl和UserAssembler,任何想法?

@Component
@Transactional
public class UserDetailsServiceImpl implements UserDetailsService{

    @Autowired
    private UserDAO userDAO;

    @Autowired
    private UserAssembler userAssembler;

    private static final Logger logger = LoggerFactory.getLogger(UserDetailsServiceImpl.class);

    @Transactional(readOnly = true)
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
        User user = userDAO.findByEmail(username);

        if(null == user) throw new UsernameNotFoundException("User not found");
        return userAssembler.buildUserFromUser(user);
    }
}
Run Code Online (Sandbox Code Playgroud)

还有一个:

@Service("assembler")
public class UserAssembler {

    @Autowired
    private UserDAO userDAO;

    @Transactional(readOnly = true)
    public User buildUserFromUser(net.viralpatel.contact.model.User user) {
        String role = "ROLE_USER";//userEntityDAO.getRoleFromUserEntity(userEntity);

        Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        authorities.add(new GrantedAuthorityImpl(role));

        return new User(user.getLogin(), user.getPassword(), true, true, true, true,  authorities);
    }
}
Run Code Online (Sandbox Code Playgroud)

axt*_*avt 13

基本上,您需要返回一个实现UserDetails,提供对您的访问User.

您有两种选择:

  • 添加你User的字段(你可以扩展org.springframework.security.core.userdetails.User):

    public class UserPrincipal extends org.springframework.security.core.userdetails.User {
        private final User user;
       ...
    }  
    
    Run Code Online (Sandbox Code Playgroud)

    User从该领域获得一个:

    Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    User user = ((UserPrincipal) principal).getUser();
    
    Run Code Online (Sandbox Code Playgroud)
  • 创建一个扩展您的User和实现的类UserDetails:

    public class UserPrincipal extends User implements UserDetails {
        ...
        public UserPrincipal(User user) {
            // copy fields from user
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    此方法允许您User直接转换主体:

    User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    
    Run Code Online (Sandbox Code Playgroud)


小智 0

看起来你的 User 类没有扩展 Spring 的 org.springframework.security.core.userdetails.User 类。

这是供参考的示例代码,我将类命名为“AuthenticUser”:

 public class AuthenticUser extends User {

        public AuthenticUser(String username, String password, boolean enabled,
        boolean accountNonExpired, boolean credentialsNonExpired,
        boolean accountNonLocked,
        Collection<? extends GrantedAuthority> authorities) {

        super(username, password, enabled, accountNonExpired, credentialsNonExpired,
            accountNonLocked, authorities);
    }
   .....
   .....
 }
Run Code Online (Sandbox Code Playgroud)

现在您可以在代码中创建此类的对象并将其设置为 Spring Authentication Context 的一部分,例如

  AuthenticUser user  = new AuthenticUser(username, password, .... rest of the parameters);
  Authentication authentication =  new UsernamePasswordAuthenticationToken(user, null,
      user.getAuthorities());
  SecurityContextHolder.getContext().setAuthentication(authentication);
Run Code Online (Sandbox Code Playgroud)

这将验证您的用户并在安全上下文中设置用户。