java - 尽管身份验证成功,但 RequestListener 中的 request.getUserPrincipal() 为 null

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

我们在使用更高版本和最新版本的 Tomcat 时遇到问题,这会阻止我们升级到比 7.0.22 更高的版本。

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

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

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

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

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

我在 bugzilla 中看到过关于在非 protected 请求上返回 userprincipal 的要求的讨论,但这里的请求是在调用 protected 资源。

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

完全相同的设置在 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>

形式 PDX领域 /jsp/登录.jsp /logout.jsp?error=true 认证用户

[更新问题以反射(reflect)与请求监听器的连接]

最佳答案

问题在 tomcat 用户列表中的 Konstantin Kolinko 的帮助下得到解决。

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

引用康斯坦丁的话:

There is the following change for 7.0.22 in the changelog file:

[quote] Correct a regression with the fix for 51653 that broke custom error pages for 4xx responses from the Authenticators. Error handling and request listeners are now handled in the StandardHostValve to ensure they wrap all Context level activity. (markt) [/quote]

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

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

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

关于java - 尽管身份验证成功,但 RequestListener 中的 request.getUserPrincipal() 为 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28147261/

相关文章:

java - 如何在 Rythm 中编写 WHILE 循环

java - Tomcat 与 mysql : "Cannot create JDBC driver of class ' ' for connect URL 'null' "

c# - 生成的 MD5 散列的大小

c# - 使用 Windows 身份验证如何将所有初始请求重定向到特定页面

spring-security - Spring安全表单认证: How are sessions tracked?

java - 批量使用JDBC preparedStatement

java - 递归计算它有多少级别和 child 数量

java - 参数绑定(bind)的名称不能为空或空!对于命名参数,您需要在 Java 版本上使用 @Param 查询方法参数

java - 如何在tomcat服务器上启动和调用普通java项目的方法?

tomcat - Nutch 不会将内容索引到 solr,但不会记录任何类型的错误或警告