如何:使用 ACS 管理服务配置证书和密钥
更新时间:2015 年 6 月 19 日
适用于:Azure
应用于
- Microsoft Azure Active Directory 访问控制(也称为访问控制服务或 ACS)
概述
可以使用 ACS 管理门户或 ACS 管理服务配置 ACS 证书和密钥。 如果要构建用于管理 ACS 的自定义用户界面,或者想要自动载入多租户软件即服务的新租户, (SaaS) 解决方案,则使用 ACS 管理服务可以更高效。
有关使用 ACS 管理门户配置证书和密钥的详细信息,请参阅 证书和密钥。
使用 ACS 管理服务配置证书和密钥的步骤
重要
在执行以下步骤之前,请确保系统满足 ACS 先决条件中汇总的所有 .NET Framework 和平台要求。
若要使用 ACS 管理服务配置证书和密钥,请完成以下步骤:
步骤 1 - 收集 ACS 配置信息
步骤 2 - 创建示例控制台应用程序
步骤 3 - 添加对所需服务和程序集的引用
步骤 4 - 实现管理服务客户端
步骤 5 - 安装证书和密钥
为 Access Control 命名空间添加令牌签名证书
为信赖方应用程序添加令牌签名证书
为 Access Control 命名空间添加令牌签名对称密钥
为信赖方应用程序添加令牌签名对称密钥
添加令牌加密证书
添加令牌解密证书
步骤 1 - 收集 ACS 配置信息
可以使用 ACS 管理门户收集必要的配置信息。 有关详细信息,请参阅 ACS 管理门户。
收集 ACS 配置信息
转到Microsoft Azure管理门户 (https://manage.WindowsAzure.com) 登录,然后单击“Active Directory”。 (故障排除提示: “Active Directory”项缺失或不可用)
若要管理访问控制命名空间,请选择该命名空间,然后单击“管理”。 (或者,单击“访问控制命名空间”,选择命名空间,然后单击“管理”。)
单击“管理服务”,单击“ManagementClient”,然后单击“密码”。
复制“密码”字段中的值。
单击“管理服务”。 获取服务命名空间和 ACS 主机名的值。 如果管理服务 URL 为 http://contoso.accesscontrol.windows.net,则命名空间为 contoso ,主机名 accesscontrol.windows.net。
步骤 2 - 创建示例控制台应用程序
在此步骤中,你将创建一个示例控制台应用程序,该应用程序可以运行代码以添加 ACS 规则组和规则。
创建示例控制台应用程序
打开 Visual Studio 2012,并在已安装Windows模板下创建新的控制台应用程序项目。
将下面的代码添加到 Program 类,然后为 serviceIdentityPasswordForManagement、serviceNamespace 和 acsHostName 变量分配你在上一步收集的相应配置信息。
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;
步骤 3 - 添加对所需服务和程序集的引用
在此步骤中,你将确定所需的依赖项并将其添加到服务和程序集中。
将所需的依赖项添加到服务和程序集中
右键单击“引用”,单击“添加引用”,然后添加对 System.Web.Extensions 的引用。
注意
你可能需要在解决方案资源管理器中右键单击示例控制台应用程序名称,选择“属性”,并将示例应用程序的目标框架从 .NET Framework 4 Client Profile(在创建新的控制台应用程序时默认分配)更改为 .NET Framework 4。
右键单击“服务引用”,单击“添加服务引用”,然后添加对管理服务的服务引用。 管理服务 URL 对命名空间是唯一的,如下所示:
https:// YOURNAMESPACE.accesscontrol.windows.net/v2/mgmt/service
添加以下声明,其中 MyConsoleApplication 是控制台应用程序的名称,而 MyServiceReference 是服务引用的名称:
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;
步骤 4 - 实现管理服务客户端
在此步骤中,你将实现管理服务客户端。
实现管理服务客户端
将以下方法添加到 Program 类:
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; }
向 Program 类中添加 GetTokenWithWritePermission 方法及其帮助程序方法。 GetTokenWithWritePermission 及其帮助程序将 SWT OAuth 令牌添加到 HTTP 请求的 Authorization 标头。
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; }
步骤 5 - 添加证书和密钥
为访问控制命名空间添加令牌签名证书
在此示例中,将为访问控制命名空间创建 X.509 签名证书。
为访问控制命名空间中的所有信赖方应用程序添加令牌签名证书
通过将以下代码添加到 Program 类中的 Main 方法初始化管理服务客户端:
ManagementService svc = CreateManagementServiceClient();
通过将以下代码添加到 Program 类,创建 ReadBytesFromPfxFile 帮助程序函数以从 X.509 证书读取字节:
//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; }
若要添加 X.509 令牌签名证书,请将以下代码添加到 Program 类中的 Main 方法:
注意
将“Full path to your .PFX file”替换为 X.509 证书的有效完整路径。 例如,“C:\ACS2ClientCertificate.pfx”。
将“MyCertificatePassword”替换为 X.509 证书的密码。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);
为信赖方应用程序添加令牌签名证书
在此示例中,你将要创建一个分配给特定信赖方应用程序的 X.509 签名证书。
如何为信赖方应用程序添加令牌签名证书
通过将以下代码添加到 Program 类中的 Main 方法初始化管理服务客户端:
ManagementService svc = CreateManagementServiceClient();
通过将以下代码添加到 Program 类,创建用于从 X.509 证书读取字节的帮助器函数 ReadBytesFromPfxFile:
//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; }
若要添加 X.509 令牌签名证书,请将以下代码添加到 Program 类中的 Main 方法:
注意
将“Full path to your .PFX file”替换为 X.509 证书的完整路径。 例如,“C:\ACS2ClientCertificate.pfx”。
将“MyCertificatePassword”替换为 X.509 证书的密码。 将“MyRelyingPartyApplication”替换为信赖方应用程序的名称。//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);
为访问控制命名空间添加令牌签名对称密钥
在此示例中,请将此签名对称密钥分配给访问控制命名空间。
为访问控制命名空间添加令牌签名对称密钥
通过将以下代码添加到 Program 类中的 Main 方法初始化管理服务客户端:
ManagementService svc = CreateManagementServiceClient();
若要添加令牌签名对称密钥,请将以下代码添加到 Program 类中的 Main 方法:
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);
为信赖方应用程序添加令牌签名对称密钥
在此示例中,你要将新的签名对称密钥分配到特定的信赖方应用程序。
为信赖方应用程序添加令牌签名对称密钥
通过将以下代码添加到 Program 类中的 Main 方法初始化管理服务客户端:
ManagementService svc = CreateManagementServiceClient();
若要添加令牌签名对称密钥,请将以下代码添加到 Program 类中的 Main 方法:
//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);
添加令牌加密证书
在此示例中,你将要为特定的信赖方应用程序添加 X.509 令牌加密证书。
为信赖方应用程序添加令牌加密证书
通过将以下代码添加到 Program 类中的 Main 方法初始化管理服务客户端:
ManagementService svc = CreateManagementServiceClient();
若要添加 X.509 令牌加密证书,请将以下代码添加到 Program 类中的 Main 方法:
注意
将“Full path to your .CER file”替换为 X.509 证书的完整路径。 例如,“C:\ ACS2ClientCertificate.cer”.
将“MyCertificatePassword”替换为 X.509 证书的密码。 将“MyRelyingPartyApplication”替换为信赖方应用程序的名称。//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);
添加令牌解密证书
在此示例中,将添加分配给访问控制命名空间的 X.509 令牌解密证书。
为访问控制命名空间中的所有信赖方应用程序添加令牌签名证书
通过将以下代码添加到 Program 类中的 Main 方法初始化管理服务客户端:
ManagementService svc = CreateManagementServiceClient();
通过将以下代码添加到 Program 类,创建用于从 X.509 证书读取字节的帮助器函数 ReadBytesFromPfxFile:
//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; }
若要添加 X.509 令牌签名证书,请将以下代码添加到 Program 类中的 Main 方法:
注意
替换“指向你的完整路径。以下代码中的 PFX 文件,其中包含 X.509 证书的有效完整路径。 例如,如果名为 ACS2ClientCertificate.pfx 的证书保存在 C:下,则正确的值为“C:\ACS2ClientCertificate.pfx”。
将以下代码中的“MyCertificatePassword”替换为 X.509 证书的正确密码。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);