我目前正在學習 Spring Security Fundamentals。我正在閱讀檔案和源代碼,因為我想盡可能多地了解幕后發生的事情的詳細資訊。除了一件事,一切都可以理解:
SecurityContextPersistenceFilter過濾器類是 Spring Security 的第一個過濾器根據這個頁面這個類的doFilter()方法的實作是這樣的:
private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
if (request.getAttribute("__spring_security_scpf_applied") != null) {
chain.doFilter(request, response);
} else {
request.setAttribute("__spring_security_scpf_applied", Boolean.TRUE);
if (this.forceEagerSessionCreation) {
HttpSession session = request.getSession();
if (this.logger.isDebugEnabled() && session.isNew()) {
this.logger.debug(LogMessage.format("Created session %s eagerly", session.getId()));
}
}
HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response);
SecurityContext contextBeforeChainExecution = this.repo.loadContext(holder);
boolean var10 = false;
try {
var10 = true;
SecurityContextHolder.setContext(contextBeforeChainExecution);
if (contextBeforeChainExecution.getAuthentication() == null) {
this.logger.debug("Set SecurityContextHolder to empty SecurityContext");
} else if (this.logger.isDebugEnabled()) {
this.logger.debug(LogMessage.format("Set SecurityContextHolder to %s", contextBeforeChainExecution));
}
chain.doFilter(holder.getRequest(), holder.getResponse());
var10 = false;
} finally {
if (var10) {
SecurityContext contextAfterChainExecution = SecurityContextHolder.getContext();
SecurityContextHolder.clearContext();
this.repo.saveContext(contextAfterChainExecution, holder.getRequest(), holder.getResponse());
request.removeAttribute("__spring_security_scpf_applied");
this.logger.debug("Cleared SecurityContextHolder to complete request");
}
}
SecurityContext contextAfterChainExecution = SecurityContextHolder.getContext();
SecurityContextHolder.clearContext();
this.repo.saveContext(contextAfterChainExecution, holder.getRequest(), holder.getResponse());
request.removeAttribute("__spring_security_scpf_applied");
this.logger.debug("Cleared SecurityContextHolder to complete request");
}
}
我的問題是:顯然,在過濾器鏈完成其作業后,SecurityContextHolder.clearContext()方法要么在 finally 塊中呼叫,要么在方法末尾呼叫。但是我知道,我仍然可以SecurityContextHolder.getContext()在我的控制器和服務層中訪問 SecurityContext 物件。如果上面的代碼清除了 SecurityContextHolder,怎么可能?我錯過了什么嗎?
uj5u.com熱心網友回復:
首先,您所指的檔案是 2016 年 12 月 21 日發布的 spring security 4.1.2 版本。 Spring security 目前在 5.6.1 上,過濾器串列在當前檔案中看起來有很大不同。
那么上面代碼中你的問題的答案是,因為這一行
this.repo.saveContext(contextAfterChainExecution, holder.getRequest(), holder.getResponse());
這SecurityContextHolder是一個單例,所以它SecurityContext被提取(這將創建一個副本)然后它被清除singleton并最后this.repo.save保存下一次的背景關系。
這是如何保存的,是不同的,默認情況下相信它使用 HttpSession (這意味著您將獲得一個會話 cookie),這是在 Spring 中的HttpSessionSecurityContextRepository中實作的,但是您可以設定一個單獨的資料庫以持久保存它,如果您'想要它,以便在重新啟動等后它仍然存在。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/429563.html
上一篇:如何擦除特定容器?
下一篇:初始化前無法訪問“用戶”
