Spring Security許可權框架理論與實戰(二)-常用許可權攔截器

1 SecurityContextPersistenceFilter
通過觀察Filter的名字,就能大概猜出來這個過濾器的作用,持久化SecurityContext例項
org.springframework.security.web.context.SecurityContextPersistenceFilter
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) { // 確保對於每個請求只應用一次過濾器 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()); } } // 將 request/response 物件交給HttpRequestResponseHolder維持 HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response); //通過SecurityContextRepository介面的實現類裝載SecurityContext例項 //HttpSessionSecurityContextRepository將產生SecurityContext例項的任務交給SecurityContextHolder.createEmptyContext() //SecurityContextHolder再根據策略模式的不同, //把任務再交給相應策略類完成SecurityContext的建立 //如果沒有配置策略名稱,則預設為 //ThreadLocalSecurityContextHolderStrategy, //該類直接通過new SecurityContextImpl()建立例項 SecurityContext contextBeforeChainExecution = repo.loadContext(holder); try { //將產生的SecurityContext再通過SecurityContextHolder-> //ThreadLocalSecurityContextHolderStrategy設定到ThreadLocal SecurityContextHolder.setContext(contextBeforeChainExecution); //繼續把請求流向下一個過濾器執行 chain.doFilter(holder.getRequest(), holder.getResponse()); } finally { //先從SecurityContextHolder獲取SecurityContext例項 SecurityContext contextAfterChainExecution = SecurityContextHolder .getContext(); //關鍵性地除去SecurityContextHolder內容 - 在任何事情之前執行此操作 //再把SecurityContext例項從SecurityContextHolder中清空 //若沒有清空,會受到伺服器的執行緒池機制的影響 SecurityContextHolder.clearContext(); //將SecurityContext例項持久化到session中 repo.saveContext(contextAfterChainExecution, holder.getRequest(), holder.getResponse()); request.removeAttribute(FILTER_APPLIED); if (debug) { logger.debug("SecurityContextHolder now cleared, as request processing completed"); } } }
通過原始碼中的註釋,應該可以看出來,這個Filter的作用主要是建立一個空的SecurityContext(如果session中沒有SecurityContext例項),然後持久化到session中。