Spring security 获取用户对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24980052/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 06:50:58  来源:igfitidea点击:

Spring security get User object

springspring-security

提问by user3127896

I have implemented user authentication through Spring Security Framework and everything works fine. I can log in and log out, I can get logged user name for example like this:

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

String userName = ((UserDetails) auth.getPrincipal()).getUsername();

Now i want to get user like an object from database(i need user id and other user properties).

现在我想从数据库中获取像对象一样的用户(我需要用户 ID 和其他用户属性)。

This how i have tried so far:

这是我迄今为止尝试过的方式:

User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();

Thereafter i got following exception:

此后我得到以下异常:

Request processing failed; nested exception is java.lang.ClassCastException: org.springframework.security.core.userdetails.User cannot be cast to net.viralpatel.contact.model.User

Here is a question - how can i get User as object, how should i modify my classes UserDetailsServiceImpl and UserAssembler, any ideas?

这是一个问题 - 我怎样才能将 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);
    }
}

And another one:

还有一个:

@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);
    }
}

回答by axtavt

Essentially, you need to return an implementation of UserDetailsthat provides access to your User.

本质上,您需要返回一个UserDetails提供对您的User.

You have two options:

您有两个选择:

  • Add your Useras a field (you can do it be extending org.springframework.security.core.userdetails.User):

    public class UserPrincipal extends org.springframework.security.core.userdetails.User {
        private final User user;
       ...
    }  
    

    and obtain a Userfrom that field:

    Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    User user = ((UserPrincipal) principal).getUser();
    
  • Create a class that extends your Userand implements UserDetails:

    public class UserPrincipal extends User implements UserDetails {
        ...
        public UserPrincipal(User user) {
            // copy fields from user
        }
    }
    

    This approach allows you to cast the principal to Userdirectly:

    User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    
  • 添加您User的字段(您可以扩展org.springframework.security.core.userdetails.User):

    public class UserPrincipal extends org.springframework.security.core.userdetails.User {
        private final User user;
       ...
    }  
    

    User从该字段中获取 a :

    Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    User user = ((UserPrincipal) principal).getUser();
    
  • 创建一个扩展您User并实现的类UserDetails

    public class UserPrincipal extends User implements UserDetails {
        ...
        public UserPrincipal(User user) {
            // copy fields from user
        }
    }
    

    这种方法允许您将主体User直接转换为:

    User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    

回答by Mayur Gupta

You need to implement your own UserDetailsService and your own UserDetails object(as per your wish):

您需要实现自己的 UserDetailsS​​ervice 和自己的 UserDetails 对象(根据您的意愿):

public class CustomService implements UserDetailsService {
@Transactional(readOnly = true)
public UserDetails loadUserByUsername(String userId) {

    Account account = accountDAO.findAccountByName(userId);

    // validation of the account
    if (account == null) {
        throw new UsernameNotFoundException("not found");
    }
    return buildUserFromAccount(account);
}


@SuppressWarnings("unchecked")
@Transactional(readOnly = true)
private User buildUserFromAccount(Account account) {

    // take whatever info you need
    String username = account.getUsername();
    String password = account.getPassword();
    boolean enabled = account.getEnabled();
    boolean accountNonExpired = account.getAccountNonExpired();
    boolean credentialsNonExpired = account.getCredentialsNonExpired();
    boolean accountNonLocked = account.getAccountNonLocked();

    // additional information goes here
    String companyName = companyDAO.getCompanyName(account);


    Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
    for (Role role : account.getRoles()) {
        authorities.add(new SimpleGrantedAuthority(role.getName()));
    }

    CustomUserDetails user = new CustomUserDetails (username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked,
            authorities, company);

    return user;
}


public class CustomUserDetails extends User{

// ...
public CustomUserDetails(..., String company){
     super(...);
     this.company = company;
}

private String company;

public String getCompany() { return company;}

public void setCompany(String company) { this.company = company;}
}

Note:
This is default implementation of User class you you need have some custom information that you can make a custom class and extend the User class

注意:
这是 User 类的默认实现,您需要一些自定义信息,您可以创建自定义类并扩展 User 类

回答by Bipul Sinha

It looks like your User class in not extending Spring's org.springframework.security.core.userdetails.User class.

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

Here is an example code for reference, I have termed class named as 'AuthenticUser':

这是一个供参考的示例代码,我将类命名为“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);
    }
   .....
   .....
 }

Now you can create an object of this class in your code and set it as part of Spring Authentication Context, e.g.

现在您可以在代码中创建此类的对象并将其设置为 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);

This will authenticate your user and set user in Security context.

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