Windows Azure AppFabric Access Control Service v2 - Adding Identity Provider Using Management Service

This is quick intro to how to use Windows Azure AppFabric Access Control Service (ACS) v2 Management Service. In this sample I will show you what’s needed to add ADFS as an identity provider.

Summary of steps:

  • Step 1 - Collect configuration information.
  • Step 2 - Add references to required services and assemblies.
  • Step 3 – Create Management Service Proxy
  • Step 4 - Add identity provider
  • Step 5 - Test your work

The full sample with other functionalities is available here - Code Sample: Management Service.

The simplified sample I used for this walkthrough is here.

Other ACS code samples available here - Code Samples Index.

Step 1 - Collect configuration information.

  1. Obtain Management Client password using ACS Management Portal. Login to the Access Control Service management portal. In Administration section click on Management Service link. On the Management Service page click on ManagementClient link (ManagementClient is actual username for the service). In the Credentials section click either on Symmetric Key or Password link. The value in each is the same. This is the password.
  2. Obtain signing certificate from your ADFS 2.0.
  3. Make a note of your namespace, AppFabric host name (for lab it is accesscontrol.appfabriclabs.com )
  4. You should have these handy. 
 string serviceIdentityUsernameForManagement = "ManagementClient";
string serviceIdentityPasswordForManagement = "QL1nPx/iuX...YOUR PASSWORD FOR MANAGEMENT SERVICE GOES HERE";
string serviceNamespace = "YOUR NAMESPACE GOES HERE";
string acsHostName = "accesscontrol.appfabriclabs.com";
string signingCertificate = "MIIDIDCCAgigA... YOUR SIGNING CERT GOES HERE";
//WILL BE USED TO CACHE AND REUSE OBTAINED TOKEN. 
string cachedSwtToken;

