Spring Security、远程用户和 Tomcat 日志 [英] Spring Security, remote user, and Tomcat logs

查看:34
本文介绍了Spring Security、远程用户和 Tomcat 日志的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

We're using Spring Security to secure our Spring web application. In fact we're using a Spring Social authentication filter. It was not easy to get it working, but it works now and everything is great.

唯一缺少的是用户名没有出现在 Tomcat 日志中.在 Tomcat 中,如果我使用良好的老式 BASIC 身份验证,登录的用户会很好地出现在日志中.这是非常有帮助的.我想知道哪个授权用户正在做某些事情,例如分析等.

The only thing missing is that the user name doesn't appear in the Tomcat logs. In Tomcat, if I use good old fashioned BASIC authentication, the logged in user appears nicely in the logs. That is very helpful. I want to know which authorized user is doing certain things, for analytics etc.

我知道 Tomcat 基于 httpServletRequest.getRemoteUser() 记录用户.Spring 将用户信息存储为 SecurityContextHolder.getSecurityContext().getPrincipal().

I know that Tomcat logs the user based on httpServletRequest.getRemoteUser(). Spring stores user info as SecurityContextHolder.getSecurityContext().getPrincipal().

我查看了 Spring 文档,看起来我需要将 SecurityContextHolderAwareRequestFilter 添加到链中,它将包装 HttpServletRequest 并提供有用的 getSecurityContext() 和其他方法的实现.

I looked around at the Spring documentation and it looks like I need to add the SecurityContextHolderAwareRequestFilter to the chain, which will wrap the HttpServletRequest and provide useful implementations of getSecurityContext() and other methods.

我尝试将其添加到我的 Java SecurityConfiguration 类中,如下所示:

I tried to add that to my Java SecurityConfiguration class, like this:

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

但是当我这样做时,我得到了一个例外:

but when I do that, I get an exception:

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 的那一行,它是:

I can see clearly what is going on. At that line in SecurityContextHolderAwareRequestFilter, it is:

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.

Either the chain parameter is null (not likely) or the requestFactory member is null.

再看代码,看起来 requestFactory 成员是通过调用 afterPropertiesSet() 创建的.何时是拨打该电话的正确地点?这整个方法甚至是正确的方法吗?

Looking at the code some more, it looks like the requestFactory member is created by calling afterPropertiesSet(). When is the right spot for making that call? Is this whole approach even the right approach?

谁能告诉我这样做的正确方法是什么?肯定有一些正确的方法可以让用户名显示在 Tomcat 日志中吗?

Can anyone tell me what's the right way to do this? Surely there's some correct way to get the user name to show up in Tomcat logs?

谢谢

推荐答案

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

If you're talking about Tomcat's access log valve, this won't work, since Tomcat is unaware of Spring Security, which operates entirely within your application.

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

SecurityContextHolderAwareRequestFilter is usually enabled by default, but its effects don't apply to parts of the call stack above where it lies in the filter chain. This should be obvious from the doFilter method you've posted above. The wrapped request created by requestFactory is only visible below that point in the filter chain.

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

The easiest option would be to just add your own filter (e.g. in web.xml) after Spring Security, and dump the information you want to a log. Or you can use it to set the username in the MDC for a logging package such as log4j or logback, which will allow you you to add it to your logging pattern. See the UserServletFilter in the above link for an example.

这篇关于Spring Security、远程用户和 Tomcat 日志的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