How to: Use ACS Management Service to Configure Certificates and Keys

Updated: June 19, 2015

Applies To: Azure

Applies To

  • Microsoft Azure Active Directory Access Control (also known as Access Control Service or ACS)

Overview

You can configure ACS certificates and keys using either the ACS Management Portal or the ACS Management Service. Working with the ACS Management Service can be more efficient if you are building a custom user interface for managing ACS or if you want to automate the onboarding of a new tenant for multi-tenant Software as a Service (SaaS) solutions.

For more information about using the ACS Management Portal to configure certificates and keys, see Certificates and Keys.

Steps for Configuring Certificates and Keys Using the ACS Management Service

Important

Before performing the following steps, make sure that your system meets all of the .NET framework and platform requirements that are summarized in ACS Prerequisites.

To configure certificates and keys using the ACS Management Service, complete the following steps:

  • Step 1 – Collect ACS Configuration Information

  • Step 2 – Create a Sample Console Application

  • Step 3 – Add References to the Required Services and Assemblies

  • Step 4 – Implement the Management Service Client

  • Step 5 - Install Certificates and Keys

    • Add a Token Signing Certificate for Your Access Control Namespace

    • Add a Token Signing Certificate for a Relying Party Application

    • Add a Token Signing Symmetric Key for Your Access Control Namespace

    • Add a Token Signing Symmetric Key for a Relying Party Application

    • Add a Token Encryption Certificate

    • Add a Token Decryption Certificate

Step 1 – Collect ACS Configuration Information

You can use the ACS Management Portal to collect the necessary configuration information. For more information, see ACS Management Portal.

