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
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)
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.)
Click Management service, click ManagementClient, and then click Password.
Copy the value in the Password field.
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
Open Visual Studio 2012 and create a new console application project under the Windows installed template.
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
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.
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
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
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; }
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
Initialize the Management Service client by adding the following code to the Main method in the Program class:
ManagementService svc = CreateManagementServiceClient();
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; }
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
Initialize the Management Service client by adding the following code to the Main method in the Program class:
ManagementService svc = CreateManagementServiceClient();
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; }
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
Initialize the Management Service client by adding the following code to the Main method in the Program class:
ManagementService svc = CreateManagementServiceClient();
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
Initialize the Management Service client by adding the following code to the Main method in the Program class:
ManagementService svc = CreateManagementServiceClient();
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
Initialize the Management Service client by adding the following code to the Main method in the Program class:
ManagementService svc = CreateManagementServiceClient();
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
Initialize the Management Service client by adding the following code to the Main method in the Program class:
ManagementService svc = CreateManagementServiceClient();
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; }
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);