为什么Windows 8在登录MS帐户后发送不同的授权标头

时间:2014-02-03 22:43:26

标签: windows fiddler kerberos ntlm waffle

我们拥有什么?

  1. 客户端:win8,ie11,使用域凭据登录系统。

  2. 服务器:3个tomcat7节点超出了apache 2.2.22。应用程序使用华夫饼库来验证以sso方式登录到域的Windows用户。

  3. 应用程序使用spring安全性,关于此主题的主要内容是处理通过表单登录的过滤器来自处理身份验证标头的过滤器。

  4. NegotiateSecurityFilterProvider仅支持Negotiate协议,而不支持NTLM
  5. 我们做什么?

    1. 通过直接链接进入申请:https://app.domain.com/app_name/subordinates.do。 没关系,我们正在承载有效的kerberos标题(fiddler描述为'授权标题(谈判)似乎包含kerberos票'^^的好的和大的kerberos标记)并且应用程序方面的华夫饼用kerberos回复传递给我们

    2. 注销。

    3. 在登录页面上通过表单登录:我们使用user_name和密码发出请求,我们再次使用相同的kerberos令牌。应用程序使用user_name和密码在waffle WindowsAuthenticationProvider的帮助下登录我们。这里我们在我们丰富NegotiateSecurityFilter之前获得身份验证,因此在服务器的回复中没有任何kerberos标头。无论如何一切都还可以。

    4. 现在我们通过操作系统登录MS帐户。魔术发生了。

      当尝试通过直接链接登录时,登录页面上的“指定的句柄无效”错误为SPRING_SECURITY_LAST_EXCEPTION常量。 我的猜测是我们发送了一些无效的授权标题

      当尝试通过表单登录时,我们得到'参数不正确'。 在这里我认为我们发送ntlm类型1 POST请求与空体但我们仍然有无效的标题,因此应用程序无法识别它并且没有发送401回复,此后华夫饼发送空名称到AD并且这里出现错误(只是猜测)

      但是当我打开小提琴手看看真正发生的事情时,一切都开始正常工作,因为在登录MS帐户之前。
      好的,要找出发送到服务器的标头,我在cmd文件中使用了一些代码:

      UDPATED 添加代码和输出

          var cookieContainer = new CookieContainer();
          var authRequest = (HttpWebRequest) WebRequest.Create("https://app.domain.com/app_name/home.do");
          var credentials = CredentialCache.DefaultNetworkCredentials;
          authRequest.Credentials = credentials;
          authRequest.CookieContainer = cookieContainer;
          authRequest.AllowAutoRedirect = false;
          var authResponse = (HttpWebResponse)authRequest.GetResponse();
          Console.WriteLine("Request headers:");
          foreach (string header in authRequest.Headers.AllKeys) {
              Console.WriteLine("\t{0}: {1}", header, authRequest.Headers.Get(header));
          }
          Console.WriteLine("\nResponse: {0} {1}", (int)authResponse.StatusCode, authResponse.StatusDescription);
          Console.WriteLine("Response headers:");
          foreach (string header in authResponse.Headers)
          Console.WriteLine("\t{0}: {1}", header, authResponse.GetResponseHeader(header));
          foreach (var cookie in cookieContainer.GetCookies(new Uri("https://app.domain.com/app_name/")))
          Console.WriteLine("Received cookie: {0}", cookie);
          Console.WriteLine("\nPress ENTER to exit");
          Console.ReadLine();
      

      我得到的是:

          Request headers:
              Authorization: Negotiate oTMwMaADCgEBoioEKE5UTE1TU1AAAQAAAJeCCOIAAAAAAAAAAAAAAAAAAAAABgOAJQAAAA8=
              Host: {host}
              Cookie: JSESSIONID={sessionId}
          Response: 302 Found
          Response headers:
              Vary: Accept-Encoding
              Content-Length: 0
              Content-Type: text/ plain; charset=UTF-8
              Date: Tue, 04 Feb 2014 11:44:15 GMT
              Location: https://app.domain.com/app_name/login.do?error_code=1
              Server: Apache/2.2.22 (Win32) mod_ssl/2.2.22 OpenSSL/0.9.8t mod_jk/1.2.37
          Received cookie: JSESSIONID={sessionId}
      

      它肯定比kerberos小得多,这是fiddler在认证工作时看到的。

      所以问题是:
      1.为什么登录MS帐户会影响向服务器发送的标头? 2.为什么它在小提琴手上开始工作?
      3.这个标题是什么类型:协商oTMwMaADCgEBoioEKE5UTE1TU1AAAAAAAJeCCOIAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAA8 =以及如何处理服务器?

      更新2014年3月17日: wireshark capture在tgs请求后显示KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN错误,服务器提到 - 带有apache的机器名。 在与支持团队调查后,我们发现用于在不同节点上运行tomcat服务器的特殊用户没有spn用于带有apache的机器的域名(它具有资源域名的spn但不适用于当前机器)。加入spn后,问题消失了。

1 个答案:

答案 0 :(得分:1)

解码oTMwMaADCgEBoioEKE5UTE1TU1AAAQAAAJeCCOIAAAAAAAAAAAAAAAAAAAAABAOAAQAAAAA =我们可以看到它包含NTLMSSP(新版本)。

检查浏览器配置: 在Internet Explorer中:网页应位于“本地Intranet”区域(在自动记录用户的区域中),并且IWA,已启用集成Windows身份验证。

如果情况并非如此,请查看Wireshark中的dns和kerberos数据包。

检查DNS: IE使用dns将Web服务器地址解析为主体名称。 CNAME地址被解析为A地址。如果没有找到,IE将根本不会要求Kerberos服务票证(并将退回到NTLM)。

检查SPN: 当Active Directory找不到请求的主体(或者那里或两个或更多)时。然后IE回到NTLM。