zoukankan      html  css  js  c++  java
  • shiro小记

    shiro:
    
    流程:
    初始化SecurityManager工厂 => 获取SecurityManager => 获取subject => 根据用户名密码创建token => subject.login(token)验证 => 调用自定义的realms: 
    
    实现AuthorizingRealm自定义的realms验证流程:
    实现doGetAuthenticationInfo(token)方法获取AuthenticationInfo对象 =>  通过CredentialsMatcher对象doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info)方法验证AuthenticationInfo
    
    subject.login(token)调用时发生了什么?
    从源码可以得知Subject是接口,实现该接口的类有:
    Subject(接口):
    	DelegatingSubject(实现类):从源码可以得知是subject默认实现,因为有login(token)方法
    		WebDelegatingSubject(实现类):
    
    DelegatingSubject.login():方法会调用securityManager.login(this, token)方法;
    调用此方法中最重要的一个过程是调用new ModularRealmAuthenticator()对象的doAuthenticate(AuthenticationToken authenticationToken)方法
    protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {
            assertRealmsConfigured();
            Collection<Realm> realms = getRealms();
            if (realms.size() == 1) {
                return doSingleRealmAuthentication(realms.iterator().next(), authenticationToken);
            } else {
                return doMultiRealmAuthentication(realms, authenticationToken);
            }
        }
    从以上方法可以看出  getRealms()获取我们自定义配置的realms,然后依次调用
    
    
    1.========主要接口=========
    securityManager:
    	主要方法:
    	Subject login(Subject subject, AuthenticationToken authenticationToken) throws AuthenticationException;
    	void logout(Subject subject);
    	Subject createSubject(SubjectContext context);
    Realm:
    	主要方法:
    	String getName();
    	boolean supports(AuthenticationToken token);
    	AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException;
    		 
    CredentialsMatcher:
    	   主要方法:
    	 boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info);
    	 	
    2.=====主要接口的实现关系=======
    实现securityManager接口实现关系:
    securityManager:
    	CachingSecurityManager(抽象实现类):
    		RealmSecurityManager(抽象实现类):
    			AuthenticatingSecurityManager:(抽象实现类)
    				AuthorizingSecurityManager(抽象实现类):
    					SessionsSecurityManager(抽象实现类):
    						DefaultSecurityManager(实现类):	 
    实现Realm接口实现关系:
    Realm(接口)
    	CachingReaml(抽象类):只是添加了cacheManager属性并没有实现Realm接口方法
    		AuthenticatingRealm(抽象类):实现了Realm接口getAuthenticationInfo(AuthenticationToken token)方法并定义为final类型,也就是说从该层开始以下的类不能在重写该方法只能重写新引入doGetAuthenticationInfo(token)抽象方法获取AuthenticationInfo对象;引入CredentialsMatcher接口对象,通过调用该对象的doCredentialsMatch(token, info)方法实现验证;(回调函数) 注意:/**getAuthenticationInfo方法定义为final,不能被重写**/  啰嗦这么多总结一句话:就是AuthenticatingRealm类已经对getAuthenticationInfo(AuthenticationToken token)方法定制好了业务逻辑,只需要实现里面的细节
    			AuthorizingRealm(抽象类):doGetAuthenticationInfo(token)实现该方法,实现自己的业务逻辑
    
    实现CredentialsMatcher接口实现关系:
    CredentialsMatcher:
    	AllowAllCredentialsMatcher(实现类):doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) return true; 所有都通过验证
    	PasswordMatcher(实现类):该类有passwordService对象,通过passwordService.passwordsMatch(submittedPassword, formatted)实现加密密码的验证;
    	SimpleCredentialsMatcher(实现类):简单的身份验证
    	
    
    3.=======关联的一些重要接口==========
    PasswordService(接口):
    	主要方法:
    	//顾名思义对密码加密
    	String encryptPassword(Object plaintextPassword) throws IllegalArgumentException;
    	//加密密码的验证
    	boolean passwordsMatch(Object submittedPlaintext, String encrypted);
    	
    	实现关系:
    	HashingPasswordService(接口):实现PasswordService
    		DefaultPasswordService(实现类):默认:DEFAULT_HASH_ALGORITHM = "SHA-256"
    
    总结:
    实现自定义realm:
    1)实现Realm接口,实现简单的自定义realm  
    2)继承AuthorizingRealm(抽象类),实现doGetAuthenticationInfo(token)方法,可以给自定义的realm设置CredentialsMatcher接口对象,如果不设置默认为SimpleCredentialsMatcher;
          如果想对密码加密需要设置PasswordMatcher接口,该对象默认使用DefaultPasswordService(PasswordService接口对象);
         也可以自定义PasswordService接口对象并传入,这样就可以按照自己的需求去加密密码,以及验证密码;
         
         继承AuthorizingRealm(抽象类)可以实现从缓存中取AuthenticationInfo:
    	由源代码可以得知AuthenticatingRealm有以下属性:
      	//用于密码验证,登录的明文密码与加密后的密码是否匹配
      	private CredentialsMatcher credentialsMatcher;
      	//使用缓存技术从缓存中获取AuthenticationInfo
        private Cache<Object, AuthenticationInfo> authenticationCache;
        //是否使用缓存获取AuthenticationInfo
        private boolean authenticationCachingEnabled;
        //获取名称
        private String authenticationCacheName;
    
    	==========主要方法介绍============
    	public final AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            //从缓存中获取AuthenticationInfo
            AuthenticationInfo info = getCachedAuthenticationInfo(token);
            if (info == null) {
                //otherwise not cached, perform the lookup:
                info = doGetAuthenticationInfo(token);
                log.debug("Looked up AuthenticationInfo [{}] from doGetAuthenticationInfo", info);
                if (token != null && info != null) {
                    cacheAuthenticationInfoIfPossible(token, info);
                }
            } else {
                log.debug("Using cached authentication info [{}] to perform credentials matching.", info);
            }
            if (info != null) {
            //认证密码是否正确
                assertCredentialsMatch(token, info);
            } else {
                log.debug("No AuthenticationInfo found for submitted AuthenticationToken [{}].  Returning null.", token);
            }
            return info;
        }  
    
    	 
    	 
    	
    
    想的都是好
  • 相关阅读:
    一个故事讲清NIO
    select()/poll() 的内核实现
    一个滑块验证破解网站并带例子
    第7章 数据清洗和准备
    关系检验
    数据分析常用的方法总结
    python数据清洗
    描述性绘图
    pandas常用方法总结
    各种windows软件下载
  • 原文地址:https://www.cnblogs.com/freezone/p/8117687.html
Copyright © 2011-2022 走看看