• (二)Shiro之一些重要的组件和工具类


    由于笔者水平有限,难免有说不清楚,或者理解有偏差的地方,望指正。


    SecurityManager:
    SecurityManager是shiro的核心组件,安全管理器;它的主要实现类有DefaultWebSecurityManager,并且当你在不指定的情况下会通过以下方法进行:

    protected WebSecurityManager createDefaultSecurityManager() {
    		//该方法是在AbstractShiroFilter中的方法,这是在web应用中用到的过滤器,一般会在web.xml中配置ShiroFilter 而,shiroFilter则extends AbstractShiroFilter;所以当在shiro.ini中不指定或者与Spring集成的时候;便会生成这个默认的安全器类
            return new DefaultWebSecurityManager();
     }
    

    SecurityManager接口继承了Authenticator, Authorizer, SessionManager三个接口;
    并且提供了一下三个方法:

        //登录
        Subject login(Subject subject, AuthenticationToken authenticationToken) throws AuthenticationException;
        //登出
        void logout(Subject subject);
        //创建Subject
        Subject createSubject(SubjectContext context);
    

    SecurityUtils:
    以下是它所含的代码:

    private static SecurityManager securityManager;
    public static Subject getSubject() {
            Subject subject = ThreadContext.getSubject();
            if (subject == null) {
                subject = (new Subject.Builder()).buildSubject();
                ThreadContext.bind(subject);
            }
            return subject;
        }
        public static void setSecurityManager(SecurityManager securityManager) {
            SecurityUtils.securityManager = securityManager;
        }
        public static SecurityManager getSecurityManager() throws UnavailableSecurityManagerException {
            SecurityManager securityManager = ThreadContext.getSecurityManager();
            if (securityManager == null) {
                securityManager = SecurityUtils.securityManager;
            }
            if (securityManager == null) {
                String msg = "No SecurityManager accessible to the calling code, either bound to the " +
                        ThreadContext.class.getName() + " or as a vm static singleton.  This is an invalid application " +
                        "configuration.";
                throw new UnavailableSecurityManagerException(msg);
            }
            return securityManager;
        }
    

    可以将安全管理器组件,利用setSecurityManagement()方法设置到私有对象securityManager中,然后获取到Subject对象,然后进行登录登出的操作。

    Subject:
    Subject current = SecurityUtils.getSubject();`Subject是一个接口;从SecurityUtils工具类中的getSubject()静态方法中获取得到,
    方法如下:

    public static Subject getSubject() {
            Subject subject = ThreadContext.getSubject();
            if (subject == null) {
                subject = (new Subject.Builder()).buildSubject();
                ThreadContext.bind(subject);
            }
            return subject;
        }
    
    

    可以看出,是从当前线程上下文中获取得到的;而它代表的是:A Subject represents state and security operations for a single application user. These operations include authentication (login/logout), authorization (access control), and session access. It is Shiro’s primary mechanism for single-user security functionality.

    UsernamePasswordToken:
    一个包含用户名和密码的令牌,这是需要去校验的用户信息,Subject提供了login(token)方法;

    Realm
    realm是shiro中一个比较重要的接口,它提供了供应用进行安全实体如:用户、角色和权限的认证和授权操作。对接的数据源可以是jdbc、file system i/o、jpa等

        String getName();
    
        boolean supports(AuthenticationToken token);
    
        AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException;
    

    但是在使用过程中,大家一般不会直接去实现Realm接口进行自定义操作,而是往往继承它的子类:AuthenticatingRealm 、AuthorizingRealm;一般只需要继承AuthorizingRealm便可以,因为它同时继承了AuthenticatingRealm;有以下两个方法需要实现:

    @Override
    	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    		//进行授权认证
    		return null;
    	}
    
    	@Override
    	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    		//进行身份验证
    		return new SimpleAuthenticationInfo(username, password, "myRealm");
    	}
    

    当然,需要注意的是自定义的Realm实现类需要在初始化的配置文件或者是spring的xml中进行添加,注给RealmSecurityManager的realms属性

     private Collection<Realm> realms;
     public void setRealms(Collection<Realm> realms) {
            if (realms == null) {
                throw new IllegalArgumentException("Realms collection argument cannot be null.");
            }
            if (realms.isEmpty()) {
                throw new IllegalArgumentException("Realms collection argument cannot be empty.");
            }
            this.realms = realms;
            afterRealmsSet();
        }
    
  • 相关阅读:
    codevs 1031 质数环
    codevs 1005 生日礼物
    codevs 1004 四子连棋
    codevs 2292 图灵机游戏
    1439 统计素数个数
    1675 大质数 2
    codevs 1462 素数和
    [NOIp2012提高组]借教室
    [NOIp2007提高组]矩阵取数游戏
    [TJOI2017]城市
  • 原文地址:https://www.cnblogs.com/Kevin-1992/p/12608425.html
Copyright © 2020-2023  润新知