在 Windows Phone 8.1 上使用 Sharepoint REST API 时,HttpClient 无法通过 NTLM 对第二个请求进行身份验证 [英] HttpClient fails to authenticate via NTLM on the second request when using the Sharepoint REST API on Windows Phone 8.1

查看:11
本文介绍了在 Windows Phone 8.1 上使用 Sharepoint REST API 时,HttpClient 无法通过 NTLM 对第二个请求进行身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

抱歉,标题太长,但根据我目前所知,这似乎是最好的总结.

我们目前正在开发一个通用应用程序,该应用程序需要使用 NTLM 身份验证通过 REST API 访问 Sharepoint 服务器上的某些文档,事实证明这比应有的困难.虽然我们能够为所有问题找到解决方法(见下文),但我真的不明白发生了什么以及为什么它们甚至是必要的.不知何故,HttpClient 类在手机和 PC 上的行为似乎不同.这是我目前了解到的.

我从这个代码开始:

var credentials = new NetworkCredential(userName, password);var handler = new HttpClientHandler(){凭证 = 凭证};var client = new HttpClient(handler);var response = await client.GetAsync(url);

这在 Windows 应用程序中运行良好,但在 Windows Phone 应用程序中失败.服务器只返回一个 401 Unauthorized 状态代码.

一些 之前,但似乎没有一个解决方案.

第二个帖子中的回答表明 NTLM 握手有问题.但是为什么只有第二次呢?另外,这似乎是 HttpClient 类的问题,因为以下代码在两个平台上都没有问题:

var request3 = WebRequest.CreateHttp(url);request3.Credentials = 凭证;var response3 = await request3.GetResponseAsync();var request4 = WebRequest.CreateHttp(url);request4.Credentials = 凭证;var response4 = await request4.GetResponseAsync();

所以问题才出现:

  • 在 Windows Phone 上.Windows 应用程序中的相同代码有效.
  • 连接到 Sharepoint 时.使用 NTLM 身份验证访问另一个站点适用于两个平台.
  • 使用 HttpClient 时.使用 WebRequest,它可以工作.

所以虽然我很高兴我至少找到了一些让它发挥作用的方法,但我真的很想知道这种组合有什么特别之处,以及可以做些什么来让它发挥作用?

解决方案

嗨 Daniel 在我进行同步时遇到了同样的问题,因为 Windows Phone 有很多缓存问题,最终我可以通过添加标题来解决.另外我认为使用超时是个好主意,因为它是一个很长的响应,你可以等待很多时间......而另一个很好的工作方式是使用使用",它类似于使用.Dispose()".现在我给你看代码:

 var request3 = WebRequest.CreateHttp(url);request3.Credentials = 凭证;request.ContinueTimeout = 4000;//4 秒//用于解决缓存问题request.Headers["Cache-Control"] = "no-cache";request.Headers["Pragma"] = "no-cache";using(httpWebResponse response3 = (httpWebResponse) await request3.GetResponseAsync()){如果(响应3.StatusCode == HttpStatusCode.OK){//你的代码...}}var request4 = WebRequest.CreateHttp(url);request4.Credentials = 凭证;request.ContinueTimeout = 4000;//4 秒//用于解决缓存问题request.Headers["Cache-Control"] = "no-cache";request.Headers["Pragma"] = "no-cache";using(httpWebResponse response4 = (httpWebResponse) await request4.GetResponseAsync()){如果(响应4.StatusCode == HttpStatusCode.OK){//你的代码...}}

我等待我的代码可以帮助您.谢谢,祝你好运!

Sorry for the long title, but it seems to be the best summary based on what I know so far.

We’re currently working on a Universal App that needs to access some documents on a Sharepoint server via the REST API using NTLM Authentication, which proves to be more difficult than it should be. While we were able to find workarounds for all problems (see below), I don’t really understand what is happening and why they are even necessary. Somehow the HttpClient class seems to behave differently on the phone and on the PC. Here’s what I figured out so far.

I started with this code:

var credentials = new NetworkCredential(userName, password);

var handler = new HttpClientHandler() 
{
    Credentials = credentials
};

var client = new HttpClient(handler);

var response = await client.GetAsync(url);

This works fine in the Windows app, but it fails in the Windows Phone app. The server just returns a 401 Unauthorized status code.

Some research revealed that you need to provide a domain to the NetworkCredential class.

var credentials = new NetworkCredential(userName, password, domain);

This works on both platforms. But why is the domain not required on Windows?

The next problem appears when you try to do multiple requests:

var response1 = await client.GetAsync(url);
var response2 = await client.GetAsync(url);

Again, this works just fine in the Windows app. Both requests return successfully:

And again, it fails on the phone. The first request returns without problems:

Strangely any consecutive requests to the same resource fail, again with status code 401.

This problem has been encountered before, but there doesn’t seem to be a solution yet.

An answer in the second thread suggests that there’s something wrong with the NTLM handshake. But why only the second time? Also, it seems to be a problem of the HttpClient class, because the following code works without problems on both platforms:

var request3 = WebRequest.CreateHttp(url);
request3.Credentials = credentials;

var response3 = await request3.GetResponseAsync();

var request4 = WebRequest.CreateHttp(url);
request4.Credentials = credentials;

var response4 = await request4.GetResponseAsync();

So the problem only appears:

  • on Windows Phone. The same code in a Windows App works.
  • when connecting to Sharepoint. Accessing another site with NTLM authentication works on both platforms.
  • when using HttpClient. Using WebRequest, it works.

So while I'm glad that I at least found some way to make it work, I’d really like to know what’s so special about this combination and what could be done to make it work?

解决方案

Hi Daniel at the same problem when I do my sync, because windows phone had a lot of problems with cache, finallt I could solve with add headers. Also I think so it's good idea that you use the timeout because it's a loooong response you can wait a lot of time... And the other good way to work it's use "using", it's similar that use ".Dispose()". Now I show you the code:

 var request3 = WebRequest.CreateHttp(url);
 request3.Credentials = credentials;
 request.ContinueTimeout = 4000; //4 seconds

 //For solve cache problems
 request.Headers["Cache-Control"] = "no-cache";
 request.Headers["Pragma"] = "no-cache";

 using(httpWebResponse response3 = (httpWebResponse) await request3.GetResponseAsync()){
      if (response3.StatusCode == HttpStatusCode.OK)
      {
          //Your code...
      }
 }

 var request4 = WebRequest.CreateHttp(url);
 request4.Credentials = credentials;
 request.ContinueTimeout = 4000; //4 seconds

 //For solve cache problems
 request.Headers["Cache-Control"] = "no-cache";
 request.Headers["Pragma"] = "no-cache";

 using(httpWebResponse response4 = (httpWebResponse) await request4.GetResponseAsync()){
      if (response4.StatusCode == HttpStatusCode.OK)
      {
          //Your code...
      }
 }

I wait that my code can help you. Thanks and good luck!

这篇关于在 Windows Phone 8.1 上使用 Sharepoint REST API 时,HttpClient 无法通过 NTLM 对第二个请求进行身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