使用 AD FS 2016 或更高版本的 OAuth 公共客户端生成本机客户端应用程序Build a native client application using OAuth public clients with AD FS 2016 or later

概述Overview

本文介绍如何生成与受 AD FS 2016 或更高版本保护的 Web API 交互的本机应用程序。This article shows how to build a native application that interacts with a Web API protected by AD FS 2016 or later.

  1. .Net TodoListClient WPF 应用程序使用 Active Directory 身份验证库 (ADAL) 通过 OAuth 2.0 协议从 Azure Active Directory (Azure AD) 获取 JWT 访问令牌The .Net TodoListClient WPF application uses the Active Directory Authentication Library (ADAL) to obtain a JWT access token from Azure Active Directory (Azure AD) through the OAuth 2.0 protocol
  2. 调用 TodoListService web API 的/todolist) 终结点时,访问令牌用作持有者令牌以对用户进行身份验证。The access token is used as a bearer token to authenticate the user when calling the /todolist endpoint of the TodoListService web API. 我们将使用此处 Azure AD 的应用程序示例,然后在 AD FS 2016 或更高版本中对其进行修改。We will be using the application example for Azure AD here and then modify it for AD FS 2016 or later.

应用程序概述

先决条件Pre-requisites

下面列出了在完成本文档之前需要满足的先决条件。The following are a list of pre-requisites that are required prior to completing this document. 本文档假定已安装 AD FS 并且已创建 AD FS 场。This document assumes that AD FS has been installed and an AD FS farm has been created.

  • GitHub 客户端工具GitHub client tools
  • Windows Server 2016 或更高版本中的 AD FSAD FS in Windows Server 2016 or later
  • Visual Studio 2013 或更高版本Visual Studio 2013 or later

创建示例演练Creating the sample walkthrough

在 AD FS 中创建应用程序组Create the application group in AD FS

  1. 在 AD FS 管理 "中,右键单击"应用程序组",然后选择"添加应用程序组"。In AD FS Management, right-click on Application Groups and select Add Application Group.

  2. 在应用程序组向导上,为 "名称" 输入你喜欢的任何名称,例如 NativeToDoListAppGroup。On the Application Group Wizard, for the name enter any name you prefer, e.g. NativeToDoListAppGroup. 选择用于访问 WEB API 模板的本机应用程序Select the Native application accessing a web API template . 单击“下一步”。Click Next. 添加应用程序组Add application group

  3. 在 "本机应用程序" 页上,记下 AD FS 生成的标识符。On the Native application page, note the identifier generated by AD FS. 这是 AD FS 将识别其公共客户端应用程序的 id。This is the id with which AD FS will recognize the public client app. 复制 "客户端标识符" 值。Copy the Client Identifier value. 稍后将在应用程序代码中将其用作ida: ClientId的值。It will be used later as the value for ida:ClientId in the application code. 如果需要,可以在此处提供任何自定义标识符。If you wish you can give any custom identifier here. 重定向 URI 是任意值,例如,put https://ToDoListClient  本机应用The redirect URI is any arbitrary value, example, put https://ToDoListClient Native app

  4. 在 "配置 WEB api " 页上,设置 Web api 的标识符值。On the Configure Web API page, set the identifier value for the Web API. 在此示例中,此值应为要在其中运行 Web 应用的SSL URL的值。For this example, this should be the value of the SSL URL where the Web App is supposed to be running. 可以通过单击解决方案中的 TooListServer 项目的属性来获取此值。You can get this value by clicking on the properties of the TooListServer project in the solution. 稍后将在本机客户端应用程序App.config文件中用作todo: TodoListResourceId值,也可以用作todo: TodoListBaseAddressThis will be later used as the todo:TodoListResourceId value in App.config file of the native client application and also as the todo:TodoListBaseAddress. Web APIWeb API

  5. 浏览 "应用访问控制策略",并将应用程序权限配置为使用默认值。Go through the Apply Access Control Policy and Configure Application Permissions with the default values in place. "摘要" 页的外观应如下所示。The summary page should look like below. 摘要Summary

单击 "下一步",然后完成向导。Click next and then complete the wizard.

将 NameIdentifier 声明添加到颁发的声明列表Add the NameIdentifier claim to the list of claims issued

