0

我被困在 Java Web 应用程序的 servlet 和安全过滤器上。所以我得到了我的 web.xml,它看起来像这样:

<!-- <distributable/> -->

<filter>
<filter-name>com.company.xxx.xxx.xxx.SecurityFilter</filter-name>
<filter-class>com.company.xxx.xxx.xxx.SecurityFilter</filter-class>
</filter>

<filter>
<filter-name>WaffleSSOFilter</filter-name>
<filter-class>waffle.servlet.NegotiateSecurityFilter</filter-class>
<init-param>
  <param-name>securityFilterProviders</param-name>
  <param-value>
      waffle.servlet.spi.NegotiateSecurityFilterProvider
  </param-value>
 </init-param>
 <init-param>
  <param-name>allowGuestLogin</param-name>
  <param-value>false</param-value>
 </init-param>
 <init-param>
  <param-name>waffle.servlet.spi.NegotiateSecurityFilterProvider/protocols</param-name>
  <param-value>
      Negotiate
  </param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>com.company.xxx.xxx.xxx.SecurityFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
<filter-name>WaffleSSOFilter</filter-name>
<url-pattern>/xxx/xxx/xxx/windowsLogin</url-pattern>
</filter-mapping>

<!-- Enabling it disables access to App from other computers -->
<context-param>
<param-name>org.jboss.weld.development</param-name>
<param-value>false</param-value>
</context-param>

<servlet-mapping>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<url-pattern>/xxx/*</url-pattern>
</servlet-mapping>

</web-app>

我得到了这个设置,因为我偶然发现了这个小帖子: Multiple filters with same url mapping

然后我发现这篇文章帮助我找到了正确的方向:java-sso-with-wildfly-8-java-1-8-0-45-and-active-directory

所以我尝试通过过滤器 WaffleSSOFilter 访问这部分。

public String getUserName( HttpServletRequest servletRequest )
  {
    Enumeration<String> headerNames = servletRequest.getHeaderNames();
    while ( headerNames.hasMoreElements() )
    {
      String headerName = headerNames.nextElement();
      String headerValue = servletRequest.getHeader( headerName );
      log.info( "Header Name:" + headerName + " " + headerValue );
    }
    String remotePrincipal = servletRequest.getRemoteUser();
    log.info( "REMOTE USER: " + remotePrincipal );
    log.info( "PRINCIPAL: " + servletRequest.getUserPrincipal().toString() );
    return remotePrincipal;
  }

对我来说,困难的部分是每个 URL 都需要第一个过滤器“com.company.xxx.xxx.xxx.SecurityFilter”,因为没有它我们的应用程序就坏了,然后什么都不起作用。但我需要为我的 WaffleSSOFilter 提供一个特殊的 POST URL,以便能够通过访问网站的远程计算机上登录的 Windows 用户进行身份验证。

目标是让登录页面具有正常的用户名和密码表单,并有一个复选框来启用 Windows 身份验证。

通过此设置,我可以使用用户名和密码正常登录。该应用程序正在运行,到目前为止还不错。现在,如果我向我的特殊 URL 发出 POST 请求以测试 Windows 身份验证,我会在访问之前的源代码时得到 java.lang.NullPointerExceptionservletRequest.getUserPrincipal().toString()

问题:我在过滤器设置中的错误在哪里或源代码有什么问题?

PS:是的,我将浏览器配置为启用第二篇文章链接中提到的请求。PPS:当我删除我们的第一个过滤器并通过华夫饼过滤器路由所有内容时,登录工作并且我没有收到 NullPointerException,但应用程序完全损坏了。

4

1 回答 1

0

好吧,所以我一直在挖掘,睡了一夜之后,我想尝试一些新的东西。

因为我遇到了已经有一个自定义 securityFilter 来阻止 waffle 正确执行的问题(即使过滤器与调度程序一起跳转等)。我的眼睛捕捉到了一些有趣的东西。

Waffle 设置了一个名为“WWW-Authenticate”的 Header,那么为什么不朝那个方向尝试呢。几个小时后,我开始工作了。我正在执行我自己的 NTLM 握手并从令牌中读出我需要的内容。 get username from NTLM auth header帮助我理解了如何执行我自己的 NTLM 握手。基本上,我在这个 masterpeace NTLM Authentication Scheme for HTTP的帮助下定制了在那里找到的源代码。现在,在看到令牌和包是如何构建的之后,我深入研究并强制我的服务器请求此身份验证,然后在获得 NTLM V3 令牌后,读出我需要登录用户的内容。

有了这个解决方案,我可以保持我的结构。只有一个过滤器,没有 Wildfly 自定义,只有纯 Web 应用程序逻辑才能使其正常工作。

重要的是,我仍然需要将浏览器配置为信任我浏览的网站,因此我不会收到要求提供凭据的弹出窗口。这可以在这里找到Waffle Doc,但我必须network.negotiate-auth.trusted-uris为 firefox 添加,然后添加域(例如:http://localhost)以使弹出窗口消失。

只是想如果有人对这种环境有类似的问题,我会分享这个。

于 2016-10-07T11:50:22.397 回答