2015-07-10 46 views
0

我們使用Spring Security來保護我們的Spring Web應用程序。事實上,我們正在使用Spring社交認證過濾器。要實現它並不容易,但它現在可行,一切都很好。Spring安全,遠程用戶和Tomcat日誌

唯一缺少的是用戶名不會出現在Tomcat日誌中。在Tomcat中,如果我使用良好的老式BASIC身份驗證,登錄的用戶會很好地出現在日誌中。這非常有幫助。我想知道哪個授權用戶正在做某些事情,用於分析等。

我知道Tomcat根據httpServletRequest.getRemoteUser()記錄用戶。 Spring將用戶信息存儲爲SecurityContextHolder.getSecurityContext()。getPrincipal()。

我環顧了Spring文檔,它看起來像我需要將SecurityContextHolderAwareRequestFilter添加到鏈,它將包裝HttpServletRequest並提供getSecurityContext()和其他方法的有用實現。

我試圖將它添加到我的Java SecurityConfiguration類,像這樣:

@Override 
    protected void configure(HttpSecurity httpSecurity) throws Exception { 
     httpSecurity 
       .addFilter(new SecurityContextHolderAwareRequestFilter()) 

,但是當我這樣做,我得到一個異常:

java.lang.NullPointerException 
    org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45) 

我可以清楚地看到是怎麼回事上。在該SecurityContextHolderAwareRequestFilter線,它是:

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) 
     throws IOException, ServletException { 
chain.doFilter(requestFactory.create((HttpServletRequest)req, (HttpServletResponse) res), res); 
} 

要麼鏈參數爲空(不可能)或requestFactory構件爲空。

再看一下代碼,看起來像requestFactory成員是通過調用afterPropertiesSet()來創建的。什麼時候打電話是正確的?這整個方法甚至是正確的方法嗎?

誰能告訴我什麼是正確的方法來做到這一點?當然,有一些正確的方法可以讓用戶名顯示在Tomcat日誌中?

感謝

回答

2

如果你談論的是Tomcat的訪問日誌閥,這是不行的,因爲Tomcat是不知道的Spring Security,你的應用程序中運行完全的。

SecurityContextHolderAwareRequestFilter默認情況下處於啓用狀態,但其效果不適用於上方位於過濾器鏈中的部分調用堆棧。這應該從您上面發佈的doFilter方法中明顯看出。由requestFactory創建的包裝請求僅在過濾器鏈中的該點之下可見。

最簡單的選擇是在Spring Security之後添加自己的過濾器(例如在web.xml),然後將想要的信息轉儲到日誌中。或者,您可以使用它在MDC中爲日誌包設置用戶名,例如log4jlogback,這將允許您將其添加到日誌記錄模式。以上鍊接中的UserServletFilter爲例。