【问题标题】:Dynamics NAV Web Service Call with C# succeeds after 401 errors401 错误后使用 C# 调用 Dynamics NAV Web 服务成功
【发布时间】:2021-03-19 21:37:55
【问题描述】:

我遇到了一些奇怪的行为(这意味着我不明白发生了什么),如果可能的话,我需要一些帮助来解决它。

我们有一些 Dynamics 365 NAV Business Central Web 服务公开了一个带有 SSL 证书的安全,我们正在使用一些标准 C# 代码访问它。

我们已将 SOAP 代理添加到 ASP .NET Webforms 应用程序,这一切都按预期工作。

然后我们声明一个 Web 服务的实例,使用新的 NetworkCredential 实例设置凭据,并将 Web 服务设置为使用 PreAuthenticate,然后在我们的服务上调用该方法。

public static bool CheckServiceStatus()
{
    bool returnValue = false;
    try
    {
        svcWebServiceServer webService = new svcWebServiceServer();
        webService.Credentials = new NetworkCredential(Globals.WebServiceUsername, Globals.WebServicePassword, Globals.WebServiceDomain);
        webService.PreAuthenticate = true;
        webService.FncServiceStatus(ref returnValue);
    }
    catch (Exception ex)
    {
        LoggingFunctions.WriteMessageToDisk("CheckServiceStatus error : " + ex.Message);
    }
    return returnValue;
}

当我们在 Fiddler 中查看日志时,我们发现该服务被调用了两次。第一次调用时,我们收到一个 401 错误响应,告诉我们必须使用 NTLM,然后使用更长的 NTLM 密钥进行第二次调用,调用成功,我们得到了我们的数据...

第一次尝试...

第二次尝试...

谁能告诉我如何进行网络服务调用,以便第一次进行身份验证? 401 被认为是 DDOS 式攻击,然后流量被阻止。

我已尝试更改凭据的传递方式,但这没有任何区别...

public static bool CheckServiceStatus()
{
    bool returnValue = false;
    try
    {
        svcWebServiceServer webService = new svcWebServiceServer();
        CredentialCache credCache = new CredentialCache();
        credCache.Add(new Uri(webService.Url), "NTLM", new NetworkCredential(Globals.WebServiceUsername, Globals.WebServicePassword, Globals.WebServiceDomain));
        webService.Credentials = credCache;
        webService.PreAuthenticate = true;
        webService.FncServiceStatus(ref returnValue);
    }
    catch (Exception ex)
    {
        LoggingFunctions.WriteMessageToDisk("CheckServiceStatus error : " + ex.Message);
    }
    return returnValue;
}

【问题讨论】:

  • 当您新建服务时,它会拨打电话吗?第一次调用中的 Content-Length 为 0。您可以新建它并在一行中传递凭据吗?
  • 感谢 Wazz,不幸的是这不起作用。使用 PreAuthenticate 时,第一次失败 2 次,然后成功。第一次失败具有正确的内容长度,并返回 401 表示需要 NTLM,第二次尝试(内容长度为 0)使用 NTLM 值,它也返回 401,最后在第三次尝试时,它通过。
  • 我想我知道为什么现在会发生这种情况,并会尽快发布答案。

标签: asp.net web-services webforms dynamics-business-central


【解决方案1】:

根据这篇文章 - https://docs.microsoft.com/en-gb/archive/blogs/chiranth/ntlm-want-to-know-how-it-works - NTLM 以质询响应方式工作。

第一次调用 Web 服务时(即使您在 credentialCache 对象中指定 NTLM),似乎第一个请求是匿名发送的。

然后服务器以 401 响应,一些 WWW-Authenticate 标头指定该服务需要通过 NTLM 进行身份验证详细信息。这是第一个 401。

然后客户端(C# 应用程序)发送一个包含 NTLM 标头的新请求,该标头包含一个表示用户名、计算机名和域的编码值。

服务器将请求传递给生成质询的身份验证服务器,然后在另一个 401 响应中将其发送回客户端。这是第二个 401。

客户端收到质询后,会根据质询和密码计算哈希值,并将其发送回 Web 服务。身份验证服务器将此哈希与其自己的哈希进行比较,并且 - 只要凭据正确 - 通过身份验证,并返回 200 响应以及客户端最初进行的 Web 服务调用的结果。

当我们在代码中添加 PreAuthenticate = true 时,我们只需在前面传递 NTLM 用户名、计算机名和域,绕过第一步。这将 401 的数量从 2 个减少到 1 个。

我并不声称自己是身份验证领域的专家,但在阅读了上面链接的页面并进行了多次测试后,我们发现了这一点。如果有人想评论/纠正我,请随时。

为了完整起见,我们已开始研究 Dynamics 265 设置中的“用户名”身份验证方法以访问 Dynamics NAV 2018 Web 服务,该服务将此身份验证传递给 Dynamics NAV 365 的控件,这意味着我们不会收到 401。但是,我们现在无法在浏览器中访问 Web 服务,因为它使用 Digest,而且我们似乎无法通过浏览器进行身份验证,并出现 400 错误。

【讨论】:

    猜你喜欢
    • 2014-07-14
    • 2014-03-23
    • 2023-03-09
    • 1970-01-01
    • 2018-04-10
    • 2015-02-08
    • 1970-01-01
    • 2020-01-11
    • 1970-01-01
    相关资源
    最近更新 更多