java - 无法转换为 org.springframework.security.core.userdetails.User

标签 java spring spring-mvc spring-security

我正在尝试将自定义UserDetailsS​​ervice添加到使用Spring Security的应用程序中。但是 CustomUserDetailsS​​ervice.java 中的以下代码行:

User user = this.appService.findUserByUsernameAndPin(username, pin);

在 eclipse 中抛出以下编译错误:

Type Mismatch Error: cannot convert from my.app.model.User to org.springframework.security.core.userdetails.User

那么如何解决此错误,使自定义 UserDetailsS​​ervice 能够正常工作?这是 CustomUserDetailsS​​ervice.java:

package my.app.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import my.app.model.Role;

@Service
@Transactional(readOnly=true)
public class CustomUserDetailsService implements UserDetailsService {

    private final AppService appService;

    @Autowired
    public CustomUserDetailsService(AppService appService) {this.appService = appService;}

    @Override
    public UserDetails loadUserByUsername(String input) throws UsernameNotFoundException, DataAccessException{
        String[] split = input.split(":");
        if(split.length < 2)
        {
            System.out.println("User did not enter both username and pin code.");
            throw new UsernameNotFoundException("Must specify both username and pin code.");
        }

        String username = split[0];
        String pin = split[1];

        System.out.println("Username = " + username);
        System.out.println("Corporate domain = " + pin);

        //THE NEXT LINE NEEEDS TO BE FIXED.  BUT HOW?
        User user = this.appService.findUserByUsernameAndPin(username, pin);
        if(user == null){
            System.out.println("User could not be found, must be an invalid username/pin combo.");
            throw new UsernameNotFoundException("Invalid username or pin");
        }

        System.out.println("Returning user: " + user);
        return user;
    }

    public Collection<GrantedAuthority> getAuthorities(Set<Role> roles) {
    List<GrantedAuthority> authList = getGrantedAuthorities(getRolesAsList(roles));
    return authList;
}

public List<String> getRolesAsList(Set<Role> roles) {
    List <String> rolesAsList = new ArrayList<String>();
    for(Role role : roles){
        rolesAsList.add(role.getRole());
    }
    return rolesAsList;
}

public static List<GrantedAuthority> getGrantedAuthorities(List<String> roles) {
    List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();

    for (String role : roles) {
        authorities.add(new SimpleGrantedAuthority(role));
    }
    return authorities;
}

}  

my.app.model.User.java 实现 UserDetails 并且是:

package my.app.model;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

@Entity
@Table(name="users")
public class User implements UserDetails{

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue
    private Integer id;

    @Column(name= "email", unique=true, nullable=false)
    private String login;//must be a valid email address

    @Column(name = "password")
    private String password;

    @Column(name = "phone")
    private String phone;

    @Column(name = "pin")
    private String pin;

    @Column(name = "sessionid")
    private String sessionId;

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

    public Integer getId() {return id;}
    public void setId(Integer id) { this.id = id;}

    public String getPhone(){return phone;}
    public void setPhone(String pn){phone = pn;}

    public String getPin(){return pin;}
    public void setPin(String pi){pin = pi;}

    public String getSessionId(){return sessionId;}
    public void setSessionId(String sd){sessionId = sd;}

    public String getLogin() {
        return login;
    }