To collect ACS configuration information

  1. Go to the Microsoft Azure Management Portal (https://manage.WindowsAzure.com), sign in, and then click Active Directory. (Troubleshooting tip: "Active Directory" item is missing or not available)

  2. To manage an Access Control namespace, select the namespace, and then click Manage. (Or, click Access Control Namespaces, select the namespace, and then click Manage.)

  3. Click Management service, click ManagementClient, and then click Password.

  4. Copy the value in the Password field.

  5. Click Management service. Get the value of your service namespace and ACS host name. If your Management Service URL is http://contoso.accesscontrol.windows.net, the namespace is contoso and the host name is accesscontrol.windows.net.

Step 2 – Create a Sample Console Application

In this step you create a sample console application that can run the code for adding your ACS rule groups and rules.

To create a sample console application

  1. Open Visual Studio 2012 and create a new console application project under the Windows installed template.

  2. Add the following code to the Program class and then assign serviceIdentityPasswordForManagement, serviceNamespace, and acsHostName variables to the appropriate configuration information that you collected in the previous step.

    public const string serviceIdentityUsernameForManagement = "ManagementClient";
    public const string serviceIdentityPasswordForManagement = "My Password/Key for ManagementClient";
    public const string serviceNamespace = "MyNameSpaceNoDots";
    public const string acsHostName = "accesscontrol.windows.net";
    public const string acsManagementServicesRelativeUrl = "v2/mgmt/service/";
    static string cachedSwtToken;
    

Step 3 – Add References to the Required Services and Assemblies

In this step you identify and add the required dependencies to the services and assemblies.

To add the required dependencies to the services and assemblies

  1. Right-click References, click Add Reference, and add a reference to System.Web.Extensions.

    Note

    You might have to right-click your sample console application name in the Solution Explorer, select Properties, and change the target framework of your sample application from .NET Framework 4 Client Profile (assigned by default when you create a new console application) to .NET Framework 4.

  2. Right-click Service References, click Add Service Reference, and add a service reference to the Management Service. The Management Service URL is unique to your namespace and looks similar to the following:

    https://YOURNAMESPACE.accesscontrol.windows.net/v2/mgmt/service

  3. Add the following declarations, where MyConsoleApplication is the name of your console application and MyServiceReference is the name of your service reference:

    using System;
    using System.IO;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Web;
    using System.Net;
    using System.Data.Services.Client;
    using System.Collections.Specialized;
    using System.Web.Script.Serialization;
    using System.Globalization;
    using System.Security.Cryptography;
    using System.Security.Cryptography.X509Certificates; 
    using MyConsoleApplication.MyServiceReference;
    

Step 4 – Implement the Management Service Client

In this step you implement the Management Service client.

To implement the Management Service client

  1. Add the following method to the Program class:

       public static ManagementService CreateManagementServiceClient()
            {
                string managementServiceEndpoint = String.Format(CultureInfo.InvariantCulture, "https://{0}.{1}/{2}",
                    serviceNamespace,
                    acsHostName,
                    acsManagementServicesRelativeUrl);
                ManagementService managementService = new ManagementService(new Uri(managementServiceEndpoint));
    
                managementService.SendingRequest += GetTokenWithWritePermission;
    
                return managementService;
            }
    
  2. Add the GetTokenWithWritePermission method and its helper methods to the Program class. GetTokenWithWritePermission and its helpers add the SWT OAuth token to the Authorization header of the HTTP request.

    public static void GetTokenWithWritePermission(object sender, SendingRequestEventArgs args)
            {
                GetTokenWithWritePermission((HttpWebRequest)args.Request);
            }
    
            public static void GetTokenWithWritePermission(HttpWebRequest args)
            {
                if (cachedSwtToken == null)
                {
                    cachedSwtToken = GetTokenFromACS();
                }
    
                args.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + cachedSwtToken);
            }
    
            private static string GetTokenFromACS()
            {
                //
                // Request a token from ACS
                //
                WebClient client = new WebClient();
                client.BaseAddress = string.Format(CultureInfo.CurrentCulture, 
                                                   "https://{0}.{1}", 
                                                   serviceNamespace, 
                                                   acsHostName);
    
                NameValueCollection values = new NameValueCollection();
                values.Add("grant_type", "client_credentials");
                values.Add("client_id", serviceIdentityUsernameForManagement);
                values.Add("client_secret", serviceIdentityPasswordForManagement);
                values.Add("scope", client.BaseAddress + acsManagementServicesRelativeUrl);
    
                byte[] responseBytes = client.UploadValues("/v2/OAuth2-13", "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 5 – Add Certificates and Keys

Add a Token Signing Certificate for Your Access Control namespace

In this example, you create an X.509 signing certificate for your Access Control namespace.

To add a token signing certificate for all relying party applications in the Access Control namespace

  1. Initialize the Management Service client by adding the following code to the Main method in the Program class:

    ManagementService svc = CreateManagementServiceClient();
    
  2. Create a ReadBytesFromPfxFile helper function to read bytes from your X.509 certificate by adding the following code to the Program class:

    //Helper function to read bytes from your .pfx file
    
            public static byte[] ReadBytesFromPfxFile(string pfxFileName, string protectionPassword)
            {
                byte[] signingCertificate;
                using (FileStream stream = File.OpenRead(pfxFileName))
                {
                    using (BinaryReader br = new BinaryReader(stream))
                    {
                        signingCertificate = br.ReadBytes((int)stream.Length);
                    }
                }
                return signingCertificate;
            }
    
  3. To add a token signing X.509 certificate, add the following code to the Main method in the Program class:

    Note

    Replace "Full path to your .PFX file" with the valid full path to your X.509 certificate. For example, "C:\ ACS2ClientCertificate.pfx".

    Replace “MyCertificatePassword” with the password for your X.509 certificate.

    X509Certificate2 cert = new X509Certificate2(@"Full path to your .PFX file", “MyCertificatePassword”);
    
                DateTime startDate, endDate;
                startDate = cert.NotBefore.ToUniversalTime();
                endDate = cert.NotAfter.ToUniversalTime();
               string pfxFileName = @"Full path to your .PFX file";
                string pfxPassword = @"MyCertificatePassword";
    
    byte[] signingCertificate = ReadBytesFromPfxFile(pfxFileName, pfxPassword);
    
    ServiceKey serviceKey = new ServiceKey()
                {
                    Type = "X509Certificate",
                    Usage = "Signing",
                    Value = signingCertificate,
                      Password = Encoding.UTF8.GetBytes("MyCertificatePassword"),
                      IsPrimary = false,
                    StartDate = startDate.ToUniversalTime(),
                    EndDate = endDate.ToUniversalTime()
                };
                svc.AddToServiceKeys(serviceKey);
                svc.SaveChanges(SaveChangesOptions.Batch);
    

Add a Token Signing Certificate for a Relying Party Application

In this example, you create an X.509 signing certificate that is assigned to a particular relying party application.

How to add a token signing certificate for a relying party application

  1. Initialize the Management Service client by adding the following code to the Main method in the Program class:

    ManagementService svc = CreateManagementServiceClient();
    
  2. Create a helper function ReadBytesFromPfxFile to read bytes out of your X.509 certificate by adding the following code to the Program class:

    //Helper function to read bytes from your .pfx file
    
            public static byte[] ReadBytesFromPfxFile(string pfxFileName, string protectionPassword)
            {
                byte[] signingCertificate;
                using (FileStream stream = File.OpenRead(pfxFileName))
                {
                    using (BinaryReader br = new BinaryReader(stream))
                    {
                        signingCertificate = br.ReadBytes((int)stream.Length);
                    }
                }
                return signingCertificate;
            }
    
  3. To add a token signing X.509 certificate, add the following code to the Main method in the Program class:

    Note

    Replace "Full path to your .PFX file" with the full path to your X.509 certificate. For example, "C:\ ACS2ClientCertificate.pfx".

    Replace “MyCertificatePassword” with the password for your X.509 certificate.

    Replace “MyRelyingPartyApplication” with the name of the relying party application.

    //Select an existing Relying Party Application by its name
    
                RelyingParty relyingParty = svc.RelyingParties.Where(m => m.Name == "MyRelyingPartyApplication").Single();
    
               // Add a signing certificate
    
               X509Certificate2 cert = new X509Certificate2(@"Full path to your .PFX file", "MyCertificatePassword");
               DateTime startDate, endDate;
               startDate = cert.NotBefore.ToUniversalTime();
               endDate = cert.NotAfter.ToUniversalTime();
    
               string pfxFileName = @"Full path to your .PFX file";
               string pfxPassword = "MyCertificatePassword";
    
                byte[] signingCertificate = ReadBytesFromPfxFile(pfxFileName, pfxPassword);
    
               RelyingPartyKey relyingPartyKey = new RelyingPartyKey()
                {
                    StartDate = startDate.ToUniversalTime(),
                   EndDate = endDate.ToUniversalTime(),
                    Type = "X509Certificate",
                    Usage = "Signing",
                    IsPrimary = true,
                    Value = signingCertificate,
                   Password = Encoding.UTF8.GetBytes("MyCertificatePassword")
                };
    
    // Add the new signing certificate to the selected Relying Party Application
    
                svc.AddRelatedObject(relyingParty, "RelyingPartyKeys", relyingPartyKey);
    
    
    
                //Save your relying party application
    
                svc.SaveChanges(SaveChangesOptions.Batch);
    

Add a Token Signing Symmetric Key for Your Access Control namespace

In this example, you assign this signing symmetric key to your Access Control namespace.

To add a token signing symmetric key for your Access Control namespace

  1. Initialize the Management Service client by adding the following code to the Main method in the Program class:

    ManagementService svc = CreateManagementServiceClient();
    
  2. To add a token signing symmetric key add the following code to the Main method in the Program class:

           string symKey = "SampleTokenSigningSymmetricKey";
                DateTime startDate, endDate;
                startDate = DateTime.UtcNow;
                endDate = DateTime.MaxValue;
    
                ServiceKey serviceKey = new ServiceKey()
                {
                    
                    Type = "Symmetric",
                    Usage = "Signing",
                    Value = Encoding.UTF8.GetBytes(symKey),
                    StartDate = startDate.ToUniversalTime(),
                    EndDate = endDate.ToUniversalTime()
                };
                svc.AddToServiceKeys(serviceKey);
                svc.SaveChanges(SaveChangesOptions.Batch);
    

Add a Token Signing Symmetric Key for a Relying Party Application

In this example, you assign your new signing symmetric key to a particular relying party application.

To add a token signing symmetric key for a relying party application

  1. Initialize the Management Service client by adding the following code to the Main method in the Program class:

    ManagementService svc = CreateManagementServiceClient();
    
  2. To add a token signing symmetric key, add the following code to the Main method in the Program class:

          //Select a relying party application
    
                RelyingParty relyingParty = svc.RelyingParties.Where(m => m.Name == "MyRelyingPartyApplication").Single();
    
               // Create a symmetric key
    
                string symKey = "SampleTokenSigningSymmetricKey";
                DateTime startDate, endDate;
                startDate = DateTime.UtcNow;
                endDate = DateTime.MaxValue;
    
                RelyingPartyKey relyingPartyKey = new RelyingPartyKey()
                {
    
                    Type = "Symmetric",
                    Usage = "Signing",
                    Value = Encoding.UTF8.GetBytes(symKey),
                    StartDate = startDate.ToUniversalTime(),
                    EndDate = endDate.ToUniversalTime()
                };
    
                //Assign this symmetric key to the selected relying party application 
    
                svc.AddRelatedObject(relyingParty, "RelyingPartyKeys", relyingPartyKey);
    
                   //Save your symmetric key
    
                svc.SaveChanges(SaveChangesOptions.Batch);        
    

Add a Token Encryption Certificate

In this example, you add an X.509 token encryption certificate for a particular relying party application.

To add a token encryption certificate for a relying party application

  1. Initialize the Management Service client by adding the following code to the Main method in the Program class:

    ManagementService svc = CreateManagementServiceClient();
    
  2. To add a token encryption X.509 certificate, add the following code to the Main method in the Program class:

    Note

    Replace "Full path to your .CER file" with the full path to an X.509 certificate. For example, "C:\ ACS2ClientCertificate.cer".

    Replace “MyCertificatePassword” with the password for the X.509 certificate.

    Replace “MyRelyingPartyApplication” with the name of a relying party application.

    //Select a relying party application
    
                RelyingParty relyingParty = svc.RelyingParties.Where(m => m.Name == "MyRelyingPartyApplication").Single();
    
               // Add an encryption certificate
    
                X509Certificate2 cert = new X509Certificate2(@"Full path to your .CER file");
                DateTime startDate, endDate; 
                  startDate = cert.NotBefore;
                  endDate = cert.NotAfter;
    
                RelyingPartyKey relyingPartyKey = new RelyingPartyKey()
                {
                    Type = "X509Certificate",
                    Usage = "Encrypting",
                    Value = cert.GetRawCertData(),
                    StartDate = startDate.ToUniversalTime(),
                    EndDate = endDate.ToUniversalTime()
                };
    
                //Assign this encryption certificate to the selected relying party application 
    
                svc.AddRelatedObject(relyingParty, "RelyingPartyKeys", relyingPartyKey);
    
                   //Save your encryption certificate
    
                svc.SaveChanges(SaveChangesOptions.Batch);     
    

Add a Token Decryption Certificate

In this example, you add an X.509 token decryption certificate assigned to your Access Control namespace.

To add a token signing certificate for all relying party applications in the Access Control namespace

  1. Initialize the Management Service client by adding the following code to the Main method in the Program class:

    ManagementService svc = CreateManagementServiceClient();
    
  2. Create a helper function ReadBytesFromPfxFile to read bytes out of your X.509 certificate by adding the following code to the Program class:

    //Helper function to read bytes from your .pfx file
    
            public static byte[] ReadBytesFromPfxFile(string pfxFileName, string protectionPassword)
            {
                byte[] decryptionCertificate;
                using (FileStream stream = File.OpenRead(pfxFileName))
                {
                    using (BinaryReader br = new BinaryReader(stream))
                    {
                        decryptionCertificate = br.ReadBytes((int)stream.Length);
                    }
                }
                return decryptingCertificate;
            }
    
  3. To add a token signing X.509 certificate, add the following code to the Main method in the Program class:

    Note

    Substitute "Full path to your .PFX file" in the code below with the valid full path to your X.509 certificate. For example, if a certificate called ACS2ClientCertificate.pfx is saved under C:, the correct value is "C:\ ACS2ClientCertificate.pfx".

    Substitute “MyCertificatePassword” in the code below with the correct password for your X.509 certificate.

    X509Certificate2 cert = new X509Certificate2(@"Full path to your .PFX file", “MyCertificatePassword”);
    
                DateTime startDate, endDate;
                startDate = cert.NotBefore.ToUniversalTime();
                endDate = cert.NotAfter.ToUniversalTime();
               string pfxFileName = @"Full path to your .PFX file";
                string pfxPassword = @"MyCertificatePassword";
    
    byte[] decryptionCertificate = ReadBytesFromPfxFile(pfxFileName, pfxPassword);
    
    ServiceKey serviceKey = new ServiceKey()
                {
                    Type = "X509Certificate",
                    Usage = "Encrypting",
                    Value = decryptionCertificate,
                      Password = Encoding.UTF8.GetBytes("MyCertificatePassword"),
                    StartDate = startDate.ToUniversalTime(),
                    EndDate = endDate.ToUniversalTime()
                };
                svc.AddToServiceKeys(serviceKey);
                svc.SaveChanges(SaveChangesOptions.Batch);
    

See Also

Concepts

ACS How To's