【问题标题】:Using default credentials to call api in console app使用默认凭据在控制台应用程序中调用 api
【发布时间】:2017-03-23 14:22:37
【问题描述】:

我正在尝试调用一个 Web API 2 方法,该方法需要从我有授权的桌面上运行的控制台应用程序进行身份验证,但我得到 401 Unathorized。我知道我有授权,因为当我从网络浏览器拨打相同的电话时,它工作正常。所以浏览器可以让我的默认登录 id/pw 发送到 API,但 .NET 的 WebClient 不能?这似乎很疯狂。必须有一种方法可以做到这一点,而无需在控制台应用程序中输入我的 id/pw。

以下是我在控制台应用程序中使用的,但它不起作用。

这是使用 Windows 身份验证,因为它是 Intranet 的东西。

这会引发异常“远程服务器返回错误:(401) 未授权。”

using(var c = new WebClient())
{
    c.UseDefaultCredentials = true;   
    string value = c.DownloadString("http://localhost:62659/api/Store/GetData");
}

我还尝试了以下方法,当我将鼠标悬停在 DefaultNetworkCredentials 上时,用户名/密码是空白字符串。为什么 .NET 不能解决这个问题?

using(var c = new WebClient())
            {
                var creds = new CredentialCache();
                var uri = new Uri("http://localhost:62659/api/Store/GetData");
                creds.Add(uri, "ntlm", System.Net.CredentialCache.DefaultNetworkCredentials);
                c.Credentials = creds;
                string value = c.DownloadString(uri);
            }

【问题讨论】:

  • 您是否收到异常或任何您可以分享的错误信息?
  • Fiddler2 将向您显示与 get 请求一起传递的凭据。
  • 我使用Postman 来解决这类问题。
  • 您能否在监控网络流量的同时查看您的凭据信息并在两个不同的调用之间进行比较?
  • 那么 cmets 是否告诉我这应该有效并且对其他人有效?

标签: c# .net asp.net-web-api2


【解决方案1】:

您的凭据信息很可能没有存储在Windows Credential Manager 中。您可以通过Control Panel > Credential Manager 访问它。从那里你可以添加你需要的任何凭证。 CredentialCache.DefaultCredentialsCredentialCache.DefaultNetworkCredentials 包含当前登录或模拟用户的登录凭据。如果您要连接的内容需要不同的凭据,那么这些将不起作用。您需要将这些凭据添加到 Windows 中的凭据管理器。

您在 Chrome 中连接良好的原因是 Chrome 会在其内部存储您指定要保存的凭据。

可以将用作功能 ID 的登录凭据设置为永不过期,或者需要将其添加到月度/年度维护项目列表中以更新这些帐户的密码。

您还想在应用程序中处理错误的登录信息。如果这是一项自动化任务,请发送电子邮件或以其他方式通知某人需要更新凭据。

如果用户运行此程序,您可以简单地提示当前用户提供新密码,然后您可以使用该密码更新存储的凭据。

另一个选项是将运行应用程序的用户设置为使用相同凭据的接收端用户。这样,整个过程都与将运行应用程序的用户绑定在一起。

【讨论】:

  • 这是一个大坏蛋。在应用程序从批处理服务器运行的公司设置中,管理员在更改批处理 id/pw 时不会想要维护它(我们在调度系统中进行作业时不知道这一点)。大无赖。
  • @user441521 - 在我看到您上面的评论后,我提到了一点。另一种方法是将其写入您的应用程序。如果凭据因登录信息错误而失败,您可以通过电子邮件发送或以其他方式通知某人需要更新凭据。
  • @user441521 - 我已经扩展了我的答案,希望能提供一些替代方案。
  • @user441521 - 这对您回答问题有帮助吗?
  • 这将从调度系统调用,因此管理员只维护 1 个用户。我认为无论如何都没有。我很可能只是创建一个控制台应用程序,它直接使用 Windows Auth 访问数据库,并让它执行与 API 相同的 sql 操作。
【解决方案2】:

使用 DefaultCredentials 应该可以在控制台应用程序中使用 Windows Auth。只要您有您的 web api 正在寻找的适当的授权标头。与我的评论相同,我建议使用 Postman 测试 api 调用,以便您可以排除故障并检查您缺少的内容。

将凭据视为空白,这可能是因为您使用的是 DefaultNetworkCredentials。

试试这个:

using(var c = new WebClient())
{
    var uri = new Uri("http://localhost:62659/api/Store/GetData");
    c.Credentials = System.Net.CredentialCache.DefaultCredentials;
    string value = c.DownloadString(uri);
}

如果你想使用 NetworkCredential,你应该像这样输入网络凭据:

c.Credentials = new NetworkCredential(username, password, domain);

我创建了这种类型的控制台应用程序并将其用作服务,我可以告诉您这应该可以工作。您应该只需要排除故障,然后一点一点地解决真正的问题。

【讨论】:

  • NetworkCredential 和 DefaultCredentials 有什么区别?我的意思是我的 ID,我认为是 DefaultCredentials,是网络上的 AD id。可悲的是,地方不允许我运行 Postman。尝试提琴手但没有看到流量出现,但我并没有那么多使用提琴手,所以可能是我。试。而您的 Web API 是 Web API 2,在控制器上带有 Authorize 标签并使用 Windows 身份验证?
  • Fiddler 在来自控制台应用程序时似乎没有显示此内容。
  • @user441521 - DefaultNetworkCredentials 属于 NetworkCredential 类型,这是实际使用的类。 DefaultCredentials 返回类型为ICredentials 的对象,但是DefaultCredentials 上的GetCredential() 函数返回NetworkCredential 类型的对象。无论您使用哪一个,您实际上都在使用实现了ICredentials 接口的NetworkCredential 实例。
  • 是的,我正在通过 Windows Auth 使用 Web API2。
  • 不是 100% 确定我在 fiddler 中寻找什么,但如果我将 .fiddler 添加到 url 就能够显示它。当我查看 cookie/login 下的标题时,我看到:代理支持:基于会话的身份验证,WWW-Authenticate:协商,WWW-Authenticate:NTLM。当我在 headers->Cookies/Login 下查看来自 Web 浏览器的请求时,它说:Persistent-Auth: true
猜你喜欢
  • 1970-01-01
  • 2020-08-08
  • 1970-01-01
  • 1970-01-01
  • 2018-04-06
  • 2017-07-04
  • 1970-01-01
  • 2023-03-25
相关资源
最近更新 更多