    public void setLogin(String login) {
        this.login = login;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    //roles methods
    public void addRole(Role alg) {roles.add(alg);}
    public Set<Role> getRoles(){
        if(this.roles==null){this.roles = new HashSet<Role>();}
        return this.roles;
    }
    public void setRoles(Set<Role> alg){this.roles = alg;}
    public boolean isInRoles(int aid){
        ArrayList<Role> mylgs = new ArrayList<Role>();
        mylgs.addAll(this.roles);
        for(int a=0;a<mylgs.size();a++){if(mylgs.get(a).getId()==aid){return true;}}
        return false;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public String getUsername() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public boolean isAccountNonExpired() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean isAccountNonLocked() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean isEnabled() {
        // TODO Auto-generated method stub
        return false;
    }
}

AppService.java 是:

package my.app.service;

import org.springframework.dao.DataAccessException;
import my.app.model.User;

public interface AppService {

public User getUser(String logn) throws DataAccessException;
    public User findUserByLogin(String ls) throws DataAccessException;
    public User findUserByUsernameAndPin(String username, String pin) throws DataAccessException;

}

AppServiceImpl.java 是:

package my.app.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import my.app.model.User;
import my.app.repository.UserRepository;

@Service
public class AppServiceImpl implements AppService {

    private UserRepository userRepository;

    @Autowired
    public AppServiceImpl(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    @Transactional(readOnly = true)
    public User getUser(String logn) throws DataAccessException {
        System.out.println("]]]]]]]]]  getting user [[[[[[[[");
        return userRepository.getUser(logn);
    }

    @Override
    @Transactional(readOnly = true)
    public User findUserByLogin(String uid) throws DataAccessException {
    return userRepository.findUserByLogin(uid);
}

    @Override
    @Transactional(readOnly = true)
    public User findUserByUsernameAndPin(String username, String pin) throws DataAccessException{
        return userRepository.findUserByUsernameAndPin(username, pin);
    }

}

UserRepository.java 是:

package my.app.repository;

import org.springframework.dao.DataAccessException;
import my.app.model.User;

public interface UserRepository {

    User getUser(String logn) throws DataAccessException;
    User findUserByLogin(String pid) throws DataAccessException;
    User findUserByUsernameAndPin(String username, String pin) throws DataAccessException;

}

JpaUserRepositoryImpl.java 是:

package my.app.repository.jpa;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.stereotype.Repository;
import my.app.model.User;
import my.app.repository.UserRepository;

@Repository
public class JpaUserRepositoryImpl implements UserRepository {

    @PersistenceContext
    private EntityManager em;

    @Override
    public User getUser(String logn) {
        Query query = this.em.createQuery("SELECT user FROM User user WHERE user.login =:logn");
        query.setParameter("logn", logn);
        User theuser = (User) query.getSingleResult();
        return theuser;
    }

    @SuppressWarnings("unchecked")
    public User findUserByLogin(String name) {
        Query query = this.em.createQuery("SELECT DISTINCT user FROM User user WHERE user.login =:name");
        query.setParameter("name", name + "%");
        return (User) query.getSingleResult();
    }

    @SuppressWarnings("unchecked")
    public User findUserByUsernameAndPin(String username, String pin){
        Query query = this.em.createQuery("SELECT DISTINCT user FROM User user WHERE user.login =:name AND user.pin =:pn");
        query.setParameter("name", username);
        query.setParameter("pn", pin);
        return (User) query.getSingleResult();
    }

}

最佳答案

my.app.model.Userorg.springframework.security.core.userdetails.User 之间存在类名冲突。

没关系,您只需要明确说明您在特定时间正在与哪一个打交道即可。您的 AppService 类返回 my.app.model.User,但您的 CustomUserDetailsS​​ervice 实际上已导入 org.springframework.security.core.userdetails.User

你有两个选择。 错误的方法是这样做:

my.app.model.User user = this.appService.findUserByUsernameAndPin(用户名, pin);

因为据我所知,Spring User 类实际上从未被需要。 您只是导入了错误的User类。

正确的解决方案是从 CustomUserDetailsS​​ervice 顶部的导入语句列表中删除 org.springframework.security.core.userdetails.User 的导入,并添加您自己的语句。

关于java - 无法转换为 org.springframework.security.core.userdetails.User,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32233139/

相关文章:

spring - 事务如何与多个 DAO 一起工作,想了解单个连接如何共享

java - Spring Security + AngularJS Ajax 帖子

java - Spring boot Controller 无法找到 bean 类

java - Spring Test Controller上传Json和Multipart文件总是返回405

java - 什么是NullPointerException,我该如何解决?

java - 在java中解决死锁的替代方法

java - 给定两个数组列表,如何计算有效组合数?

java - Java Eclipse SDK 入门

java - Spring数据Mongodb聚合排序顺序

java - 服务的任何公共(public)方法的 AOP 切入点表达式