Shiro源码学习---SecurityManager

 1.  我们知道SecurityManager安全管理器,是Shiro的核心,现在就看一下这个

public interface SecurityManager extends Authenticator, Authorizer, SessionManager {
    //登录方法
    Subject login(Subject subject, AuthenticationToken authenticationToken) throws AuthenticationException;
    //注销方法
    void logout(Subject subject);
    //创建subject
     Subject createSubject(SubjectContext context);

}

初始的安全管理器接口有三个方法,并且实现了三个接口,分别来看一下,这三个接口

    1.1 Authenticator(认证器) ,用户登录时候会调用

public interface Authenticator {  
    //初始的认证方法,入参是一个令牌对象,返回值是一个包装好的身份信息
 public AuthenticationInfo authenticate(AuthenticationToken authenticationToken)  throws AuthenticationException;
}

    1.2  Authorizer(授权器) 检查是否具有相关的权限.这个接口定义的都是检查权限和角色的方法

    1.3  SessionManager(会话管理器)  这个后面会有详细的解释

2.  Securitymanager的继承体系

    

    与spring整合的默认安全管理器就是图中标注的那个,一般如果不自己定义的话,就会使用这个东西

很有意思的集成体系,每次继承都实现一些接口,或者实现一些特色的功能,这个学习到了

    2.1 CacheSecurityManager 从名字就可以知道它应该是注入了缓存相关的东西

        2.1.1 定义

public abstract class CachingSecurityManager implements SecurityManager, Destroyable, CacheManagerAware, EventBusAware 

        实现了四个接口,除了第一个,后面三个都是简单的,暂时不做处理

        2.1.2 属性

      //注入的缓存管理器
      private CacheManager cacheManager;
       //不知道这个鬼是什么作用,感觉想那种can总线结构
      private EventBus eventBus;

        2.1.3 构造

        public CachingSecurityManager() {
        //注入了一个默认的eventBus
        setEventBus(new DefaultEventBus());
        }

        2.1.4 一些有意思的方法 

            //这个方法就是将默认eventBus注入cachemanager中.这个写法后面还有用到           
            //这个方法会在 setCacheManager(CacheManager cacheManager) 里面执行        
            protected void applyEventBusToCacheManager() {
            if (this.eventBus != null && this.cacheManager != null && this.cacheManager instanceof EventBusAware) {
            ((EventBusAware)this.cacheManager).setEventBus(this.eventBus);
            }
        }

    2.2 RealmSecurityManager 这个抽象类实现了Realm(数据源)先关的功能

        2.2.1 定义    

        //没有实现任何接口,只做了继承
        public abstract class RealmSecurityManager extends CachingSecurityManager{} 

        2.2.2  属性  

        //注入了数据源的集合
        private Collection<Realm> realms;

        2.2.3  构造 //只有一个空实现

        2.2.4  一些方法

       //这个方法就是将缓存管理器,eventbus注入到realm中,这个方法在setRealms(Collection<Realm> realms)调用
       //realm需要实现CachemanagerAware接口,才能注入缓存管理器
        protected void afterRealmsSet() {
            applyCacheManagerToRealms();
            applyEventBusToRealms();
        }
        //这个方法定义了默认的realm的实现是一个arrayList集合
        public void setRealm(Realm realm) {
            if (realm == null) {
                throw new IllegalArgumentException("Realm argument cannot be null");
            }
            Collection<Realm> realms = new ArrayList<Realm>(1);
            realms.add(realm);
            setRealms(realms);
        }

    2.3 AuthenticatingSecurityManager 这个方法实现了认证的部分功能

        2.3.1 定义

//只是单纯的继承,没有实现任何借口
public abstract class AuthenticatingSecurityManager extends RealmSecurityManager{}

        2.3.2 属性

 private Authenticator authenticator;AuthorizingSecurityManager

        2.3.3 构造

//注入了一个认证器,这个认证器具有默认的实现ModularRealmAuthenticator
public AuthenticatingSecurityManager() {
        super();
        this.authenticator = new ModularRealmAuthenticator();
    }
        2.3.4 一些方法
//调用完父类的方法后,这个方法会将所有的数据源Realms集合注入到定义的authenticator中,注意这个必须是ModularRealmAuthenticator子类
protected void afterRealmsSet() {
        super.afterRealmsSet();
        if (this.authenticator instanceof ModularRealmAuthenticator) {
            ((ModularRealmAuthenticator) this.authenticator).setRealms(getRealms());
        }
}
//当调用这个方法后,就会调用默认的认证器中的认证方法
public AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException {
        return this.authenticator.authenticate(token);
    }

    2.4 AuthorizingSecurityManager  完成授权部分功能

        2.4.1 定义,只是单纯的继承,没有实现任何接口

        2.4.2 属性 单纯出入了一个授权器

private Authorizer authorizer;

        2.4.3 构造

// 注意这个授权器是有默认实现的 ,而且和上面那个类很类似,猛地一看差不多,其实不一样
public AuthorizingSecurityManager() {
        super();
        this.authorizer = new ModularRealmAuthorizer();
}
        2.4.4 一些方法
//和上面的类似,将所有的Realms注入到了授权器中,这个授权器必须是ModularRealmAuthorizer的子类
protected void afterRealmsSet() {
        super.afterRealmsSet();
        if (this.authorizer instanceof ModularRealmAuthorizer) {
            ((ModularRealmAuthorizer) this.authorizer).setRealms(getRealms());
        }
    }
