TokenClient (Mix) introduction

This week at Mix I demonstrated a new experimental client API (TokenClient) for interacting with the Access Control Service (ACS). The purpose of this API is to simplify the developer interaction with the ACS Security Token Service. It still uses WS-Trust on the wire, but restricts the WS-Trust options to what I believe to be the bare minimum.

NOTE: this code requires the Geneva Fx (version released at PDC 08) in order to work. The assembly version # is 0.5.1.0.

NOTE NOTE: This code is highly experimental – I’ve written it to demonstrate a core capability of ACS. As a result, it hasn’t been rigorously tested, and I am absolutely certain that there are bugs.

Recalling earlier posts, remember that ACS simply accepts claims and uses access control rules to transform those input claims to output claims. Claims in, Claims out – all the live long day. The client API shown here reflects that simplicity.

ACS receives “claims in” if those claims are wrapped in a token. As a result, the TokenClient type has a method that will package claims into a signed and encrypted token. There are other methods that send that token to ACS, and still other methods that return the ACS issued claims in a couple of different handy formats.

First let’s discuss instantiation. In order to create a token, a TokenClient object needs to be able to sign and encrypt a token. This information is packaged in a TokenClientSettings object. The TokenClient type constructor accepts a TokenClientSettings object as shown below.

 TokenClientSettings settings = new TokenClientSettings() {
   LocalIssuerAddress = new Uri("https://localhost/myissuer"),
   LocalIssuerSigningCertificate = new X509Certificate2("sign.pfx", "pwd"),
   Scope = new Uri("https://localhost/myservice"),
   ScopeEncryptingCertificate = new X509Certificate2(“enc.cer", "pwd"),
   SolutionName = "justindemoaccount"
 };
  
 TokenClient client = new TokenClient(settings);

Property Name

Description

LocalIssuerAddress

The value of the SAML issuer for the self-issued token. This address will need to be registered with ACS

LocalIssuerSigningCertificate

The X509Certificate2 object (with private key) that will be used to sign the self-issued token

Scope

The Scope URI that the token will be sent to (in an RST)

ScopeEncryptingCertificate

In cases where an ACS issued token will be decrypted, this certificate is used.

SolutionName

Your solution name. This is needed to direct the RST to the correct address.

Next, let’s instantiate an IEnumerable<Microsoft.IdentityModel.Claims.Claim> object.

 Claim[] claims = new Claim[] { new Claim(@"https://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn", 
                                                      "justin@calculatordemo.com") };

This claim value is completely made up. It’s just a value that I’ve decided to use. Similarly, the claim type is fairly arbitrary. I chose UPN out of convenience – you can choose any claim type you like (as long as you set that claim type up in your ACS scope).

Next, let’s send those claims to ACS and see what claims we get back:

 IEnumerable<Claim> acsIssuedClaims = client.TransformForClaims(claims);

Next, we can dump these claims to the console:

 foreach (Claim claim in acsIssuedClaims) {
  
 if (claim.ClaimType != "https://schemas.microsoft.com/ws/2008/06/identity/claims/confirmationkey")
  
 {
  
      Console.WriteLine("===================================");
  
      Console.WriteLine("Claim Value: {0}", claim.Value);
  
      Console.WriteLine("\tClaim Type: {0}", claim.ClaimType);
  
      Console.WriteLine("\tClaim Issuer: {0}", claim.Issuer);
  
      Console.WriteLine("===================================\n");
  
 }
  
 }
  

Before we compile and run this sample, we need to setup ACS. The steps below roughly approximate what to do:

1) Login to the https://portal.ex.azure.microsoft.com and browse to the ACS management portal

2) Create a new scope (https://localhost/myservice)

3) Setup a new Identity Issuer:

a. Name: SimpleClaimIssuer

b. Uri: (https://localhost/myissuer)

c. Certificate (the public key only version of sign.cer)

4) Setup the encryption preferences:

a. Certificate (the public key verision of enc.cer)

5) Add a rule:

a. Input: UPN justin@calculatordemo.com

b. Output: Action: Read

When you press F5 in the project, you will see the Action claim print to the console. In essence, the TokenClient will have created a token that contains a UPN claim, sent it to ACS for transformation, received the result, decrypted and verified the result, and printed the claims to the console.

A link to download the code is below. Enjoy and please let me know as you find bugs… Again – this code is highly experimental…