spring security中使用ThreadLocal保存S

2018-11-29  本文已影响0人  Ray昱成

在spring security中,类SecurityContextHolder提供了一系列的静态方法。使用了策略设计模式,默认使用的策略是ThreadLocalSecurityContextHolderStrategy,这其中便是使用ThreadLocal进行存储的。

大概流程:
浏览器请求经过spring security的SecurityContextPersistenceFilter处理,会从SecurityContextRepository中获取SecurityContext,然后将其设置到SecurityContextHolder中,之后会转到下一个过滤器。在请求结束之后,清空SecurityContextHolder,并将请求后的SecurityContext在保存到SecurityContextRepository中。贴上源码:

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;
    
        //省略若干语句...

    HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request,
            response);
    //从session中根据key取出SecurityContext,如果没有会创建一个新的
    SecurityContext contextBeforeChainExecution = repo.loadContext(holder);

    try {
            //设置到ThreadLoacal中
        SecurityContextHolder.setContext(contextBeforeChainExecution);

        chain.doFilter(holder.getRequest(), holder.getResponse());

    }
    finally {
        SecurityContext contextAfterChainExecution = SecurityContextHolder
                .getContext();
        // Crucial removal of SecurityContextHolder contents - do this before anything(清除ThreadLoacal数据)
        // 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");
        }
    }
}

参考链接:
https://juejin.im/post/5a6aef4f6fb9a01cbb3957b7
http://dead-knight.iteye.com/blog/1513086

上一篇下一篇

猜你喜欢

热点阅读