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