Back in September I wrote the article “Requesting a Token from Access Control Service in C#”. In that article I demonstrated the creation of a requesting token, using the Simple Web Token (SWT) token format, and using the OAuth Web Resource Authorization Protocol (WRAP) as the token request protocol. In response ACS will issue a SWT token back which can be used to access web services (commonly REST).
There is one problem though: OAuth WRAP has been deprecated in favor of the OAuth 2.0 specification which the IETF community has been working on over the past year.
The Access Control Service team has been working on supporting the latest revision of OAuth 2.0. As such, it is currently implemented in the Labs CTP version of ACS available at http://portal.appfabriclabs.com/ for testing.
The intent of this article is to provide a simple piece of code to request tokens from ACS using the OAuth 2.0 protocol head instead of OAuth WRAP profile. As such, I will provide a new version of the TokenFactory class I previous posted and I will highlight the differences. For a full understanding of the OAuth 2.0 support in ACS please visit http://acs.codeplex.com/ for documentation and samples.
Also earlier in the year I had written a number of other samples for obtaining tokens from ACS using other languages other than C#, like PHP, Java, and Python. I will not be updating those samples for using OAuth 2.0 instead of WRAP; however, both protocols are relatively simple so it won’t take much effort to figure out how the changes apply for the other languages.
using System; using System.Collections.Generic; using System.Collections.Specialized; using System.IO; using System.Net; using System.Text; using System.Web.Script.Serialization; public class TokenFactory { private static string acsHost = "accesscontrol.appfabriclabs.com"; string serviceNamespace; string serviceIdentityName; string serviceIdentityPassword; public TokenFactory(string serviceNamespace, string serviceIdentityName, string serviceIdentityPassword) { this.serviceNamespace = serviceNamespace; this.serviceIdentityName = serviceIdentityName; this.serviceIdentityPassword = serviceIdentityPassword; } public string GetACSToken(string relyingPartyApplicationName) { string response; // request a token from ACS WebClient client = new WebClient(); client.BaseAddress = string.Format(@"https://{0}.{1}/", serviceNamespace, acsHost); NameValueCollection values = new NameValueCollection(); values.Add("grant_type", "password"); values.Add("client_id", serviceIdentityName); values.Add("username", serviceIdentityName); values.Add("client_secret",serviceIdentityPassword); values.Add("password", serviceIdentityPassword); try { byte[] responseBytes = client.UploadValues("/v2/OAuth2-10/rp/" + relyingPartyApplicationName, values); string responseData = Encoding.UTF8.GetString(responseBytes); JavaScriptSerializer serializer = new JavaScriptSerializer(); Dictionary<string, object> decodedDictionary = serializer.DeserializeObject(responseData) as Dictionary<string, object>; response = decodedDictionary["access_token"] as string; } catch (WebException ex) { StreamReader reader = new StreamReader(ex.Response.GetResponseStream()); response = reader.ReadToEnd(); } return response; } }
Notice that there are a number of changes from the previous version.
Due to these changes Main() also needs to be updated as we no longer need to produce the SWT request and the terminology is updated.
static void Main(string[] args) { string serviceNamespace = "...your service namespace..."; string serviceIdentityName = "... your service identity name..."; string serviceIdentityPassword = "...your service identity password..."; string relyingPartyApplicationName = "... your Relying Party application name..."; TokenFactory tf = new TokenFactory(serviceNamespace, serviceIdentityName, serviceIdentityPassword); string returnToken = tf.GetACSToken(relyingPartyApplicationName); Console.WriteLine(returnToken); Console.ReadLine(); }