SpringSecurity框架原理浅谈之UserDetails

 

先看一下UserDetails的源码和实现结构

public interface UserDetails extends Serializable {

Collection<? extends GrantedAuthority> getAuthorities();
String getPassword();
String getUsername();
boolean isAccountNonExpired();
boolean isAccountNonLocked();
boolean isCredentialsNonExpired();
boolean isEnabled();

}

该类文档注释中有这么一段话:

提供用户核心信息。

Spring Security不直接使用实现来实现安全性。它们只是存储稍后封装到Authentication对象中的用户信息。这使得与安全无关的用户信息(如电子邮件地址、电话号码等)可以存储在一个方便的位置。

那这句话什么意思呢?

  • 该接口是提供用户信息的核心接口。
  • 该接口实现仅仅存储用户的信息。
  • 后续会将该接口提供的用户信息封装到认证对象中去。

那UserDetails默认提供的方法都是什么意思呢?

1.Collection<? extends GrantedAuthority> getAuthorities();

用户的权限集, 默认需要添加前缀

2.String getPassword();

用户的加密后的密码, 不加密会使用前缀

3.String getUsername();

应用内唯一的用户名

4.boolean isAccountNonExpired();

账户是否过期

5.boolean isAccountNonLocked();

账户是否锁定

6.boolean isCredentialsNonExpired();

凭证是否过期

7.boolean isEnabled();

用户是否可用

它和Authentication接口很类似,比如它们都拥有username,authorities。Authentication的getCredentials()与 UserDetails中的getPassword()需要被区分对待,前者是用户提交的密码凭证,后者是用户实际存储的密码(数据库中的密码),认证其实就是对这两者的比对。Authentication中的getAuthorities()实际是由UserDetails的getAuthorities()传递而形成的。还记得Authentication接口中的getDetails()方法吗?其中的UserDetails用户详细信息便是经过了 AuthenticationProvider认证之后被填充的。

在实际开发中,如果以上的信息满足不了你使用(通常是满足不了的),你可以自行实现扩展以存储更多的用户信息。比如用户的邮箱、手机号等等。也就是说咱们可以自己去实现这个接口,然后在其基础上,加上自己想要的属性,下面给个示例:

package com.itheima.stock.security.detail;

import com.itheima.stock.pojo.vo.PermissionRespNodeVo;
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.util.List;

/**
 * @author Mr.huang
 * @version 1.0
 * @description 自定义用户认证详情类
 * @date 2023/2/9 9:16
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class LoginUserDetail implements UserDetails {


    /*
        用户密码
     */
   private String password;
//    @Override
//    public String getPassword() {
//        return null;
//    }
    /*
        用户名
     */
    private String username;

//    @Override
//    public String getUsername() {
//        return null;
//    }
    /*
        权限信息
     */
    private List<GrantedAuthority> authorities;
//    @Override
//    public Collection<? extends GrantedAuthority> getAuthorities() {
//        return null;
//    }
    /*
    账户是否过期
     */
    private boolean isAccountNonExpired=true;
//    @Override
//    public boolean isAccountNonExpired() {
//        return false;
//    }
    /*
    账号是否被锁定
    true 没有被锁定
     */
    private boolean isAccountNonLocked=true;

//    @Override
//    public boolean isAccountNonLocked() {
//        return false;
//    }
    /*
    密码是否过期
    true 没有过期
     */
    private boolean isCredentialsNonExpired=true;
//    @Override
//    public boolean isCredentialsNonExpired() {
//        return false;
//    }
    /*
    账户是否禁用
    true:没有禁用
     */
    private boolean isEnabled=true;
//    @Override
//    public boolean isEnabled() {
//        return false;
//    }

    /**
     * 用户ID
     */
    private String id;
    /**
     * 电话
     */
    private String phone;
    /**
     * 昵称
     */
    private String nickName;

    /**
     * 真实姓名
     */
    private String realName;

    /**
     * 性别(1.男 2.女)
     */
    private Integer sex;

    /**
     * 账户状态(1.正常 2.锁定 )
     */
    private Integer status;

    /**
     * 邮箱
     */
    private String email;

    /**
     * 权限树,不包含按钮相关权限信息
     */
    private List<PermissionRespNodeVo> menus;

    /**
     * 按钮权限集合
     */
    private List<String> permissions;
}

 

那这个类会用到哪里呢?

当 UserDetailsService 调用UserDetails loadUserByUsername(String loginName)方法时

这个方法会根据用户名提取用户信息 UserDetails(包含密码) ,一般是从数据库中提取信息进行组装,最后返回一个UserDetails实例.loadUserByUsername方法返回之后的UserDetails就去和 Authentication中的数据做认证并传递数据,形成认证之后的Authentication,即successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult)方法中的Authentication!

如果这篇文章对您有帮助,请动动你的小手指,点个关注和赞!,鼓励鼓励作者

 

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.huang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值