/** 綁定Subject到當前線程. */ protected static void bindSubject(Subject subject) { clearSubject(); threadState = new SubjectThreadState(subject); threadState.bind(); }
/** 清除當前線程中的Subject. */ public static void clearSubject() { if (threadState != null) { threadState.clear(); threadState = null; } }
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // Check request type. // if (!(request instanceof HttpServletRequest)) { raiseSecurityError(response, "Unexpected request class detected."); return; } HttpServletRequest hsr = (HttpServletRequest) request; // Try to match URL against exclude pattern. // String requestUri = hsr.getRequestURI(); if (excludePattern != null && excludePattern.matcher(requestUri).matches()) { chain.doFilter(request, response); return; } // Extract security token from custom header. // String token = hsr.getHeader(SECURITY_TOKEN); logger.debug("Passed security token: " + token); // SecurityResource token must be present. // if (token == null) { logger.info("No token found in request header."); raiseSecurityError(response, "Null token detected"); return; } // Check if the passed token is associated with a valid session. // try { Session session = SecurityUtils.getSecurityManager().getSession(new DefaultSessionKey(token)); if (session == null) { logger.info("Unable to find a valid session using token."); raiseSecurityError(response, "Invalid session token."); return; } // Ensure that the last accessed timestamp gets updated. This should be made // internally by Shiro, but it looks like it is not working. Maybe the pattern // employed here to get the session is not canonical... // session.touch(); } catch (SessionException se) { logger.info(se.getMessage()); raiseSecurityError(response, "Invalid session token. Cause: " + se.getMessage()); return; } Subject requestSubject = new Subject.Builder().sessionId(token).buildSubject(); ThreadState threadState = new SubjectThreadState(requestSubject); threadState.bind(); try { chain.doFilter(request, response); } finally { threadState.clear(); } }