演示应用程序在不同位置使用 NameIdentifier 声明中的值。The demo application uses the value in NameIdentifier claim at various places. 与 Azure AD 不同,AD FS 默认情况下不发出 NameIdentifier 声明。Unlike Azure AD, AD FS does not issue a NameIdentifier claim by default. 因此,我们需要添加声明规则以颁发 NameIdentifier 声明,使应用程序可以使用正确的值。Therefore, we need to add a claim rule to issue the NameIdentifier claim so that the application can use the correct value. 在此示例中,用户的给定名称将作为令牌中用户的 NameIdentifier 值发出。In this example, the given name of the user is issued as the NameIdentifier value for the user in the token. 若要配置声明规则,请打开刚刚创建的应用程序组,然后双击 Web API。To configure the claim rule, open the application group just created, and double click on the Web API. 选择 "颁发转换规则" 选项卡,然后单击 "添加规则" 按钮。Select the Issuance Transform Rules tab and then click on Add Rule button. 在声明规则的类型中,选择 "自定义声明规则",然后添加声明规则,如下所示。In the type of claim rule, choose Custom claim rule and then add the claim rule as shown below.

c:[Type == "https://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"]
 => issue(store = "Active Directory", types = ("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"), query = ";givenName;{0}", param = c.Value);

NameIdentifier 声明规则

修改应用程序代码Modify the application code

本部分介绍如何在 Visual Studio 中下载并修改示例 Web API。This section discusses how to download the sample Web API and modify it in Visual Studio. 我们将使用此处的 Azure AD 示例。We will be using the Azure AD sample that is here.

若要下载示例项目,请使用 Git Bash,并键入以下内容:To download the sample project, use Git Bash and type the following:

git clone https://github.com/Azure-Samples/active-directory-dotnet-native-desktop

修改 ToDoListClientModify ToDoListClient

解决方案中的此项目表示 native client 应用程序。This project in the solution represents the native client application. 我们需要确保客户端应用程序知道:We need to make sure that the client application knows:

  1. 需要在何处进行用户身份验证?Where to go to get the user authenticated when required?
  2. 客户端需要向身份验证机构提供什么 ID (AD FS) ?What is the ID that client needs to provide to the authenticating authority (AD FS)?
  3. 需要访问令牌的资源的 ID 是多少?What is the ID of the resource that we are asking the access token for?
  4. Web API 的基址是什么?What is the base address of the Web API?

需要进行以下代码更改,以便将上述信息获取给 native client 应用程序。The following code changes are needed in order to get the above information to the native client application.

App.configApp.config

  • 添加密钥ida:权威,其中包含描述 AD FS 服务的值。Add the key ida:Authority with the value depicting the AD FS service. 例如: https://fs.contoso.com/adfs/For example, https://fs.contoso.com/adfs/

  • 在 AD FS 中创建应用程序组期间,在 "本机应用程序" 页中修改ida: ClientId密钥,其值来自 "客户端标识符"。Modify ida:ClientId key with the value from Client Identifier in the Native Application page during the Application Group creation in AD FS. 例如,3f07368b-6efd-4f50-a330-d93853f4c855For example, 3f07368b-6efd-4f50-a330-d93853f4c855

  • 在 AD FS 中创建应用程序组期间 ,在 " 配置 Web API " 页中修改todo: todo: TodoListResourceId的值。Modify the todo:todo:TodoListResourceId with the value from Identifier in the Configure Web API page during the Application Group creation in AD FS. 例如: https://localhost:44321/For example, https://localhost:44321/

  • 在 AD FS 中创建应用程序组期间,通过 "配置 WEB API " 页中的 "标识符" 中的值修改todo: TodoListBaseAddressModify the todo:TodoListBaseAddress with the value from Identifier in the Configure Web API page during the Application Group creation in AD FS. 例如: https://localhost:44321/For example, https://localhost:44321/

  • 在 AD FS 中创建应用程序组期间,将ida: RedirectUri的值设置为 "本机应用程序" 页中的 "重定向 URI " 中的值。Set the value of ida:RedirectUri with the value from Redirect URI in the Native application page during the Application Group creation in AD FS. 例如: https://ToDoListClientFor example, https://ToDoListClient

  • 为了便于阅读,你可以删除/注释 ida 的密钥 :租户ida: AADInstanceFor ease of reading you can remove / comment the key for ida:Tenant and ida:AADInstance.

    应用配置

MainWindow.xaml.csMainWindow.xaml.cs

  • 备注 aadInstance 的行,如下所示Comment the line for aadInstance as below

    // private static string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];

  • 为授权机构添加值,如下所示Add the value for authority as below

    private static string authority = ConfigurationManager.AppSettings["ida:Authority"];

  • 删除用于从 aadInstance 和租户创建授权值的行Delete the line for creating the authority value from aadInstance and tenant

    private static string authority = String.Format(CultureInfo.InvariantCulture, aadInstance, tenant);

  • 在函数mainwindow.xaml中,将 authContext 实例更改为In the function MainWindow, change the authContext instantiation to

    authContext = new AuthenticationContext(authority,false);

    ADAL 不支持验证 AD FS 作为权限,因此我们必须传递 validateAuthority 参数的 false 值标志。ADAL does not support validating AD FS as authority and therefore we have to pass a false value flag for validateAuthority parameter.

    主窗口

