• SpringSecurity-SecurityContextPersistenceFilter的作用


      SecurityContextPersistenceFilter每个request只执行一次,以解决servlet容器的兼容性问题(特别是WebLogic)。

      它在request执行之前从SecurityContextRepository(一般是HTTPSession)获取信息,产生一个SecurityContextHolder,然后在request结束的时候把信息再复制回(stores it back in)SecurityContextRepository,并销毁SecurityContextHolder。这个Filter应该在任何进行authentication认证之前执行,因为authentication认证需要SecurityContextHolder有一个完整可用的SecurityContext。

      这个Filter存在的原因是显而易见的。request是单独的线程,而安全认证是基于session的,所以每次请求都要讲认证信息从HttpSession中取出,认证完毕后将认证信息再复制回HttpSession(因为request时认证信息可能会发生改变),以备下一个request使用。

    核心代码如下:

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
                throws IOException, ServletException {
            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) res;
    
            if (request.getAttribute(FILTER_APPLIED) != null) {
                // ensure that filter is only applied once per request
                chain.doFilter(request, response);
                return;
            }
    
            final boolean debug = logger.isDebugEnabled();
    
            request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
    
            if (forceEagerSessionCreation) {
                HttpSession session = request.getSession();
    
                if (debug && session.isNew()) {
                    logger.debug("Eagerly created session: " + session.getId());
                }
            }
    
            HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request,
                    response);
            SecurityContext contextBeforeChainExecution = repo.loadContext(holder);
    
            try {
                SecurityContextHolder.setContext(contextBeforeChainExecution);
    
                chain.doFilter(holder.getRequest(), holder.getResponse());
    
            }
            finally {
                SecurityContext contextAfterChainExecution = SecurityContextHolder
                        .getContext();
                // Crucial removal of SecurityContextHolder contents - do this before anything
                // else.
                SecurityContextHolder.clearContext();
                repo.saveContext(contextAfterChainExecution, holder.getRequest(),
                        holder.getResponse());
                request.removeAttribute(FILTER_APPLIED);
    
                if (debug) {
                    logger.debug("SecurityContextHolder now cleared, as request processing completed");
                }
            }
        }
  • 相关阅读:
    PHP用*号替代姓名除第一个字之外的字符
    苹果笔记本下载的应用打不开或提示损坏怎么办
    codeigniter教程:Codeigniter出现Unable to connect to your databas
    Python3.6.0安装
    某游戏应用的redis 数据库结构设计(转)
    True(False) Positives (Negatives), 召回率和精度定义
    儿童书库
    年轻人必须知道的71个做饭技巧
    20种泡菜做法[3到5天就可以吃了]
    读懂此文——股市就是你的取款机
  • 原文地址:https://www.cnblogs.com/zsxneil/p/6622042.html
Copyright © 2020-2023  润新知