I tried TFS 2015 REST API Authentication However, it mentions request object (as I can't use javascript), not sure where is the request object or what type of it.
I am trying to pass query id and the code should execute the query and get result via API. The solution works from my local, however, after publishing to server it does not seems working. I also checked that the TFS is accessible from server using the credentials.
My code below:
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;
}
The error I received is:
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