Spring Security,远程用户和Tomcat日志

时间:2015-07-10 19:22:39

标签: tomcat spring-security

我们正在使用Spring Security来保护我们的Spring Web应用程序。实际上我们正在使用Spring Social身份验证过滤器。让它运作并不容易,但它现在有效,一切都很棒。

唯一缺少的是用户名未出现在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);
}

chain参数为null(不太可能)或requestFactory成员为null。

再看一下代码,看起来像requestFactory成员是通过调用afterPropertiesSet()创建的。什么时候才能打电话?这整个方法是否是正确的方法?

谁能告诉我这是怎样的正确方法?当然有一些正确的方法可以让用户名显示在Tomcat日志中吗?

由于

1 个答案:

答案 0 :(得分:2)

如果您正在谈论Tomcat的访问日志阀,这将无效,因为Tomcat不知道Spring Security,它完全在您的应用程序中运行。

SecurityContextHolderAwareRequestFilter通常默认启用,但其效果不适用于调用堆栈中位于过滤器链中的部分。从上面发布的doFilter方法中可以看出这一点。由requestFactory创建的包装请求仅在过滤器链中的该点下方可见。

最简单的选择是在Spring Security之后添加您自己的过滤器(例如在web.xml中),并将您想要的信息转储到日志中。或者,您可以使用它在MDC中为log4jlogback等日志记录包设置用户名,这样您就可以将其添加到日志记录模式中。有关示例,请参阅上面链接中的UserServletFilter