zoukankan      html  css  js  c++  java
  • 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");
                }
            }
        }
  • 相关阅读:
    在Oracle中计算两个日期间隔的天数、月数和年数
    洛谷P1182 数列分段 Section II(二分+贪心)
    BZOJ1734 [Usaco2005 feb]Aggressive cows 愤怒的牛(二分答案+贪心)
    分治算法
    洛谷P1031 [NOIP2002]均分纸牌
    洛谷P1803 凌乱的yyy / 线段覆盖
    洛谷P1094 [NOIP2007]纪念品分组
    洛谷P1223 排队接水
    洛谷P1208 [USACO1.3]混合牛奶 Mixing Milk
    洛谷P1181 数列分段Section1
  • 原文地址:https://www.cnblogs.com/zsxneil/p/6622042.html
Copyright © 2011-2022 走看看