我正在尝试向使用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();
}
}
答案 0 :(得分:0)
my.app.model.User
和org.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
的导入,然后添加您自己的导入语句。