如何:使用 ACS 管理服务配置信赖方应用程序
更新时间:2015 年 6 月 19 日
适用于:Azure
应用于
- Microsoft Azure Active Directory 访问控制(也称为访问控制服务或 ACS)
概述
可以使用 ACS 管理门户 (配置 ACS 信赖方应用程序,有关详细信息,请参阅 信赖方应用程序) 或 ACS 管理服务。 如果要构建用于管理 ACS 的自定义用户界面,或者想要自动载入多租户软件即服务的新租户, (SaaS) 解决方案,则使用 ACS 管理服务可以更高效。
使用 ACS 管理服务配置信赖方应用程序的步骤
重要
在执行以下步骤之前,请确保系统满足 ACS 先决条件中汇总的所有 .NET Framework 和平台要求。
若要使用 ACS 管理服务配置信赖方应用程序,请完成以下步骤:
步骤 1 - 收集 ACS 配置信息
步骤 2 - 创建示例控制台应用程序
步骤 3 - 添加对所需服务和程序集的引用
步骤 4 - 实现管理服务客户端
步骤 5 - 添加信赖方应用程序
步骤 1 - 收集 ACS 配置信息
可以使用 ACS 管理门户收集必要的配置信息。 有关如何启动 ACS 管理门户的详细信息,请参阅 ACS 管理门户。
收集 ACS 配置信息
启动 ACS 管理门户。 有关如何启动 ACS 管理门户的详细信息,请参阅 ACS 管理门户。
获取 ACS 管理服务帐户的值。 可以使用默认的 ManagementClient 帐户。 若要查看此值,请在 ACS 管理门户中单击页面左侧树中的“管理”部分下的管理服务。
获取 ACS 管理服务帐户密码的值。 若要查看此值,请执行以下操作:
在 ACS 管理门户中,单击页面左侧树的“管理”部分下的管理服务。
在“管理服务”页上,单击“管理服务帐户”下的 ManagementClient。
在“编辑管理服务帐户”页上的“凭据”下,单击“密码”。
在“编辑管理凭据”页上,复制“密码”字段中的值。
获取 Azure 命名空间的名称。 可以从Azure 门户或 ACS 管理门户的 URL 获取此值。 例如,命名空间 http://contoso.accesscontrol.windows.net名称为 contoso。
获取 ACS 主机名。 通常,它为 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 是控制台应用程序的名称:
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 - 添加信赖方应用程序
在此步骤中,你将使用 SAML 2.0 令牌格式创建一个示例信赖方应用程序, () 默认选项) 没有令牌加密策略 (默认选项) ,Windows Live ID (Microsoft 帐户) 标识提供者 (默认选项) 、600 秒的令牌生存期 (默认选项) ,以及信赖方应用程序的自定义 X.509 令牌签名证书或令牌签名证书访问控制命名空间。
使用访问控制命名空间令牌签名证书添加信赖方应用程序
通过将以下代码添加到 Program 类中的 Main 方法初始化管理服务客户端:
ManagementService svc = CreateManagementServiceClient();
通过将以下代码添加到 Program 类中的 Main 方法添加新的信赖方应用程序(可以称之为“MyRelyingPartyApplication”,如下面的代码所示),并保存更改:
注意
替换“指向你的完整路径。以下代码中的 PFX 文件,其中包含 X.509 证书的有效完整路径。 例如,如果名为 ACS2ClientCertificate.cer 的证书保存在 C:下,则正确的值为“C:\ACS2ClientCertificate.cer”。
将以下代码中的“MyCertificatePassword”替换为 X.509 证书的正确密码。//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);
添加具有专用令牌签名证书的信赖方应用程序
通过将以下代码添加到 Program 类中的 Main 方法初始化管理服务客户端:
ManagementService svc = CreateManagementServiceClient();
通过将以下代码添加到 Program 类,创建 Helper 函数 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; }
通过将以下代码添加到 Program 类中的 Main 方法添加新的信赖方应用程序(可以称之为“MyRelyingPartyApplication”,如下面的代码所示),并保存更改:
注意
替换“指向你的完整路径。以下代码中的 PFX 文件,其中包含 X.509 证书的有效完整路径。 例如,如果名为 ACS2ClientCertificate.cer 的证书保存在 C:下,则正确的值为“C:\ACS2ClientCertificate.cer”。
将以下代码中的“MyCertificatePassword”替换为 X.509 证书的正确密码。//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);