天天看點

class org.springframework.security.core.userdetails.User cannot be cast to class com.lp.common.mode.問題描述原因分析:解決方案:

問題描述

在使用springsecurity進行登陸認證時,出現如下錯誤

class org.springframework.security.core.userdetails.User cannot be cast to class com.lp.common.mode.LoginUser
           

意思是說

類org.springframework.security.core.userdetails.User不能強制轉換為類com.lp.common.mode.LogUser

以下是我的代碼:

從寫的loadUserByUsername方法

@Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//        擷取使用者資訊
//        System.out.println(username);
        TUser tUser = tUserService.getUserInfoByName(username);
//        System.out.println(tUser);
        if (StringUtils.isNull(tUser)){
            throw new UserException("user is not null",null);
        }
        
        List<GrantedAuthority> arrayList = new ArrayList<>();
        List<TRoles> roles = tUser.getRoles();//擷取使用者角色權限
        if (roles != null && roles.size() > 0){//周遊角色
            for (TRoles role : roles) {
                arrayList.add(new SimpleGrantedAuthority(role.getRole_key()));
            }
        }
//        passWordService.validate(tUser);//密碼驗證
//        return createLoginUser(tUser);
        return new User(username,tUser.getPassword(),arrayList);
           
LoginUser類
package com.lp.common.model;



import com.lp.common.entity.domain.TRoles;
import com.lp.common.entity.domain.TUser;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.Set;

/**
 * @author LuoPing
 * @date 2022/10/8 10:51
 * 登陸實體
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class LoginUser implements Serializable, UserDetails {
    private static final long serialVersionUID = 1L;

    /**
     * 使用者ID
     */
    private Long userId;
    /**
     * 使用者唯一辨別
     */
    private String token;
    /**
     * 登入時間
     */
    private Date loginTime;
    /**
     * 登入IP位址
     */
    private String ipaddr;

    /**
     * 登入地點
     */
    private String loginLocation;
    /**
     * 浏覽器類型
     */
    private String browser;
    /**
     * 作業系統
     */
    private String os;
    /**
     * 使用者資訊
     */
    private TUser tUser;

    private Set<String> roles;

    public LoginUser(Long id, TUser tUser, Set<String> role) {
        this.tUser = tUser;
        this.userId = id;
        this.roles = role;
    }

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    public Date getLoginTime() {
        return loginTime;
    }

    public void setLoginTime(Date loginTime) {
        this.loginTime = loginTime;
    }

    public String getIpaddr() {
        return ipaddr;
    }

    public void setIpaddr(String ipaddr) {
        this.ipaddr = ipaddr;
    }

    public String getLoginLocation() {
        return loginLocation;
    }

    public void setLoginLocation(String loginLocation) {
        this.loginLocation = loginLocation;
    }

    public String getBrowser() {
        return browser;
    }

    public void setBrowser(String browser) {
        this.browser = browser;
    }

    public String getOs() {
        return os;
    }

    public void setOs(String os) {
        this.os = os;
    }

    public TUser gettUser() {
        return tUser;
    }

    public void settUser(TUser tUser) {
        this.tUser = tUser;
    }

    public Set<String> getRoles() {
        return roles;
    }

    public void setRoles(Set<String> roles) {
        this.roles = roles;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return null;
    }

    @Override
    public String getPassword() {
        return tUser.getPassword();
    }

    @Override
    public String getUsername() {
        return tUser.getPassword();
    }
    /**
     * 賬戶是否未過期,過期無法驗證
     */
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }
    /**
     * 指定使用者是否解鎖,鎖定的使用者無法進行身份驗證
     *
     * @return
     */
    @Override
    public boolean isAccountNonLocked() {
        return true;
    }
    /**
     * 訓示是否已過期的使用者的憑據(密碼),過期的憑據防止認證
     *
     * @return
     */
    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }
    /**
     * 是否可用 ,禁用的使用者不能身份驗證
     *
     * @return
     */
    @Override
    public boolean isEnabled() {
        return true;
    }
}

           

原因分析:

網上資料顯示,問題在于UserDetailsServiceImpl.loadUserByUsername(…)的傳回語句。不能将User轉換為LoginUser對象,因為它們完全不同。應該傳回擴充UserDetails建立的對象。

class org.springframework.security.core.userdetails.User cannot be cast to class com.lp.common.mode.問題描述原因分析:解決方案:

解決方案:

因為LoginUser實作了Userdetais接口,是以我們在loadUserByUsername中傳回即可:

修改後代碼如下:
@Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//        擷取使用者資訊
//        System.out.println(username);
        TUser tUser = tUserService.getUserInfoByName(username);
//        System.out.println(tUser);
        if (StringUtils.isNull(tUser)){
            throw new UserException("user is not null",null);
        }

        List<GrantedAuthority> arrayList = new ArrayList<>();
        List<TRoles> roles = tUser.getRoles();//擷取使用者角色權限
        if (roles != null && roles.size() > 0){//周遊角色
            for (TRoles role : roles) {
                arrayList.add(new SimpleGrantedAuthority(role.getRole_key()));
            }
        }
//        passWordService.validate(tUser);//密碼驗證
        return createLoginUser(tUser);
//        return new User(username,tUser.getPassword(),arrayList);
    }

    private UserDetails createLoginUser(TUser tUser) {
        String token = IdUtils.fastUUID();//生成token
        //這裡使用建造者模式建立,因為LoginUser中添加的@Builder注解
        return LoginUser.builder()
                .userId(tUser.getId())
                .token(token)
                .tUser(tUser)
                .roles(permissionService.getRole(tUser))
                .build();
    }