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

时间:2015-08-26 17:36:56

标签: java spring spring-mvc spring-security

我正在尝试向使用Spring Security的应用添加自定义UserDetailsService。但是CustomUserDetailsService.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

那么如何以一种使自定义UserDetailsService正常工作的方式解决此错误?以下是CustomUserDetailsService.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();
    }

}

1 个答案:

答案 0 :(得分:0)

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

好的,您只需要明确指出您在特定时间处理的是哪一个。您的AppService班级会返回my.app.model.User,但您的CustomUserDetailsService实际上已导入org.springframework.security.core.userdetails.User

您有两种选择。 错误的方式是这样做:

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

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

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