13

We are trying to invoke the TFS 2015 REST API's from a web-page using Javascript and have a challenge in establishing valid authentication with the TFS server.

We do not know how to generate a personal access tokens or an OAuth access tokens. The instruction below seem to apply more toward VSO than on-premise TFS. https://www.visualstudio.com/en-us/integrate/get-started/rest/basics

How can I generate an authentication key/token?

UPDATE: As on Mar 2017, the latest release of On-Prem TFS supports creating personal access tokens for all users. Using the below javascript code by @Elmar you can make requests to update, edit TFS workitems from REST API.

vikkee
  • 361
  • 1
  • 2
  • 12

3 Answers3

14

The OAuth mechanism is used against the VSO api at the time of writing this as you've seemingly identified. official docs for VSO OAuth tokens here.

For on-prem however, the following is required:

Via a javascript client (note I'm using jquery for the ajax request here)

Since alternative creds or token based auth isn't available on-prem to match current vso implementation; You can consider the following approach: If you have admin permissions on the TFS app tier, you can configure basic authentication for the tfs application in IIS, and set the default domain.

enabling basic auth and setting domain

And then invoke as follows:

var self = this;
        self.tasksURI = 'https://<SERVER>/tfs/<COLLECTION>/<PROJECT>/_apis/build/builds?api-version=2.0';
        self.username = "<USERNAME>"; //basic username so no domain here.
        self.password = "<PASSWORD>";

        self.ajax = function (uri, method, data) {
            var request = {
                url: uri,
                type: method,
                contentType: "application/json",
                accepts: "application/json",
                cache: false,
                dataType: 'json',
                data: JSON.stringify(data),
                beforeSend: function (xhr) {
                    xhr.setRequestHeader("Authorization", "Basic " + btoa(self.username + ":" + self.password));
                },
                error: function (jqXHR) {
                    console.log("ajax error " + jqXHR.status);
                }
            };
            return $.ajax(request);
        }

        self.ajax(self.tasksURI, 'GET').done(function (data) {

            alert(data);

        });

IMPORTANT NOTE! : If you enable basic auth you really should configure your site to use https too or your credentials will be sent in clear text (as indicated in the warning seen -> top right of the image above).


Via a .NET client

In on-prem (currently rtm'd: 2015 update 1) the api is generally gated/fenced off with NTLM, meaning a pre-flight request is made, 401 returned from server to challenge for auth, in this case, setting the request Credential as follows allows the request to auth against the server once the preflight challenge is received. To accommodate the challenge you can do this:

request.Credentials = new NetworkCredential(this.UserName, this.Password);
//you may want to specify a domain too

If you've enabled basic auth for tfs on prem you can attempt authenticating as follows, this pattern matches the mechanism used when invoking vso after enabling alternative credentials in the ui:

request.Headers[HttpRequestHeader.Authorization] = "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(this.UserName + ":" + this.Password));

Note: In some code I modified a few weeks ago; support for both VSO and on-prem was required so I used the two patterns above to deal with the specific scenario.

Elmar
  • 1,236
  • 1
  • 11
  • 16
  • Thanks @Elmar for sharing your answers here. I am writing more of java script, so I am trying to find out how create the personal access token in place of myPatToken in the request header "Authorization" as mentioned here? `headers: { 'Authorization': 'Basic ' + btoa("" + ":" + myPatToken) }` – vikkee Mar 18 '16 at 16:48
  • 2
    @vikkee please see the modified answer. I've provided basic auth information and a javascript snippet. as far as the token is concerned, i myself would like it on prem. – Elmar Mar 18 '16 at 21:44
  • Thanks much for your detailed javascript syntax, I do not have permission or influence over the TFS administrator at my place, so I need to first find out a way around it. Is it possible to find out what all types of authentication are already enabled by the administrator? – vikkee Jun 01 '16 at 21:18
  • @vikkee Realistically you will need an admin to confirm it for you. You can ask the admin to run the following command on the application tier and then to give you the output of the command: `%systemroot%\system32\inetsrv\appcmd.exe list config "Team Foundation Server/tfs" -section:windowsAuthentication`. you can also provide `basicAuthentication` to the `-section` argument to and get the output of that. This will not however tell you _exactly_ how basic auth has been configured. The procedure in my answer is the way to enable it none the less. – Elmar Jun 03 '16 at 15:14
  • 1
    @vikkee As an aside if you intend on trying the NTLM route as a possibility please check out this SO question too: [link](http://stackoverflow.com/questions/18527749/javascript-ajax-ntlm-authentication) – Elmar Jun 03 '16 at 15:18
  • After almost an year I am marking this as resolved. The On-Prem TFS version finally had capability to create PAT (personal access token), and using this code we were able to now make REST Calls successfully and retrieve, update work items. my version number says, "15.112.26307.0" which is the latest 2017 release as per this [link]https://blogs.msdn.microsoft.com/tfssetup/2013/11/21/what-version-of-team-foundation-server-do-i-have/[link] – vikkee May 22 '17 at 20:38
  • @vikkee What does PAT have to do with it? Elmar's code doesn't use the PAT, it uses username/password. – pabrams Feb 04 '19 at 16:58
2

My question is old but as on Mar 2017, the latest release of On-Prem TFS supports creating personal access tokens for all users. Using the javascript code by @Elmar you can make requests to update, edit TFS workitems from REST API.

vikkee
  • 361
  • 1
  • 2
  • 12
1

If possible, I would recommend using the .NET client libraries for Visual Studio Team Services (and TFS):

https://www.visualstudio.com/en-us/docs/integrate/get-started/client-libraries/dotnet

You can use windows authentication (which is what I needed). After including the following nuget packages in my code:

Microsoft.TeamFoundationServer.Client
Microsoft.VisualStudio.Services.Client
Microsoft.VisualStudio.Services.InteractiveClient

I was able to write this code:

// Create instance of VssConnection using Windows credentials (NTLM)
var connection = new VssConnection(new Uri("http://mytfsserver:8080/tfs/CollectionName"), new VssClientCredentials());

// Create instance of WorkItemTrackingHttpClient using VssConnection
var gitClient = connection.GetClient<GitHttpClient>();
var items = gitClient.GetRepositoriesAsync().Result;

foreach (var item in items)
{
    Console.WriteLine(item.Name);
}

See also: https://www.visualstudio.com/en-us/docs/integrate/get-started/client-libraries/samples

Trevor
  • 4,620
  • 2
  • 28
  • 37