Невозможно использовать TFS 2015 API. Получение 401 неавторизованной ошибки

Я пробовал TFS 2015 REST API Authentication Однако он упоминает объект запроса (насколько я могу '' t использовать javascript), не знаю, где находится объект запроса или какой его тип.

Я пытаюсь передать идентификатор запроса, и код должен выполнить запрос и получить результат через API. Решение работает с моего локального компьютера, однако после публикации на сервере оно не работает. Я также проверил, что TFS доступна с сервера с использованием учетных данных.

Мой код ниже:

    private HttpClientHandler GetTfsCredentials()
    {
        HttpClientHandler handler2 = new HttpClientHandler { UseDefaultCredentials = true };
        handler2.Credentials = new NetworkCredential("username", "password", "domain");
        return handler2;
    }
        private async Task<object> GetQueryResults(string queryId)
    {
        string tfsApiUrl = ConfigurationManager.AppSettings["TfsApiUrl"];
        string tfsProjectName = ConfigurationManager.AppSettings["TfsProjectName"];
        string TfsProjectGuid = ConfigurationManager.AppSettings["TfsProjectGuid"];

        //I tried both credentials and credentials2, but none of them working

        string credentials = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes($"{""}:{"password"}"));

        string credentials2 = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes("domain\\username:password") );

        if (!string.IsNullOrEmpty(tfsApiUrl) && !string.IsNullOrEmpty(tfsProjectName)
            && !string.IsNullOrEmpty(Id))
        {
            log.Info("GetQueryResults:: Config values found");
            using (var client = new HttpClient(GetTfsCredentials()) { BaseAddress = new Uri(tfsApiUrl) })
            {
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));

                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials2);

                HttpResponseMessage response = client.GetAsync($"{tfsProjectName}/_apis/wit/wiql/{Id}").Result;

                log.Info("GetQueryResults:: response.ReasonPhrase" + response.ReasonPhrase.ToString());
                log.Info("GetQueryResults:: response" + response.ToString());
                log.Info("GetQueryResults:: response.IsSuccessStatusCode" + response.IsSuccessStatusCode.ToString());
                string workItemList = null;

                if (response.IsSuccessStatusCode)
                {
                    //do something
                }
            }
        }

        return null;

    }

Я получил следующую ошибку:

2020-03-20 16:17:35,382 INFO GetQueryResults:: response.ReasonPhrase Unauthorized
2020-03-20 16:17:35,382 INFO GetQueryResults:: responseStatus Code: 401, ReasonPhrase: 'Unauthorized', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
  X-TFS-ProcessId: 115b5bba-0bf4-45e2-a3b2-2913ccc93f09
  ActivityId: bb21d947-99a3-44dc-bdb7-317d7af34934
  X-TFS-Session: bb21d947-99a3-44dc-bdb7-317d7af34934
  X-VSS-E2EID: bb21d947-99a3-44dc-bdb7-317d7af34934
  X-FRAME-OPTIONS: SAMEORIGIN
  X-TFS-SoapException: %3c%3fxml+version%3d%221.0%22+encoding%3d%22utf-8%22%3f%3e%3csoap%3aEnvelope+xmlns%3asoap%3d%22http%3a%2f%2fwww.w3.org%2f2003%2f05%2fsoap-envelope%22%3e%3csoap%3aBody%3e%3csoap%3aFault%3e%3csoap%3aCode%3e%3csoap%3aValue%3esoap%3aReceiver%3c%2fsoap%3aValue%3e%3csoap%3aSubcode%3e%3csoap%3aValue%3eUnauthorizedRequestException%3c%2fsoap%3aValue%3e%3c%2fsoap%3aSubcode%3e%3c%2fsoap%3aCode%3e%3csoap%3aReason%3e%3csoap%3aText+xml%3alang%3d%22en%22%3eTF400813%3a+The+user+%27CWOPA%5cSTCTCAPD006%24%27+is+not+authorized+to+access+this+resource.%3c%2fsoap%3aText%3e%3c%2fsoap%3aReason%3e%3c%2fsoap%3aFault%3e%3c%2fsoap%3aBody%3e%3c%2fsoap%3aEnvelope%3e
  X-TFS-ServiceError: TF400813%3a+The+user+%27CWOPA%5cSTCTCAPD006%24%27+is+not+authorized+to+access+this+resource.
  Server: Microsoft-IIS/8.5
  WWW-Authenticate: Bearer
  WWW-Authenticate: Negotiate
  WWW-Authenticate: NTLM
  X-Powered-By: ASP.NET
  P3P: CP="CAO DSP COR ADMa DEV CONo TELo CUR PSA PSD TAI IVDo OUR SAMi BUS DEM NAV STA UNI COM INT PHY ONL FIN PUR LOC CNT"
  Lfs-Authenticate: NTLM
  X-Content-Type-Options: nosniff
  Date: Fri, 20 Mar 2020 20:17:35 GMT
  Content-Length: 82
  Content-Type: text/plain; charset=utf-8
}
2020-03-20 16:17:35,382 INFO GetQueryResults:: response.IsSuccessStatusCode False


person TechTurtle    schedule 20.03.2020    source источник


Ответы (1)


Похоже, вы выполняете аутентификацию сразу двумя разными способами:

  • В GetTfsCredentials-методе вы настраиваете проверку подлинности Windows (NTLM или Kerberos)
  • Добавив client.DefaultRequestHeaders.Authorization, вы попытаетесь настроить базовую аутентификацию.

Ваша TFS указывает (см. Заголовок WWW-Authenticate), что он поддерживает однонаправленную передачу, согласование и NTLM; но не Basic.

Я бы попробовал:

  1. Удалите client.DefaultRequestHeaders.Authorization, credentials и credentials2. Это должно удалить базовую аутентификацию
  2. Удалите UseDefaultCredentials = true, поскольку в следующей строке вы явно указали учетные данные. UseDefaultCredentials сообщает HttpClientHandler о необходимости доступа к TFS с учетными данными запущенного процесса, которые, вероятно, являются вашей учетной записью при локальном выполнении и учетной записью службы при выполнении на сервере.
    Без этой строки указанный NetworkCredential должен использоваться для доступа к TFS.
person Sebastian Segerer    schedule 21.03.2020
comment
Кажется, что это работает, однако теперь я получаю еще одну ошибку: NotFound, я попробовал пустой URL-адрес прямо в браузере, и он вернул ответ. Не знаю, почему через API я получаю ошибку NotFound. - person TechTurtle; 22.03.2020
comment
http://www.{orgname}/tfs/{DEPT}/{projectName}/_apis/wit/wiql/fd32daa7-ecdb-41f7-aa36-6736dfbbb792 Это формат, который работает в браузере, но не через API. - person TechTurtle; 22.03.2020
comment
неважно, это была проблема с разрешением, и ее удалось исправить после ее назначения. Спасибо. - person TechTurtle; 23.03.2020