Step 2 - Add references to required services and assemblies.

  1. Add reference to System.Web.Extensions.

  2. Add service reference to Management Service. Obtain Management Service URL.(https://<<YOURNAMESPACE>>.accesscontrol.appfabriclabs.com/v2/mgmt/service)

  3. Add the following declarations

     using System.Web;
    using System.Net;
    using System.Data.Services.Client;
    using System.Collections.Specialized;
    using System.Web.Script.Serialization;
    

Step 3 – Create Management Service Proxy

To create Management Service proxy:

  1. Using configuration information collected earlier instantiate the proxy:

     string managementServiceHead = "v2/mgmt/service/";
    string managementServiceEndpoint = string.Format("https://{0}.{1}/{2}", serviceNamespace, acsHostName, managementServiceHead);
    ManagementService managementService = new ManagementService(new Uri(managementServiceEndpoint));
    managementService.SendingRequest += GetTokenWithWritePermission;
    

  2. Implement GetTokenWithWritePermission and its helper methods. It adds SWT OAuth token to Authorization header of HTTP request.

     public static ManagementService CreateManagementServiceClient()
    {
        string managementServiceHead = "v2/mgmt/service/";
        string managementServiceEndpoint = string.Format("https://{0}.{1}/{2}", serviceNamespace, acsHostName, managementServiceHead);
        ManagementService managementService = new ManagementService(new Uri(managementServiceEndpoint));
    
        managementService.SendingRequest += GetTokenWithWritePermission;
    
        return managementService;
    }
    
    public static void GetTokenWithWritePermission(object sender, SendingRequestEventArgs args)
    {
        GetTokenWithWritePermission((HttpWebRequest)args.Request);
    }
    
    /// <summary>
    /// Helper function for the event handler above, adding the SWT token to the HTTP 'Authorization' header. 
    /// The SWT token is cached so that we don't need to obtain a token on every request.
    /// </summary>
    public static void GetTokenWithWritePermission(HttpWebRequest args)
    {
        if (cachedSwtToken == null)
        {
            cachedSwtToken = GetTokenFromACS();
        }
    
        args.Headers.Add(HttpRequestHeader.Authorization, string.Format("OAuth {0}", cachedSwtToken));
    }
    
    /// <summary>
    /// Obtains a SWT token from ACSv2. 
    /// </summary>
    private static string GetTokenFromACS()
    {
        // request a token from ACS
        WebClient client = new WebClient();
        client.BaseAddress = string.Format("https://{0}.{1}", serviceNamespace, acsHostName);
    
        NameValueCollection values = new NameValueCollection();
    
        values.Add("grant_type", "password");
        values.Add("client_id", serviceIdentityUsernameForManagement);
        values.Add("username", serviceIdentityUsernameForManagement);
        values.Add("client_secret", serviceIdentityPasswordForManagement);
        values.Add("password", serviceIdentityPasswordForManagement);
    
        byte[] responseBytes = client.UploadValues("/v2/OAuth2-10/rp/AccessControlManagement", "POST", values);
    
        string response = Encoding.UTF8.GetString(responseBytes);
    
        // Parse the JSON response and return the access token 
        JavaScriptSerializer serializer = new JavaScriptSerializer();
    
        Dictionary<string, object> decodedDictionary = serializer.DeserializeObject(response) as Dictionary<string, object>;
    
        return decodedDictionary["access_token"] as string;
    
    }
    

Step 4 - Add identity provider

To add Identity Provider:

  1. Add your identity provider as issuer (svc is an instance of a proxy to Management Service):

     Issuer issuer = new Issuer
    {
        Name = identityProviderName
    };
    svc.AddToIssuers(issuer);
    svc.SaveChanges(SaveChangesOptions.Batch);
    

  2. Add identity provider:

     IdentityProvider identityProvider = new IdentityProvider()
    {
        DisplayName = identityProviderName,
        Description = identityProviderName,
        WebSSOProtocolType = "WsFederation",
        IssuerId = issuer.Id
    };
    svc.AddObject("IdentityProviders", identityProvider);
    

  3. Create identity provider’s signing key based on the certificate obtained earlier 

     IdentityProviderKey identityProviderKey = new IdentityProviderKey()
    {
        DisplayName = "SampleIdentityProviderKeyDisplayName",
        Type = "X509Certificate",
        Usage = "Signing",
        Value = Convert.FromBase64String(signingCertificate),
        IdentityProvider = identityProvider,
        StartDate = startDate,
        EndDate = endDate,
    };
    
    svc.AddRelatedObject(identityProvider, "IdentityProviderKeys", identityProviderKey);
    

  4. Update identity provider’s sign in address:

     IdentityProviderAddress realm = new IdentityProviderAddress()
    {
        Address = "https://yourdomain.com/sign-in/",
        EndpointType = "SignIn",
        IdentityProvider = identityProvider,
    };
    svc.AddRelatedObject(identityProvider, "IdentityProviderAddresses", realm);
    svc.SaveChanges(SaveChangesOptions.Batch);
    

  5. Make identity provider available to relying parties the Management relying party.

     foreach (RelyingParty rp in svc.RelyingParties)
    {
        // skip the built-in management RP. 
        if (rp.Name != "AccessControlManagement")
        {
            svc.AddToRelyingPartyIdentityProviders(new RelyingPartyIdentityProvider()
            {
                IdentityProviderId = identityProvider.Id,
                RelyingPartyId = rp.Id
            });
        }
    }
    svc.SaveChanges(SaveChangesOptions.Batch);
    

Step 5 - Test your work

To test your work:

  1. Log on to Access Control Service Management Portal.
  2. On the Access Control Service page click on Rule Groups link in  Trust Relationships section.
  3. Click on any of the available rules.
  4. On the Edit Rule Group page click on Add Rule link.
  5. On the Add Claim Rule page choose newly added Identity Provider from the dropdown list in the Claim Issuer section.
  6. Leave the rest with default values.
  7. Click on Save button.
  8. You have just created passthrough rule for the Identity Provider and if no error returned chances you are good to go.

ACSManagementService.zip