//调用这个类的方法,会调用注入的授权器中相应的方法
public boolean isPermitted(PrincipalCollection principals, String permissionString) {
        return this.authorizer.isPermitted(principals, permissionString);
    }

    2.5 SessionsSecurityManager 注入了会话管理器

        2.5.1 定义 单纯的继承,没有实现

        2.5.2 属性  注入 会话管理器

 private SessionManager sessionManager;
        2.5.3 构造
// 注入了一个默认的会话管理器,并且将缓存管理器注入会话管理器中,要求,sessionManager必须实现了CacheManagerAware的接口
public SessionsSecurityManager() {
        super();
        this.sessionManager = new DefaultSessionManager();
        applyCacheManagerToSessionManager();
    }

    2.6 DefaultSecurityManager  默认非web环境的安全管理器

        2.6.1 定义 单纯的继承,没有实现

        2.6.2 属性

    protected RememberMeManager rememberMeManager;
    protected SubjectDAO subjectDAO;
    protected SubjectFactory subjectFactory;
        2.6.3 构造
//注意注入了默认的subjectFactory()和subjectDao 
public DefaultSecurityManager() {
        super();
        this.subjectFactory = new DefaultSubjectFactory();
        this.subjectDAO = new DefaultSubjectDAO();
    }
        2.6.4 一些方法
         //根据subjectContext以及令牌token,认证信息info,创建subject
protected Subject createSubject(AuthenticationToken token, AuthenticationInfo info, Subject existing) {
        SubjectContext context = createSubjectContext();
        context.setAuthenticated(true);
        context.setAuthenticationToken(token);
        context.setAuthenticationInfo(info);
        if (existing != null) {
            context.setSubject(existing);
        }
        return createSubject(context);
    }
//下面这三个,就是关于RememberMe功能,如果这个功能为true,那么就会执行相应的操作
 protected void rememberMeSuccessfulLogin(AuthenticationToken token, AuthenticationInfo info, Subject subject) {
        RememberMeManager rmm = getRememberMeManager();
        if (rmm != null) {
            try {
                rmm.onSuccessfulLogin(subject, token, info);
            } catch (Exception e) {
                }
            }
        } else {
            }
        }
    }

    protected void rememberMeFailedLogin(AuthenticationToken token, AuthenticationException ex, Subject subject) {
        RememberMeManager rmm = getRememberMeManager();
        if (rmm != null) {
            try {
                rmm.onFailedLogin(subject, token, ex);
            } catch (Exception e) {
                }
            }
        }
    }

    protected void rememberMeLogout(Subject subject) {
        RememberMeManager rmm = getRememberMeManager();
        if (rmm != null) {
            try {
                rmm.onLogout(subject);
            } catch (Exception e) {
                }
            }
        }
    }
//这个就是登录执行的认证功能,调用认证器中的认证方法,回逐级调用
 public Subject login(Subject subject, AuthenticationToken token) throws AuthenticationException {
        AuthenticationInfo info;
        try {
            info = authenticate(token);
        } catch (AuthenticationException ae) {
            try {
                onFailedLogin(token, ae, subject);
            } catch (Exception e) {
                ...
                 }
            }
            throw ae; //propagate
        }
        Subject loggedIn = createSubject(token, info, subject);
        onSuccessfulLogin(token, info, loggedIn);
        return loggedIn;
    }
//这是注销方法,
 public void logout(Subject subject) {
        if (subject == null) {
            throw new IllegalArgumentException("Subject method argument cannot be null.");
        }
        //注销remeberme操作
        beforeLogout(subject);
        PrincipalCollection principals = subject.getPrincipals();
        if (principals != null && !principals.isEmpty()) {
            Authenticator authc = getAuthenticator();
            if (authc instanceof LogoutAware) {
                //我们知道authc是有一个默认值的,这个默认值是实现了LogoutAware这个接口的
                ((LogoutAware) authc).onLogout(principals);
            }
        }
        try {
            delete(subject);
        } catch (Exception e) {
           
            }
        } finally {
            try {
                stopSession(subject);
            } catch (Exception e) {
               
                }
            }
        }
    } 

    2.7 DefaultWebSecurityManager  默认的继承web层次的安全管理器

        2.7.1 定义  除了继承之外,还实现了一个接口,这个接口的功能就是判断当前是否是web环境

public class DefaultWebSecurityManager extends DefaultSecurityManager implements WebSecurityManager{}

         2.7.5 属性

      只有三个过期的属性,自1.2之后就不应使用了

    @Deprecated
    public static final String HTTP_SESSION_MODE = "http";
    @Deprecated
    public static final String NATIVE_SESSION_MODE = "native";
    /**
     * @deprecated as of 1.2.  This should NOT be used for anything other than determining if the sessionMode has changed.
     */
    @Deprecated
    private String sessionMode;

         2.7.3 构造

public DefaultWebSecurityManager() {
        super();
        ((DefaultSubjectDAO) this.subjectDAO).setSessionStorageEvaluator(new DefaultWebSessionStorageEvaluator());
        this.sessionMode = HTTP_SESSION_MODE;
        setSubjectFactory(new DefaultWebSubjectFactory());
        setRememberMeManager(new CookieRememberMeManager());
        setSessionManager(new ServletContainerSessionManager());
    }

            重置了subjectFactory,rememberMeManager,SessionManager这三个默认值

        2.7.4 一些方法

//这个就是现在判断是不是web环境的,方法在构造中已经重置了sessionmMnager为ServletContainerSessionManager,这个类的isSer..()方法返回就是true
public boolean isHttpSessionMode() {
        SessionManager sessionManager = getSessionManager();
        return sessionManager instanceof WebSessionManager && ((WebSessionManager)sessionManager).isServletContainerSessions();
    }




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值