Java Can';t在使用带Spring安全用户名和密码AuthFilter的MultiReadHttpServletRequest时登录

Java Can';t在使用带Spring安全用户名和密码AuthFilter的MultiReadHttpServletRequest时登录,java,spring,spring-security,aop,aspectj,Java,Spring,Spring Security,Aop,Aspectj,我正在尝试构建一个简单的日志工具,使用AspectJ可以打印HttpServletRequest主体 为此,我创建了一个简单的切入点,用于捕获javax Filter.doFilter、HttpServlet doPost、doGet、service等的所有执行 然后,我用我自己的请求包装器替换HttpServletRequest,该包装器复制请求的主体,以便可以多次调用它,这样我就能够记录它。 见- 到目前为止,它工作得很好,直到我尝试将主体记录到使用Spring安全过滤器的应用程序中。现在我

我正在尝试构建一个简单的日志工具,使用AspectJ可以打印HttpServletRequest主体

为此,我创建了一个简单的切入点,用于捕获javax Filter.doFilter、HttpServlet doPost、doGet、service等的所有执行

然后,我用我自己的请求包装器替换HttpServletRequest,该包装器复制请求的主体,以便可以多次调用它,这样我就能够记录它。 见-

到目前为止,它工作得很好,直到我尝试将主体记录到使用Spring安全过滤器的应用程序中。现在我无法登录,似乎HttpServletRequstWrapper的实现对Spring很重要,但我不知道在哪里以及为什么

我的代码(与原始代码相比有点修改,但它给出了想法):

你知道为什么我不能登录,而这无法与Spring security一起工作吗? 我看到他们正在使用自己的包装器,但是由于API是相同的,所以应该可以工作

澄清一下——我正在tomcat上运行一个应用程序,而没有检测org.apache.catalina(它不工作,可能是因为类加载顺序阻止了aspectj编织tomcat源代码)

编辑:

我现在明白了问题出在UsernamePasswordAuthenticationFilter.java中:

 protected String obtainUsername(HttpServletRequest request) {
    return request.getParameter(usernameParameter);
}
如果我使用我的包装器,上面的函数将返回null,否则它将返回“guest”,这是我使用的用户名。我确实覆盖了inputstream和读取器,但是对getParameter(…)的实际调用是通过底层请求完成的,该请求使用来自org.apache.catalina.connector.RequestFacade的原始输入流

谢谢


Lin

我无法登录,因为spring security调用了tomcat的org.apache.coyote.Request来读取参数。请求不使用InputStream,而是使用BufferInput。不管怎样,它都不使用我的包装InputStream

有两种解决方案:

  • request.getParametersMap()-如果是post调用(例如登录,例如spring security j_spring_security_check),您可以使用request.getParametersMap()并从中生成请求正文
  • 使用java反射将org.apach.coyote.Request的inputBuffer替换为您自己的实现,该实现允许从流中多次读取

我选择了第一个选项,因为后者风险太大。

发布特性的完整代码。在这个缩短的版本中,如果
firstTimeTracking
条件为
true
@NándorElődFekete,您似乎只调用
procedue(…)
,我更新了代码。感谢您的帮助。该代码适用于除spring security之外的所有情况,spring security某种程度上依赖于HttpServletRequestWrapper的类型(?)。
 protected String obtainUsername(HttpServletRequest request) {
    return request.getParameter(usernameParameter);
}