【问题标题】:401 Unauthorized on SECOND HttpClient/HttpWebRequest call401 在第二个 HttpClient/HttpWebRequest 调用上未经授权
【发布时间】:2014-07-23 23:51:04
【问题描述】:

我有一个使用 SharePoint 2010 REST API 的应用程序。 在创建 Item 的过程中,有多个请求一个接一个地完成:

1 调用:从列表中获取项目:成功

2 调用:创建项目:401 Unauthorized

如果我这样做也是一样的:

1 调用:创建项目:成功

2 调用:删除项目:401 Unauthorized

我所知道的是,我的函数是单独工作的,它们不会在它们被一个接一个地调用时工作。 当我在创建项目后关闭应用程序(Windows Phone 8.1 应用程序)并在重新启动时尝试删除它工作的项目。

首先,我认为这与我处理字段的方式有关,因此我在 finally 语句中将它们更改为 NULL,但这不起作用。

    public async Task<bool> CreateNewItem(NewItem myNewItem)
    {   
        try
        {
            StatusBar statusBar = await MyStatusBar.ShowStatusBar("Creating new List Item.");
            //Retrieving Settings from Saved file
            mySettings = await MyCredentials.GetMySettings();
            myCred = new NetworkCredential(mySettings.UserName, mySettings.Password, mySettings.Domain);

            using (var handler = new HttpClientHandler { Credentials = myCred })
            {
                HttpClient client = new HttpClient(handler);
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                NewItem newItem = myNewItem;
                var jsonObject = JsonConvert.SerializeObject(newItem);

                HttpResponseMessage response = await client.PostAsync(new Uri(baseUrl + listNameHourRegistration), new StringContent(jsonObject.ToString(), Encoding.Unicode, "application/json"));
                response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                response.EnsureSuccessStatusCode();

                string responseMessage = await response.Content.ReadAsStringAsync();

                client.Dispose();

                if (responseMessage.Length > 0)
                     return true;
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message);
            return false;
        }
        finally
        {
            request = null;
            response = null;
            myCred = null;
            mySettings = null;
        }
        
        return false;
    }

【问题讨论】:

    标签: c# httpwebrequest httpclient


    【解决方案1】:

    遇到同样的问题。

    无论如何,第二个请求没有遵循相同的身份验证程序。即使你初始化了一个新的 HttpClient 对象。我嗅探了 HTTP 流量。

    在第一次请求之后,我正在使用不同的凭据进行另一次请求。这也以401结尾。我真的很困惑......

    似乎 NTLM 握手卡在 6 步中的第 2 步 http://www.innovation.ch/personal/ronald/ntlm.html

    编辑: 您可能想要使用 CSOM。 http://social.msdn.microsoft.com/Forums/office/en-US/efd12f11-cdb3-4b28-a9e0-32bfab71a419/windows-phone-81-sdk-for-sharepoint-csom?forum=sharepointdevelopment

    【讨论】:

    • 感谢您的回复,现在我知道我不是唯一一个。我也在 MSDN 上创建了一个问题,也许有人可以帮助我们MSDN Post
    • 可怕.... 搞乱 CredentialCache。但还没有成功。
    • 您找到解决方案了吗?
    • 不。我在我的项目中使用了 CSOM Api。
    【解决方案2】:

    虽然我仍然不知道实际问题是什么,但至少我找到了workaround:使用WebRequest 类而不是HttpClient

    【讨论】:

    • 我刚刚看到你在我的帖子上发布了这个。我得到了同样的答案,虽然我使用了HttpWebRequest
    • 是的,我使用了 WebRequest.CreateHttp,它创建了一个 HttpWebRequest。 ;)
    【解决方案3】:

    当我意识到每次调用端点时都在添加标头时,我遇到了同样的错误。希望这会对某人有所帮助。

    相反,我在类构造函数中初始化了 HttpClient 实例并在那里设置了标题。我还了解到,最好只使用 1 个实例而不是使用“使用”重新创建(参见这篇文章 https://www.aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/

    我正在循环中从另一个类调用 CallApiAsync。

    这是我的最终解决方案:

    class ApiShared
        {
            private HttpClient client;
    
            public ApiShared()  {
                client = new HttpClient();
                client.DefaultRequestHeaders.Add("x-api-key", ConfigurationManager.AppSettings["ApiKey"]);
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            }
    
            public async Task<ApiResponse_Root> CallApiAsync(string endpoint)
            {
                // Make API call
                Uri endpointUri = new Uri(endpoint);
                var stringTask = client.GetStringAsync(endpointUri);
                var data = JsonConvert.DeserializeObject<ApiResponse_Root>(await stringTask);
    
                return data;
            }
        }
    

    【讨论】:

      【解决方案4】:

      在 Windows 机器上,您可以通过以下注册表设置更改来解决此问题:

      转到以下注册表项:

      Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa
      

      现在向 Lsa 文件夹添加一个新的 DWORD,名为:DisableLoopBackCheck,并将其设置为 1

      【讨论】:

        【解决方案5】:

        我看到这个问题很久以前就发布过了。但我还没有看到这个帖子发布了一个正确工作的解决方案。

        我遇到了完全相同的问题,即下一个请求不断失败,返回 401 UnAuthorized。

        我使用 fiddler 发现,从第二个请求开始,请求中添加了一个 Cookie,这可能是服务器与第一个响应一起发送的 Set-Cookie 响应的结果。

        以下是我处理这种情况的方法 - 将 UseCookies 设为 false:

        new HttpClientHandler { Credentials = myCred, UseCookies = false }
        

        这应该可以解决您的问题。希望这对正在寻找类似问题的解决方案的人有所帮助。

        【讨论】:

          猜你喜欢
          • 2012-12-20
          • 1970-01-01
          • 1970-01-01
          • 2018-09-12
          • 1970-01-01
          • 1970-01-01
          • 2023-03-27
          • 2011-03-06
          • 2018-05-19
          相关资源
          最近更新 更多