我们来看一下Authentication(认证信息)的结构,它是一个接口,我们之前提到的 UsernamePasswordAuthenticationToken就是它的实现之一:
先看一下源码:
public interface Authentication extends Principal, Serializable {
Collection extends GrantedAuthority> getAuthorities();
Object getCredentials();
Object getDetails();
Object getPrincipal();
boolean isAuthenticated();
void setAuthenticated(boolean var1) throws IllegalArgumentException;
}
再来看一下每个方法对应的意思:
最后看一下该接口的实现体系:
这里参考:Authentication详解_「已注销」的博客-CSDN博客_authentication.getprincipal()
(1). Authentication是spring security包中的接口,直接继承自Principal类,而Principal是位于java.security包中的。可以见得,Authentication在spring security中是最高级别的身份/认证的抽象。
(2).由这个顶级接口,我们可以得到用户拥有的权限信息列表,密码,用户细节信息,用户身份信息,认证信息。
在之前的浅谈AuthenticationManager文章中,我们知道了:当web表单提交用户名密码时,AuthenticationManager初始化委托AuthenticationProvider进行处理表单,AuthenticationProvider找到对应的DaoAuthenticationProvider进行认证处理。
认证成功后既得到一个 Authentication(UsernamePasswordAuthenticationToken实现),里面包含了身份信息(Principal)。这个身份 信息就是一个 Object ,大多数情况下它可以被强转为UserDetails对象。
所以我们从这里可以知道Authentication是用来封装用户的认证信息的!
这里引用:Spring Security:身份验证令牌Authentication介绍与Debug分析_spring访问令牌认证_ITKaven的博客-CSDN博客
它是一种Authentication实现,继承AbstractAuthenticationToken抽象类,旨在简单地表示用户名和密码。principal和credentials属性应设置为通过其toString方法提供相应属性的Object,最简单的就是String类型。
public class UsernamePasswordAuthenticationToken extends AbstractAuthenticationToken {
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
private final Object principal;
private Object credentials;
/**
* 任何希望创建UsernamePasswordAuthenticationToken实例的代码都可以安全地使用此构造函数
* 因为isAuthenticated()将返回false
*/
public UsernamePasswordAuthenticationToken(Object principal, Object credentials) {
super(null);
this.principal = principal;
this.credentials = credentials;
setAuthenticated(false);
}
/**
* 此构造函数只能由满足生成可信(即isAuthenticated() = true )身份验证令牌的AuthenticationManager或AuthenticationProvider实现使用
*/
public UsernamePasswordAuthenticationToken(Object principal, Object credentials,
Collection extends GrantedAuthority> authorities) {
super(authorities);
this.principal = principal;
this.credentials = credentials;
super.setAuthenticated(true); // 必须使用super来设置
}
// 返回凭证(如密码)
public Object getCredentials() {
return this.credentials;
}
// 返回实体(如用户名)
public Object getPrincipal() {
return this.principal;
}
// 设置isAuthenticated属性,只能设置为false
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
// 无法将此令牌设置为受信任的令牌
// 需要使用有GrantedAuthority列表参数的构造函数
if (isAuthenticated) {
throw new IllegalArgumentException(
"Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");
}
super.setAuthenticated(false);
}
// 重写eraseCredentials方法
// 将凭证直接设置为null
@Override
public void eraseCredentials() {
super.eraseCredentials();
credentials = null;
}
}
RememberMeAuthenticationToken
它是一种Authentication实现,继承AbstractAuthenticationToken抽象类,表示需要记住的Authentication,需要记住的Authentication必须提供完全有效的Authentication ,包括适用的GrantedAuthority。
public class RememberMeAuthenticationToken extends AbstractAuthenticationToken {
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
// 主体
private final Object principal;
// 识别此对象是否由授权客户生成的key的hashCode
private final int keyHash;
/**
* 构造函数
* 参数:
* key – 识别此对象是否由授权客户生成
* principal – 主体(通常是UserDetails)
* authorities — 授予主体的权限
*/
public RememberMeAuthenticationToken(String key, Object principal,
Collection extends GrantedAuthority> authorities) {
super(authorities);
if ((key == null) || ("".equals(key)) || (principal == null)
|| "".equals(principal)) {
throw new IllegalArgumentException(
"Cannot pass null or empty values to constructor");
}
this.keyHash = key.hashCode();
this.principal = principal;
setAuthenticated(true);
}
/**
* 帮助Jackson反序列化的私人构造函数
* 参数:
* keyHash – 上面给定key的hashCode
* principal – 主体(通常是UserDetails)
* authorities — 授予主体的权限
*/
private RememberMeAuthenticationToken(Integer keyHash, Object principal, Collection extends GrantedAuthority> authorities) {
super(authorities);
this.keyHash = keyHash;
this.principal = principal;
setAuthenticated(true);
}
/**
* 总是返回一个空String
*/
@Override
public Object getCredentials() {
return "";
}
// 返回keyHash
public int getKeyHash() {
return this.keyHash;
}
// 返回主体
@Override
public Object getPrincipal() {
return this.principal;
}
}
它是一种Authentication实现,继承AbstractAuthenticationToken抽象类,用于预认证身份验证。有些情况下,希望使用Spring Security进行授权,但是在访问应用程序之前,用户已经被某个外部系统可靠地验证过了,将这种情况称为预认证场景,比如CSDN可以使用其他平台的账号进行登陆,如下图所示:
public class PreAuthenticatedAuthenticationToken extends AbstractAuthenticationToken {
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
// 主体
private final Object principal;
// 凭证
private final Object credentials;
/**
* 用于身份验证请求的构造函数
* isAuthenticated()将返回false
*/
public PreAuthenticatedAuthenticationToken(Object aPrincipal, Object aCredentials) {
super(null);
this.principal = aPrincipal;
this.credentials = aCredentials;
}
/**
* 用于身份验证响应的构造函数
* isAuthenticated()将返回true
*/
public PreAuthenticatedAuthenticationToken(Object aPrincipal, Object aCredentials,
Collection extends GrantedAuthority> anAuthorities) {
super(anAuthorities);
this.principal = aPrincipal;
this.credentials = aCredentials;
setAuthenticated(true);
}
/**
* 返回凭证
*/
public Object getCredentials() {
return this.credentials;
}
/**
* 返回主体
*/
public Object getPrincipal() {
return this.principal;
}
}
其余还有几种实现类解析,具体可去Spring Security:身份验证令牌Authentication介绍与Debug分析_spring访问令牌认证_ITKaven的博客-CSDN博客进行阅读