Visual Studio Online Extensibility – OAuth 2.0

VSO IntegrateIn meinem letzten Beitrag habe ich das neue REST Interface von Visual Studio Online vorgestellt. Dieses Interface kann als zukünftige Basis-Schnittstelle von Visual Studio Online und Team Foundation Server angesehen werden. Um eine möglichst sichere Art des Datenaustausches über dieses API zu erzielen, empfiehlt sich die Verwendung des OAuth 2.0 Protokolls. Mit OAuth können sich Benutzer am System authentifizieren, ohne bei jedem Interface-Aufruf die User Credentials angeben zu müssen.

Die REST API gibt es schon seit ein paar Monaten (Preview seit Mai 2014) und somit konnten meine Kollegin Ulli Stirnweiss und ich uns schon eine Weile damit beschäftigen. Zusammen mit Marco Richardson (MVP Windows Plattform Development) haben wir eine Windows App entwickelt, die ihre Daten über die neue Schnittstelle von Visual Studio Online bezieht und zur Authentifizierung das OAuth 2.0 Protokoll verwendet.

RestApi_VSO_EvolutionAbbildung 1: Screenshots aus dem TFS Showcase

Ich werde euch in diesem Beitrag die Grundlagen von OAuth an Hand einer einfachen Webanwendung näher bringen. Das Sample, welches ich in diesem Beitrag verwende, ist von Will Smythe (Program Manager bei Microsoft) und steht auf Codeplex zum Download bereit.

OAuth 2.0

Das OAuth 2.0 Protokoll ist eine Erweiterung des seit 2006 bestehenden OAuth 1.0 Protokolls und soll Authentifizierungsabläufe für Client-Entwickler vereinfachen. Der große Benefit von OAuth ist, dass die aufrufende Applikation keine Credentials des Benutzers vorhält und beim Aufruf der VSO Interfaces mitübertragen muss. OAuth 2.0 ist auch kein Standard der alleine von Visual Studio Online eingesetzt wird, es gibt zahlreiche Unternehmen, die ebenfalls auf dieses Protokoll setzen (z.B. Dropbox, Foursquare, GitHub und Google).

Der zugrundeliegende Mechanismus von OAuth 2.0 unterliegt folgendem Ablauf. Als erstes muss sich eine Applikation am aufzurufenden Service registrieren. In diesem Registrationsverfahren werden üblicherweise allgemeine Daten wie App-Name, Webseite, Logo, etc. abgefragt. Wesentlicher Bestandteil ist auch die Angabe einer sogenannten Redirect URL, zu der Benutzer beim Aufruf des Services umgeleitet werden, um unerwünschte Service-Aufrufe, die nicht von der Applikation kommen, zu vermeiden.

Nach der erfolgreichen Registrierung erhält man dann eine Client ID und ein Client Secret. Die Client ID enthält öffentliche Informationen und wird dann in der App verwendet, um den Service aufzurufen. Das Client Secret hingegen muss absolut vertraulich behandelt werden, damit eine sichere Authentifizierung erfolgen kann.

OAuth 2.0 für Visual Studio Online

Das folgende Schaubild, welches ich auf visualstudio.com gefunden habe, zeigt den kompletten Authentifizierungs-Mechanismus für Visual Studio Online.

OAuth-Mechanismus von VSOAbbildung 2: OAuth Mechanismus von Visual Studio Online

Als erstes wird von der App eine Anfrage an Visual Studio Online zur Autorisierung eines neuen Benutzers gesendet. Anschließend muss der User die App für die Abfrage von Daten aus VSO berechtigen. Mit Hilfe eines von VSO übersendeten Authorization Codes kann von VSO ein Access Token und ein Refresh Token angefragt werden. Diese Token können dann von der Anwendung verwendet werden, um Daten über das Visual Studio Online REST Interface abzufragen.

Registrierung einer Anwendung an Visual Studio Online

