相关阅读
- Spring Shiro流程简析 登录请求处理
- Spring Shiro基础组件 AuthenticationStrategy
- Spring Shiro基础组件 AuthenticationToken
- Spring Shiro基础组件 Authenticator
简介
表示Subject
存储的只和鉴权/登录过程相关的账户信息;
AuthenticationInfo
表示已经验证过且存储在系统中的账户信息;
AuthenticationToken
表示登录时提交的凭据信息(可能匹配,也可能不匹配AuthenticationInfo
);
AuthorizationInfo
表示访问控制数据,如角色和权限;
核心方法
/**
* 获取关联Subject的principal集合
*/
PrincipalCollection getPrincipals();
/**
* 获取关联Subject的凭据
*/
Object getCredentials();
实现子类
public interface AuthenticationInfo extends Serializable
public interface Account extends AuthenticationInfo, AuthorizationInfo
public class SimpleAccount implements Account, MergableAuthenticationInfo, SaltedAuthenticationInfo, Serializable
public interface MergableAuthenticationInfo extends AuthenticationInfo
public class SimpleAccount implements Account, MergableAuthenticationInfo, SaltedAuthenticationInfo, Serializable
public class SimpleAuthenticationInfo implements MergableAuthenticationInfo, SaltedAuthenticationInfo
public interface SaltedAuthenticationInfo extends AuthenticationInfo
public class SimpleAccount implements Account, MergableAuthenticationInfo, SaltedAuthenticationInfo, Serializable
public class SimpleAuthenticationInfo implements MergableAuthenticationInfo, SaltedAuthenticationInfo
Account
简介
同时继承AuthenticationInfo
和AuthorizationInfo
接口,表示单个Realm
中单个账户的鉴权和授权;
核心方法
无
MergableAuthenticationInfo
简介
支持合并其它AuthenticationInfo
的实现,即允许本类实例是来自多个Realm
的账户数据的聚合或者组合;
支持多Realm
鉴权;
核心方法
/**
* 合并指定的AuthenticationInfo
*/
void merge(AuthenticationInfo info);
SaltedAuthenticationInfo
简介
表示支持使用盐值进行哈希凭据信息的账户信息,主要为了支持需要哈希用户凭据的环境;
盐值通常从安全的伪随机数生成器生成,和账户信息一起安全地存储,和账户的凭据一起维护;
核心方法
/**
* 获取账户凭据使用的盐值
*/
ByteSource getCredentialsSalt();
SimpleAuthenticationInfo
简介
MergableAuthenticationInfo
的简单实现;
核心方法
// principal集合
protected PrincipalCollection principals;
// credentials
protected Object credentials;
// 盐值
protected ByteSource credentialsSalt;
/**
* 构造方法
*/
public SimpleAuthenticationInfo(Object principal, Object hashedCredentials, ByteSource credentialsSalt, String realmName) {
this.principals = new SimplePrincipalCollection(principal, realmName);
this.credentials = hashedCredentials;
this.credentialsSalt = credentialsSalt;
}
/**
* 获取关联Subject的principal集合
*/
public PrincipalCollection getPrincipals() {
return principals;
}
/**
* 获取关联Subject的凭据
*/
public Object getCredentials() {
return credentials;
}
/**
* 获取账户凭据使用的盐值
*/
public ByteSource getCredentialsSalt() {
return credentialsSalt;
}
/**
* 合并指定的AuthenticationInfo
*/
public void merge(AuthenticationInfo info) {
// 校验入参
if (info == null || info.getPrincipals() == null || info.getPrincipals().isEmpty()) {
return;
}
if (this.principals == null) {
// 原principal集合不存在,直接用入参覆盖
this.principals = info.getPrincipals();
} else {
if (!(this.principals instanceof MutablePrincipalCollection)) {
// 如果当前principals属性不是MutablePrincipalCollection实例,则包装该属性为SimplePrincipalCollection
this.principals = new SimplePrincipalCollection(this.principals);
}
// 添加principal集合
((MutablePrincipalCollection) this.principals).addAll(info.getPrincipals());
}
// 盐值只在realm的credentials认证过程中使用,所以合并来自不同realm的盐值也没意义
// 但如果当前实例的盐值为null,那么如果存在非空值,放入一个非空值也无妨
//only mess with a salt value if we don't have one yet. It doesn't make sense
//to merge salt values from different realms because a salt is used only within
//the realm's credential matching process. But if the current instance's salt
//is null, then it can't hurt to pull in a non-null value if one exists.
//
//since 1.1:
if (this.credentialsSalt == null && info instanceof SaltedAuthenticationInfo) {
// 当前实例的盐值为null,直接使用入参的盐值
this.credentialsSalt = ((SaltedAuthenticationInfo) info).getCredentialsSalt();
}
Object thisCredentials = getCredentials();
Object otherCredentials = info.getCredentials();
if (otherCredentials == null) {
// 无需合并其他的credentials
return;
}
if (thisCredentials == null) {
// 直接使用入参的credentials
this.credentials = otherCredentials;
return;
}
if (!(thisCredentials instanceof Collection)) {
// 当前实例的credentials不是一个集合就创建一个集合存储credentials
Set newSet = new HashSet();
newSet.add(thisCredentials);
setCredentials(newSet);
}
// 此时实例的credentials是集合对象
// At this point, the credentials should be a collection
Collection credentialCollection = (Collection) getCredentials();
if (otherCredentials instanceof Collection) {
// 入参的credentials是集合对象
credentialCollection.addAll((Collection) otherCredentials);
} else {
// 入参的credentials是单个对象
credentialCollection.add(otherCredentials);
}
}
SimpleAccount
简介
Account
的简单实现,内部使用SimpleAuthenticationInfo
和SimpleAuthorizationInfo
实例实现Account
接口;
核心方法
// 鉴权信息,实现AuthenticationInfo接口
private SimpleAuthenticationInfo authcInfo;
// 授权信息,实现AuthorizationInfo接口
private SimpleAuthorizationInfo authzInfo;
// 账户锁定标识
private boolean locked;
// 账户过期标识
private boolean credentialsExpired;
/**
* 构造方法
*/
public SimpleAccount(PrincipalCollection principals, Object credentials) {
// 鉴权信息
this.authcInfo = new SimpleAuthenticationInfo(principals, credentials);
// 授权信息
this.authzInfo = new SimpleAuthorizationInfo();
}
/**
* 获取锁定标识
*/
public boolean isLocked() {
return locked;
}
/**
* 设置锁定标识
*/
public void setLocked(boolean locked) {
this.locked = locked;
}
/**
* 获取过期标识
*/
public boolean isCredentialsExpired() {
return credentialsExpired;
}
/**
* 设置过期标识
*/
public void setCredentialsExpired(boolean credentialsExpired) {
this.credentialsExpired = credentialsExpired;
}
/**
* 合并AuthenticationInfo
*/
public void merge(AuthenticationInfo info) {
// 合并鉴权信息
authcInfo.merge(info);
// Merge SimpleAccount specific info
if (info instanceof SimpleAccount) {
// 合并SimpleAccount的锁定和过期标识
SimpleAccount otherAccount = (SimpleAccount) info;
if (otherAccount.isLocked()) {
setLocked(true);
}
if (otherAccount.isCredentialsExpired()) {
setCredentialsExpired(true);
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/4791.html