修改 TodoListServiceModify TodoListService

此项目中需要更改两个文件-Web.config 和 Startup.Auth.cs。Two files need changes in this project – Web.config and Startup.Auth.cs. 需要 Web.Config 更改才能获取正确的参数值。Web.Config changes are required to get the correct values of the parameters. 需要 Startup.Auth.cs 更改以将 WebAPI 设置为针对 AD FS 而不是 Azure AD 进行身份验证。Startup.Auth.cs changes are required to set the WebAPI to authenticate against AD FS rather than Azure AD.

Web.configWeb.config

  • 注释密钥ida:租户,因为我们不需要它Comment the key ida:Tenant as we don't need it
  • ida:核证机关添加密钥,其值指示联合身份验证服务的 FQDN,例如https://fs.contoso.com/adfs/Add the key for ida:Authority with value indicating the FQDN of the federation service, example, https://fs.contoso.com/adfs/
  • 修改 key ida:受众,其中包含你在 AD FS 中的 "添加应用程序组" 期间在 "配置 web api " 页中指定的 web api 标识符的值。Modify key ida:Audience with the value of the Web API identifier that you specified in the Configure Web API page during Add Application Group in AD FS.
  • 添加密钥ida: AdfsMetadataEndpoint ,其中包含与 AD FS 服务的联合元数据 URL 对应的值,例如:https://fs.contoso.com/federationmetadata/2007-06/federationmetadata.xmlAdd key ida:AdfsMetadataEndpoint with value corresponding to the federation metadata URL of the AD FS service, for ex: https://fs.contoso.com/federationmetadata/2007-06/federationmetadata.xml

Web 配置

Startup.Auth.csStartup.Auth.cs

按如下所示修改 ConfigureAuth 函数Modify the ConfigureAuth function as below

    public void ConfigureAuth(IAppBuilder app)
    {
        app.UseActiveDirectoryFederationServicesBearerAuthentication(
            new ActiveDirectoryFederationServicesBearerAuthenticationOptions
            {
                MetadataEndpoint = ConfigurationManager.AppSettings["ida:AdfsMetadataEndpoint"],
                TokenValidationParameters = new TokenValidationParameters()
                {
                    SaveSigninToken = true,
                    ValidAudience = ConfigurationManager.AppSettings["ida:Audience"]
                }

            });
    }

实质上,我们要将身份验证配置为使用 AD FS 并进一步提供有关 AD FS 元数据的信息,并验证令牌,受众声明应该是 Web API 所需的值。Essentially, we are configuring the authentication to use AD FS and further provide information about the AD FS metadata, and to validate the token, the audience claim should be the value expected by the Web API. 运行应用程序Running the application

  1. 在解决方案 Nativeclient-ios-DotNet 上,右键单击并选择 "属性"。On the solution NativeClient-DotNet, right click and go to properties. 将启动项目更改为 "多个启动项目",并将 "TodoListClient" 和 "TodoListService" 设置为 "启动"。Change the Startup Project as shown below to Multiple Startup projects and set both TodoListClient and TodoListService to Start. 解决方案属性Solution properties

  2. 按 F5 按钮,或选择菜单栏中的 "调试" > 继续。Press F5 button or select Debug > Continue in the menu bar. 这将启动本机应用程序和 WebAPI。This will launch both the native application and the WebAPI. 单击本机应用程序上的 "登录" 按钮,该按钮将弹出来自 AD AL 的交互式登录,并将其重定向到 AD FS 服务。Click on Sign-in button on the native application and it will pop-up an interactive logon from AD AL and redirect to your AD FS service. 输入有效用户的凭据。Enter the credentials of a valid user. 登录Sign-in

在此步骤中,本机应用程序重定向到 AD FS 并获得一个 ID 令牌和一个用于 Web API 的访问令牌In this step, the native application redirected to AD FS and got an ID token and an access token for the Web API

  1. 在文本框中输入一个待办事项,并单击 "添加项"。Enter a to do item in the text box and click on Add item. 在此步骤中,应用程序将进入 Web API 以添加待办事项,若要执行此操作,请向 AD FS 中获取的 WebAPI 提供访问令牌。In this step, the application reaches out to the Web API to add the to do item, and in order to do so, presents the access token to the WebAPI obtained from AD FS. Web API 与受众值匹配,以确保令牌适用于该令牌,并使用来自联合元数据的信息验证令牌签名。The Web API matches the audience value to make sure the token is intended for it and verifies the token signature using the info from the federation metadata.

登录

后续步骤Next Steps

AD FS 开发AD FS Development