SpringShiro基础组件AuthenticationInfo

导读:本篇文章讲解 SpringShiro基础组件AuthenticationInfo,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

相关阅读

简介

表示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

简介

同时继承AuthenticationInfoAuthorizationInfo接口,表示单个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的简单实现,内部使用SimpleAuthenticationInfoSimpleAuthorizationInfo实例实现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

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!