How to: Use ACS Management Service to Configure Relying Party Applications

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 relying party applications using either the ACS Management Portal (for more information, see Relying Party Applications) 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.

Steps for Configuring Relying Party Applications 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 relying party applications 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 – Add a Relying Party Application

Step 1 – Collect ACS Configuration Information

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

To collect ACS configuration information

  1. Launch the ACS Management Portal. For more information about how to launch the ACS Management Portal, see ACS Management Portal.

  2. Get the value of the ACS management service account. You can use the default ManagementClient account. To view this value, in the ACS Management Portal, click Management service under the Administration section in the tree on the left-hand side of the page.

  3. Get the value of the ACS Management Service account password. To view this value, do the following:

    1. In the ACS Management Portal, click Management service under the Administration section in the tree on the left-hand side of the page.

    2. On the Management Service page, click ManagementClient under Management Service Accounts.

    3. On the Edit Management Service Account page, under Credentials, click Password.

    4. On the Edit Management Credential page, copy the value in the Password field.

  4. Get the name of your Azure namespace. You can get this value from the Azure portal or from the URL of your ACS Management Portal. For example, in http://contoso.accesscontrol.windows.net, the namespace name is contoso.

  5. Get the ACS hostname. Usually, it 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 2012and 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:

    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 a Relying Party Application

In this step you create a sample relying party application with a SAML 2.0 token format (default option), no token encryption policy (default option), associated with a Windows Live ID (Microsoft account) identity provider (default option), 600 seconds of token lifetime (default option), and either a custom X.509 token signing certificate for your relying party application or a token signing certificate for the Access Control namespace.

To add a relying party application with a Access Control namespace token signing certificate

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

    ManagementService svc = CreateManagementServiceClient();
    
  2. Add your new relying party application (you can call it “MyRelyingPartyApplication”, as shown in the code below) and save the changes by adding 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.cer is saved under C:, the correct value is "C:\ ACS2ClientCertificate.cer".

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

                //Create Relying Party Application
    
                RelyingParty relyingParty = new RelyingParty()
                {
                    Name = "MyRelyingPartyApplication",
                    AsymmetricTokenEncryptionRequired = false,
                    TokenType = "SAML_2_0",
                    TokenLifetime = 3600
                };
    
                svc.AddToRelyingParties(relyingParty);
    
    
                //Create the Realm Address
    
                RelyingPartyAddress realmAddress = new RelyingPartyAddress()
                {
                    Address = "http://TestRelyingParty.com/Realm",
                    EndpointType = "Realm"
                };
    
                svc.AddRelatedObject(relyingParty, "RelyingPartyAddresses", realmAddress);
    
                //Create the Return URL Address
    
                RelyingPartyAddress replyAddress = new RelyingPartyAddress()
                {
                    Address = "http://TestRelyingParty.com/Reply",
                    EndpointType = "Reply"
                };
    
                svc.AddRelatedObject(relyingParty, "RelyingPartyAddresses", replyAddress);
    
              // Create a Rule Group for This Relying Party Application
    
                RuleGroup rg = new RuleGroup();
                rg.Name = "SampleRuleGroup For " + relyingParty.Name;
                svc.AddToRuleGroups(rg);
    
                // Assign This New Rule Group to Your New Relying Party Application
    
                RelyingPartyRuleGroup relyingPartyRuleGroup = new RelyingPartyRuleGroup();
    
                svc.AddToRelyingPartyRuleGroups(relyingPartyRuleGroup);
                svc.AddLink(relyingParty, "RelyingPartyRuleGroups", relyingPartyRuleGroup);
                svc.AddLink(rg, "RelyingPartyRuleGroups", relyingPartyRuleGroup);
    
    
                //Save Your New Relying Party Application
    
                svc.SaveChanges(SaveChangesOptions.Batch);
    

To add a relying party application with a dedicated token signing certificate

  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. Add your new relying party application (you can call it “MyRelyingPartyApplication”, as shown in the code below) and save the changes by adding 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.cer is saved under C:, the correct value is "C:\ ACS2ClientCertificate.cer".

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

                //Create Relying Party Application
    
                RelyingParty relyingParty = new RelyingParty()
                {
                    Name = "MyRelyingPartyApplication",
                    AsymmetricTokenEncryptionRequired = false,
                    TokenType = "SAML_2_0",
                    TokenLifetime = 3600
                };
    
                svc.AddToRelyingParties(relyingParty);
    
    
                //Create the Realm Address
    
                RelyingPartyAddress realmAddress = new RelyingPartyAddress()
                {
                    Address = "http://TestRelyingParty.com/Realm",
                    EndpointType = "Realm"
                };
    
                svc.AddRelatedObject(relyingParty, "RelyingPartyAddresses", realmAddress);
    
                //Create the Return URL Address
    
                RelyingPartyAddress replyAddress = new RelyingPartyAddress()
                {
                    Address = "http://TestRelyingParty.com/Reply",
                    EndpointType = "Reply"
                };
    
                svc.AddRelatedObject(relyingParty, "RelyingPartyAddresses", replyAddress);
    
                //Create 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")
                };
                svc.AddRelatedObject(relyingParty, "RelyingPartyKeys", relyingPartyKey);
    
    
              // Create a Rule Group for This Relying Party Application
    
                RuleGroup rg = new RuleGroup();
                rg.Name = "SampleRuleGroup For " + relyingParty.Name;
                svc.AddToRuleGroups(rg);
    
                // Assign This New Rule Group to Your New Relying Party Application
    
                RelyingPartyRuleGroup relyingPartyRuleGroup = new RelyingPartyRuleGroup();
    
                svc.AddToRelyingPartyRuleGroups(relyingPartyRuleGroup);
                svc.AddLink(relyingParty, "RelyingPartyRuleGroups", relyingPartyRuleGroup);
                svc.AddLink(rg, "RelyingPartyRuleGroups", relyingPartyRuleGroup);
    
    
                //Save Your New Relying Party Application
    
                svc.SaveChanges(SaveChangesOptions.Batch);
    

See Also

Concepts

ACS How To's