Last active
August 29, 2015 14:06
-
-
Save bfcamara/6aab0858ebda2db435a9 to your computer and use it in GitHub Desktop.
Consuming VS Online REST API using a Service Account
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using System.Net; | |
using System.Net.Http; | |
using System.Diagnostics; | |
using System.Net.Http.Headers; | |
using Newtonsoft; | |
using Newtonsoft.Json; | |
using Newtonsoft.Json.Converters; | |
using Newtonsoft.Json.Serialization; | |
using Newtonsoft.Json.Utilities; | |
using Newtonsoft.Json.Linq; | |
namespace VsoRestAPiWithServiceAccount | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
Console.WriteLine("Main start"); | |
Task t = AsyncMain(); | |
t.ContinueWith((str) => | |
{ | |
Console.WriteLine(str.Status.ToString()); | |
Console.WriteLine("Main end"); | |
}); | |
t.Wait(); | |
} | |
public static async Task AsyncMain() | |
{ | |
string accountName = "your account goes here"; | |
string urlAccount = string.Format("https://{0}.visualstudio.com", accountName); | |
string serviceAccountUsername = "your service account username goes here"; | |
string servviceAccountPassword = "your service account password goes here"; | |
//1 - Hit VSOnline unauthenticated | |
var client = HttpClientFactory.Create(new HttpClientHandler() { AllowAutoRedirect = false }); | |
var resp = await client.GetAsync(urlAccount, HttpCompletionOption.ResponseHeadersRead); | |
Console.WriteLine("Status Code = " + resp.StatusCode); | |
Debug.Assert(resp.StatusCode == HttpStatusCode.Redirect); | |
if (!resp.Headers.Contains("x-tfs-fedauthrealm") || | |
!resp.Headers.Contains("x-tfs-fedauthissuer")) | |
{ | |
Console.WriteLine("Cannot determine federation data"); | |
return; | |
} | |
string realm = resp.Headers.GetValues("x-tfs-fedauthrealm").First(); | |
string issuer = resp.Headers.GetValues("x-tfs-fedauthissuer").First(); | |
Console.WriteLine("Federation Data:Realm={0}; Issuer={1}", realm, issuer); | |
//2 - Get an access token from ACS using WRAP protocol | |
string acsHost = new Uri(issuer).Host; | |
string acsRequestTokenUrl = string.Format("https://{0}/WRAPv0.9", acsHost); | |
resp = await client.PostAsync(acsRequestTokenUrl, new FormUrlEncodedContent( | |
new KeyValuePair<string, string>[] { | |
new KeyValuePair<string, string>("wrap_scope", realm), | |
new KeyValuePair<string, string>("wrap_name", serviceAccountUsername), | |
new KeyValuePair<string, string>("wrap_password", servviceAccountPassword) | |
} | |
)); | |
resp.EnsureSuccessStatusCode(); | |
var acsTokenData = await resp.Content.ReadAsFormDataAsync(); | |
var accessToken = acsTokenData["wrap_access_token"]; | |
var accessTokenExpiredInSecs = int.Parse(acsTokenData["wrap_access_token_expires_in"]); | |
Console.WriteLine("Your access token expires in {0}: {1}", | |
accessTokenExpiredInSecs, | |
accessToken); | |
//3 - Let's use the access token to consumer the REST api | |
var request = new HttpRequestMessage( | |
HttpMethod.Get, | |
urlAccount + "/DefaultCollection/_apis/projects?api-version=1.0-preview.1"); | |
request.Headers.Authorization = new AuthenticationHeaderValue( | |
"WRAP", | |
string.Format("access_token=\"{0}\"", accessToken)); | |
resp = await client.SendAsync(request); | |
resp.EnsureSuccessStatusCode(); | |
JObject jsonResult = await resp.Content.ReadAsAsync<JObject>(); | |
var projects = jsonResult.SelectTokens("$.value[*].name"); | |
Console.WriteLine("Here is the list of your pojects"); | |
foreach (var p in projects) | |
{ | |
Console.WriteLine(p); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment