shiro重写filter的了解

shiro的了解 (2014-11-06 15:13:14)
标签: 股票 分类: java
shiro学习:
   大体功能是认证、授权、加密、会话管理
一、SecurityManager
   所有基于web的应用程序都是用 DefaultWebSecurityManager进行管理,它主要提供如下方面的功能

   Authentication(认证)
   1、web应用FormAuthenticationFilter拦截器
  
   在web应用中认证是通过FormAuthenticationFilter拦截器来实现的
   分析对应源代码:  
   整个拦截器的执行方法是在AdviceFilter.doFilterInternal进行封装
   它调用下面三个方法:
      boolean continueChain = preHandle(request, response); //是否继续执行后续拦截器链操作
      if (continueChain) {
           executeChain(request, response, chain);//继续执行拦截器后面的操作
            }
     postHandle(request, response);//拦截器执行完后的操作
    
    
     preHandle调用
     onPreHandle(request, response, pathConfig)
     {
     return isAccessAllowed(request, response, mappedValue) || onAccessDenied(request, response, mappedValue);
     }
    
     isAccessAllowed(request, response, mappedValue)//是否允许访问
     在AuthenticatingFilter.isAccessAllowed中进行了如下实现:
      Subject subject = getSubject(request, response);
      return  subject.isAuthenticated() || (!isLoginRequest(request, response) && isPermissive(mappedValue));
     //只要当前用户已经过认证就直接返回true,
    
    
     如果isAccessAllowed返回false,则系统执行onAccessDenied
     FormAuthenticationFilter.onAccessDenied实现对应的方法
     protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        if (isLoginRequest(request, response)) //判断请求是否是登录请求
           {
            if (isLoginSubmission(request, response)) //判断请求是否是post方法
              {
                if (log.isTraceEnabled()) {
                    log.trace("Login submission detected.  Attempting to execute login.");
                }
                return executeLogin(request, response);//执行登录验证
            } else //如果是get方法则会返回true,跳转到登陆页面
              {
                if (log.isTraceEnabled()) {
                    log.trace("Login page view.");
                }
                //allow them to see the login page ;)
                return true;
            }
        }
        //如果访问的是非登录页面,则跳转到登录页面
        else {
            if (log.isTraceEnabled()) {
                log.trace("Attempting to access a path which requires authentication.  Forwarding to the " +
                        "Authentication url [" + getLoginUrl() + "]");
            }
            saveRequestAndRedirectToLogin(request, response);
            return false;
        }
    }
   
   
    //executeLogin执行真正的登录操作
     protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
        AuthenticationToken token = createToken(request, response); //创建用户的身份、凭证
        if (token == null) {
            String msg = "createToken method implementation returned null. A valid non-null AuthenticationToken " +
                    "must be created in order to execute a login attempt.";
            throw new IllegalStateException(msg);
        }
        try {
            Subject subject = getSubject(request, response);
            subject.login(token); //执行shiro的登录操作
            return onLoginSuccess(token, subject, request, response);//登录成功
        } catch (AuthenticationException e) {
            return onLoginFailure(token, e, request, response);//登录失败
        }
    }

   在FormAuthenticationFilter中登录成功和登录失败的具体实现
   protected boolean onLoginSuccess(AuthenticationToken token, Subject subject,
                                     ServletRequest request, ServletResponse response) throws Exception {
        issueSuccessRedirect(request, response); //直接重定向到成功页面
        //we handled the success redirect directly, prevent the chain from continuing:
        return false; //不再执行过滤器链后面的操作
    }

    protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e,
                                     ServletRequest request, ServletResponse response) {
        setFailureAttribute(request, e); //登录失败,设置异常信息继续执行过滤器链后面的操作
        //login failed, let request continue back to the login page:
        return true;
    }

 

  
  SessionManager(session管理)
     DefaultWebSecurityManager-->sessionManager
     有下面几种具体的实现
     1、ServletContainerSessionManager(默认)
       ServletContainerSessionManager使用web容器提供的session进行管理,所以默认使用DefaultWebSecurityManager管理session和直接使用web容器的session
  是没有区别的
  ServletContainerSessionManager管理的session对象是org.apache.shiro.web.session.HttpServletSession,该对象代理封装了对javax.servlet.http.HttpSession的操作
     2、DefaultWebSessionManager
       该session管理器默认指定的sessionDAO = new MemorySessionDAO();
       它是基于当前内存来进行管理session,没有使用web容器的session;该中方式在集群环境时会出现问题,比如在同一session中访问不同的机器,则可能某些机器存在session值,有些不存在
       除非web server配置成ip_hosts
       可以通过该sessionManager来实现通过分布式缓存进行多台机器的session共享,可以采用如下配置
     
  
     
  
  
    
  
  
  
    
      
     
  
  

  
      
  
  
   CacheManage(缓存管理)
   Realm中使用缓存
  
   在Realm中有2个使用缓存的地方
   1、认证缓存
   首先判断getAuthenticationCache()是否为空,如果未设置则判断authenticationCachingEnabled=true&&cachingEnabled=true如果都为true
   则通过设置的cacheManager中取出name=authenticationCacheName的缓存
   也就是说要想使用认证缓存,则在Realm中有2种方式设置
   一种是通过设置cacheManager
      然后设置 authenticationCacheName(认证缓存名)authenticationCachingEnabled=true、cachingEnabled=true
   或者直接设置
   public void setAuthenticationCache(Cache authenticationCache)
    
   2、授权缓存
   首先判断getAuthorizationCache()如果未设置则判断authorizationCachingEnabled=true&&cachingEnabled=true如果都为true
   则通过设置的cacheManager中取出name=authorizationCacheName的缓存
   也就是说要想使用授权缓存,则在Realm中有2种方式设置
   一种是通过设置cacheManager
      然后设置 authorizationCacheName(授权缓存名)、authorizationCachingEnabled=true、cachingEnabled=true
   或者直接设置
   public void setAuthorizationCache(Cache authorizationCache)
  
  上面有很多变量值需要设置,Realm默认情况下
     authorizationCachingEnabled=true(是否可授权缓存)
     authenticationCachingEnabled=false(是否可认证缓存)
     cachingEnabled=true(是否可缓存)
  目前认证缓存功能使用不了,当缓存时序列化时对应的对象无法序列化;而且一般也不要使用认证缓存,避免修改密码无法及时生效
  授权缓存可以在session期间有效,session过期后重新取授权
 
  SessionManager中使用缓存
  在这里使用缓存的目的主要是管理系统session的缓存,比如系统如果想使用memcached来管理session就可以在这里配置

猜你喜欢

转载自endual.iteye.com/blog/2390089