request.getUserPrincipal() 在 RequestListener 中为 null,尽管身份验证成



我们在更高和最新的Tomcat版本中遇到了问题,这使我们无法升级到7.0.22之后的版本。

我们将 FormBasedAuthentication 与自定义领域一起使用。

这是在Windows上的Tomcat 7.0.57和JDK 7u76上测试的。

我的设置有一个调用j_security servlet的登录表单。调用自定义领域并且身份验证成功时,将返回自定义主体。

然后,Tomcat 将转发到受保护的资源,我们在 RequestListener 中捕获请求。

问题是,request.getUserPrincipal() 返回 null。调试器显示,request.getSession(false)(包含 StandardSession 的 SessionWrapper 实例)返回的会话包装器有一个字段"principal",其中包含从我的领域返回的主体。

我已经看到了关于在 bugzilla 中对非受保护的请求返回用户主体的要求的讨论,但这里的请求需要受保护的资源。

任何关于为什么会发生这种情况的想法都会非常有帮助。实际上,我认为这是一个错误,请求未经身份验证但仍得到服务。

完全相同的设置就像 Tomcat 7.0.12 上的魅力,我认为最高可达 7.0.22。

此致敬意

托马斯

下面是请求侦听器的代码:

@Override
public void requestInitialized(ServletRequestEvent event) {
    if( log.isTraceEnabled() ) {
        log.trace( ">> requestInitialized" );
    }
    HttpServletRequest request = (HttpServletRequest)event.getServletRequest();
    PortalRequest.current.set( request );
    HttpSession httpSession = null;
    GenericPrincipal genericPrincipal = (GenericPrincipal)request.getUserPrincipal();
// genericPrincipal is null, requestURI is pointing to a protected resource.

这是 Web 中的表单身份验证配置.xml

<welcome-file-list>
<welcome-file>jsp/main.jsp</welcome-file>
</welcome-file-list>
<security-constraint>
<display-name>PDiX Portal</display-name>
<web-resource-collection>
  <web-resource-name>PDX Portal Protected</web-resource-name>
  <url-pattern>/jsp/*</url-pattern>
</web-resource-collection>
<web-resource-collection>
  <web-resource-name>servlets</web-resource-name>
  <url-pattern>/servlet/*</url-pattern>
</web-resource-collection>
<web-resource-collection>
  <web-resource-name>GWT Resourcen</web-resource-name>
  <url-pattern>/StandardPortal/*</url-pattern>
</web-resource-collection>
<web-resource-collection>
  <web-resource-name>services</web-resource-name>
  <url-pattern>/delegating/*</url-pattern>
</web-resource-collection>
<web-resource-collection>
  <web-resource-name>ViewerServlet</web-resource-name>
  <url-pattern>/frameset</url-pattern>
  <url-pattern>/run</url-pattern>
</web-resource-collection>
<web-resource-collection>
  <web-resource-name>EngineServlet</web-resource-name>
  <url-pattern>/preview</url-pattern>
  <url-pattern>/download</url-pattern>
  <url-pattern>/parameter</url-pattern>
  <url-pattern>/document</url-pattern>
  <url-pattern>/output</url-pattern>
  <url-pattern>/extract</url-pattern>
</web-resource-collection>
<auth-constraint>
  <role-name>authenticatedUser</role-name>
</auth-constraint>

形式 PDXRealm /jsp/login.jsp /logout.jsp?error=true 经过身份验证的用户

[更新了问题以反映与请求侦听器的连接]

这个问题在雄猫用户列表中的康斯坦丁·科林科的帮助下得到解决。

从 Tomcat 7.0.22 开始,身份验证在触发 servlet 请求侦听器之后进行。这会产生副作用,即请求侦听器不能再用于在会话中设置应用程序身份验证。

引用康斯坦丁的话:

更改

日志文件中对 7.0.22 进行了以下更改:

[quote] 使用修复破坏自定义的 51653 更正回归 来自身份验证器的 4xx 响应的错误页面。错误处理 和请求侦听器现在在标准主机阀中处理 确保它们包装所有上下文级别活动。(市场)[/引用]

所以,我的解决方案是找到另一种方法来设置我的东西,这很可能是一个过滤器。

我已经浏览了 Servlet 3.0 规范,以找到有关调用 requestInitialized() 的请求状态的任何提示,但没有给出特定的要求(或者我没有找到它们)。

希望其他人也会发现这有帮助。

最新更新