【问题标题】:Spring Security, remote user, and Tomcat logsSpring Security、远程用户和 Tomcat 日志
【发布时间】:2015-09-29 16:11:24
【问题描述】:

我们正在使用 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 日志中吗?

谢谢

【问题讨论】:

    标签: tomcat spring-security


    【解决方案1】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2020-03-02
      • 1970-01-01
      • 1970-01-01
      • 2020-02-26
      • 2016-08-08
      • 2014-06-29
      • 2021-07-13
      • 2019-11-20
      相关资源
      最近更新 更多