我正在使用带有嵌入式 tomcat + spring security 的 spring boot。 我从 tomcat 的访问日志看起来像这样
IP - - [14/2/2017:08:49:50 +0200]“GET /page/2 HTTP/1.1”200 2606
那么,我怎样才能使日志文件看起来像
IP - - [14/2/2017:08:49:50 +0200] 用户名 -“GET /page/2 HTTP/1.1”200 2606
每个请求都必须有发出的用户名。对于安全身份验证,我使用带有数据库用户名和密码信息的 Spring Security。
您可能需要将应用程序属性中的访问日志模式更改为如下所示:
server.tomcat.accesslog.pattern=%h %l %t %u "%r" %s %b
其中
%u
是已通过身份验证的远程用户(请参阅示例此处)。
UPD:这可能还不够,因为 common 模式已经包含
%u
参数。在这种情况下,我建议采取两个额外步骤:
request.getSession().setAttribute("username", user.getName());
在访问日志模式中添加以下参数:
%{username}s
server.tomcat.accesslog.pattern=%h %l %t %u %{用户名}s "%r" %s %b
应从
username
获取名为 HttpSession
的属性,如此处所述。
只是添加一个完整的示例来说明我如何做到这一点。由于现有的答案没有提供非常详细的解释如何实现这个目标。
在您的 Spring Web Security 配置中输入以下行。
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.csrf().disable()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.addFilterAfter(usernameAccessLogFilter(), BasicAuthenticationFilter.class)
.build();
}
@Bean
public UsernameAccessLogFilter usernameAccessLogFilter(){
return new UsernameAccessLogFilter();
}
然后创建自定义过滤器:
public class UsernameAccessLogFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = ((HttpServletRequest) servletRequest);
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null) {
request.getSession().setAttribute("user", authentication.getName());
}
filterChain.doFilter(servletRequest, servletResponse);
}
}
在您的属性文件(.yml 格式)中添加以下内容:
server:
tomcat:
accesslog:
enabled: true
directory: logs
pattern: "%t %a %A %r %s %u %{user}s %B %T %I"
basedir: .
这就是我为获得上述结果而必须做的一切。