Wie bereits erwähnt, muss eine Anwendung erst für Visual Studio Online registriert werden, damit der eigentliche Authentifzierungs-Mechanismus durchgeführt werden kann. Dafür notwendig ist eine  Webseite, die als Redirect verwendet werden kann. Letztendlich werden einige Informationen der Anwendung, sowie die URL der Webseite im Registrierungsformular von Visual Studio Online eingegeben und bestätigt (https://app.vssps.visualstudio.com/app/register).

OAuth_App Registration

Abbildung 3: Registrierungsformular für Anwendung an VSO

Wichtig an dieser Stelle ist, dass der richtige Bereich angegeben wird, auf den die Anwendung Zugriff haben soll. Diese sogenannten Authentication Scopes können bisher nicht nachträglich geändert werden, demzufolge sollte man sich vor dem Abschluss der Registrierung ausreichend sicher sein.

Hinweis: Wenn ein Authentication Scope falsch gesetzt oder eine App noch während der Preview-Phase registriert wurde, dann kann man eine App auch ein weiteres Mal registrieren, um die Scopes zu ändern.

Authentifizierung durch OAuth 2.0

Nach einer erfolgreichen Registrierung der Anwendung erhält man wie erwartet eine App ID und ein App Secret. Durch die folgende URL ist man nun in der Lage sich aus der App heraus zu authentifizieren:

https://app.vssps.visualstudio.com/oauth2/authorize?client_id={App-ID}&response_type=Assertion&state=User1&scope=vso.work%20vso.code_write&redirect_uri=https://almsports-oauthsample.azurewebsites.net /myapp/oauth-callback

In der Sample App wird zum Aufruf der URL, folgender Code ausgeführt:

public ActionResult RequestToken(string code, string status)
{
   return new RedirectResult(GenerateAuthorizeUrl());
}
public String GenerateAuthorizeUrl()
{
   return String.Format("{0}?client_id={1}&response_type=Assertion&state={2}&scope={3}&redirect_uri={4}",
   ConfigurationManager.AppSettings["AuthUrl"],
   ConfigurationManager.AppSettings["AppId"],
   "state",
   ConfigurationManager.AppSettings["Scope"],
   ConfigurationManager.AppSettings["CallbackUrl"]);
}

Durch den Aufruf der Seite, wird dem Benutzer folgender Screen gezeigt:

OAuth_User_ProofAbbildung 4: Berechtigungen überprüfen für App Zugriff

Durch diese Seite wird die Zustimmung des Benutzers für den Zugriff der App auf den VSO Account bestätigt.

Nach der Zustimmung schickt Visual Studio Online einen Authorization Code zurück an die Anwendung, die den Code aufbereitet und für die Anfrage für den Access Token verwendet.

https://app.vssps.visualstudio.com/oauth2/token?client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion={AppSecret}&grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion={authorization code}&redirect_uri={callbackUrl}

Die Methode PerformTokenRequest(string, out Token) verwendet dafür einen „Post-Data“-Wert, der ungefähr dem obigen String entspricht. Der eigentliche Aufruf in der App sieht dann wie folgt aus:

HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(ConfigurationManager.AppSettings["TokenUrl"]);
webRequest.Method = "POST";
webRequest.ContentLength = postData.Length;
webRequest.ContentType = "application/x-www-form-urlencoded";
 
using (StreamWriter swRequestWriter = new StreamWriter(webRequest.GetRequestStream()))
{
   swRequestWriter.Write(postData);
}
try
{
   HttpWebResponse hwrWebResponse = (HttpWebResponse)webRequest.GetResponse();
 
   //to be done
}

Ist der Aufruf erfolgreich, steckt im HttpWebResponse Objekt der Access Token verborgen, zusammen mit einem Gültigkeits-Zeitstempel, der Token-Typ-Bezeichnung und einem Refresh Token. Der Refresh Token muss nach Ablauf des Zeitstempels zur verwendet werden, denn dann ist der Access Token nicht mehr gültig.

Daten abfragen

Bei jeder Datenabfrage über die REST API muss nun der erhaltene Token im Header mitgeschickt werden. Die Abfrage der Build Status Informationen würde demnach wie folgt aussehen:

using (HttpClient client = new HttpClient())
{
   client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
 
   client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization", "bearer " + token.accessToken);
 
   using (HttpResponseMessage response = 
      client.GetAsync("https://almsports.visualstudio.com/DefaultCollection/_apis/build/builds").Result)
   {
      response.EnsureSuccessStatusCode();
      responseBody = await response.Content.ReadAsStringAsync();
 
      //Response.Write(responseBody);
   }
}

Wer sich noch an meinen Blog Post zum Thema REST API erinnert, dem fällt sofort auf, dass nun im Authentication Header nicht mehr „Basic“, sondern „Authorization“ als Schema angegeben ist und als Parameter nicht mehr „Username/Passwort“, sondern der Token durch „bearer {Access Token}“.

Freuen könnt Ihr Euch auch diesmal wieder auf einen Beitrag von Ulli Stirnweiss zum diesem Thema. Sie wird Euch auf Ihrem Blog ein paar Hinweise geben, wie man Windows Store Apps mit OAuth für Visual Studio Online baut.

Stay tuned.

[1] https://vsooauthclientsample.codeplex.com

[2] http://aaronparecki.com/articles/2012/07/29/1/oauth2-simplified

[3] http://www.visualstudio.com/integrate%5Cget-started/get-started-auth-oauth2-vsi

[4] http://www.codesmartnothard.com/CategoryView,category,VisualStudio.aspx

2 Gedanken zu “Visual Studio Online Extensibility – OAuth 2.0

  1. Pingback: Ullibility.net | Eine App für VSO – Teil 1: Authentifizierung

  2. Pingback: Visual Studio Online Extensibility – OAuth 2.0 - Christian Binder - Site Home - MSDN Blogs

Die Kommentarfunktion ist geschlossen.