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

时间:2015-01-26 09:12:37

标签: java tomcat form-authentication j-security-check

我们遇到了后期和最新Tomcat版本的问题,这些版本阻止我们升级到比7.0.22更晚的版本。

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

这是在Windows上使用Tomcat 7.0.57和JDK 7u76进行测试的。

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

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

问题是,request.getUserPrincipal()返回null。调试器公开,request.getSession(false)返回的sessionwrapper(包含StandardSession的SessionWrapper实例)有一个字段“principal”,它包含从我的领域返回的主体。

我已经看到有关在bugzilla中返回非受保护请求的userprincipal的要求的讨论,但这里的请求是要求受保护的资源。

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

完全相同的设置就像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                     authenticatedUser     

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

1 个答案:

答案 0 :(得分:1)

在tomcat用户列表上,Konstantin Kolinko帮助解决了这个问题。

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

引用康斯坦丁:

  

更改日志文件中的7.0.22有以下更改:

     

[quote]用破坏自定义的51653修正来纠正回归   来自Authenticators的4xx响应的错误页面。错误处理   现在,在StandardHostValve中处理请求侦听器   确保它们包装所有Context级别的活动。 (markt)[/ quote]

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

我已经浏览了Servlet 3.0规范,以便在调用requestInitialized()时查找请求状态的任何提示,但是没有给出具体要求(或者我没有找到它们)。

希望其他人也会觉得这很有帮助。