繁体   English   中英

WPF应用使用AAD访问Azure功能

[英]WPF app Accessing Azure Function with AAD

我已经在Azure Functions中创建了一个示例函数。 我已经使用AAD对其进行了保护。 我可以成功转到URL,使用我的Office 365帐户登录,然后该函数运行。

我在AAD中为WPF客户创建了另一个应用程序。 我可以使用我的Office 365凭据成功登录到WPF客户端。 然后,我在AAD中为此应用创建了一个permision,以访问Azure Function AAD应用。

这是我的问题:如何使用WPF应用程序中的登录令牌访问Azure功能?

我遍历了大约十二个不同的教程,展示了如何进行设置,每个教程都无法真正验证对函数的调用。

我想念什么?

经过大量研究和反复试验,终于可以使用我的Office365帐户登录并访问Azure功能。

步骤1-向Azure Active Directory注册您的App Service应用程序

  1. 登录到Azure门户,然后导航到您的App Service应用程序。 将应用程序URL复制到Azure函数。 您将使用它来配置Azure Active Directory应用程序注册。
  2. 导航到Active Directory,然后选择应用程序注册,然后单击顶部的“新建应用程序注册”以开始新的应用程序注册。
  3. 在“创建”页面中,为您的应用程序注册输入名称,选择Web App / API类型,在“登录URL”框中粘贴应用程序URL(从步骤1开始)。 然后单击创建。
  4. 几秒钟后,您应该会看到刚刚创建的新应用程序注册。
  5. 添加应用程序注册后,单击应用程序注册名称,单击顶部的“设置”,然后单击“属性”。
  6. 在“应用程序ID URI”框中,粘贴“应用程序URL”(来自步骤1),也粘贴在“主页URL”中,同时粘贴应用程序URL(来自步骤1),然后单击“保存”。
  7. 现在单击“答复URL”,编辑“答复URL”,粘贴到“应用程序URL”(从步骤1开始),修改协议以确保您具有https://协议(不是http://),然后附加到末尾。 URL /.auth/login/aad/callback(例如, https: //contoso.azurewebsites.net/.auth/login/aad/callback)。 单击保存。
  8. 此时,复制该应用程序的应用程序ID。 保留以备后用。 您将需要它来配置您的App Service应用程序。
  9. 关闭已注册的应用程序页面。 在“应用程序注册”页面上,单击顶部的“端点”按钮,然后复制联合身份验证元数据文档URL。
  10. 打开一个新的浏览器窗口,并通过粘贴和浏览到XML页面来导航到URL。 文档顶部是EntityDescriptor元素。 查找entityID属性并复制其值。 它用作您的发行者URL。 您将配置您的应用程序以供以后使用。

步骤2-将Azure Active Directory信息添加到您的App Service应用程序

  1. 返回Azure门户,导航到您的App Service应用程序。 单击身份验证/授权。 如果未启用身份验证/授权功能,则将开关转到On。 单击身份验证提供程序下的Azure Active Directory,以配置您的应用程序。 (可选)默认情况下,App Service提供身份验证,但不限制对您的网站内容和API的授权访问。 您必须在您的应用代码中授权用户。 将操作设置为在未对请求进行身份验证时采取以使用Azure Active Directory登录。 此选项要求对所有请求进行身份验证,并且所有未经身份验证的请求都将重定向到Azure Active Directory进行身份验证。
  2. 在Active Directory身份验证配置中,单击“管理模式”下的“高级”。 将应用程序ID粘贴到“客户端ID”框中(从步骤8开始),然后单击“确定”。
  3. 在“ Active Directory身份验证”配置页上,单击“保存”。

步骤3-配置本机客户端应用程序

Azure Active Directory还允许您注册本机客户端,从而更好地控制权限映射。 如果您希望使用诸如Active Directory身份验证库之类的库来执行登录,则需要这样做。

  1. 导航到Azure门户中的Azure Active Directory。
  2. 在左侧导航中,选择“应用程序注册”。 点击顶部的新应用注册。
  3. 在“创建”页面中,输入您的应用程序注册名称。 在“应用程序类型”中选择“本机”。
  4. 在“重定向URI”框中,使用HTTPS方案输入站点的/.auth/login/done端点。 此值应类似于https://contoso.azurewebsites.net/.auth/login/done 如果创建Windows应用程序,则使用包SID作为URI。
  5. 单击创建。
  6. 添加应用程序注册后,选择它以将其打开。 找到应用程序ID并记下该值。
  7. 单击所有设置>所需权限>添加>选择API。
  8. 输入您先前注册的App Service应用程序的名称以进行搜索,然后选择它并单击“选择”。
  9. 选择访问。 然后单击选择。 然后单击完成。

以上指示来自https://docs.microsoft.com/zh-cn/azure/app-service/configure-authentication-provider-aad?toc=%2fazure%2fazure-functions%2ftoc.json

以下是我所做的更改,以使其能够与调用Azure函数的WPF应用程序一起使用

步骤4-授权Service App中的Client App

  1. 复制第3步中的客户端应用ID:
  2. 打开Azure Active Directory
  3. 单击应用程序注册(预览)
  4. 单击在步骤1中注册的服务应用程序
  5. 单击公开API
  6. 在“授权的客户端应用程序”下,单击“添加客户端应用程序”。
  7. 粘贴客户端ID,然后单击范围https:// {您的租户名称} .onmicrosoft.com / {您的服务应用程序ID} / user_impersonation
  8. 单击添加应用程序

第5步-使Service App多租户

  1. 打开Azure Active Directory
  2. 单击应用程序注册(预览)
  3. 单击在步骤1中注册的服务应用程序
  4. 单击身份验证
  5. 在“受支持的帐户类型”下,选择“任何组织目录中的帐户”
  6. 您将收到一个错误。 这是因为步骤1的子步骤6。我们需要基于承租人域{tenantname} .onmicrosoft.com创建一个App URI。
  7. 导航到旧的应用程序注册(因为除非您编辑清单,否则在应用程序注册(预览)中不可用)
  8. 选择您的服务应用程序(您可能需要单击以查看所有应用程序)
  9. 单击设置。 然后单击属性。
  10. 在“应用程序ID URI”下,将其更改为https:// {ad tenant name} .onmicrosoft.com / {Service App ID}
  11. 确保“多租户”设置为“是”(这是由于步骤5的子步骤6)。

步骤6-将范围添加到功能APP

  1. 在Azure门户中打开您的功能应用程序并导航到Authenticaiton
  2. 更改Active Directory设置,以使Service APP IE中的API作用域权限的全部值具有允许的令牌访问者

https:// {AD TENANT} .onmicrosoft.com / {SERVICE APP ID} / user_impersonation

现在为代码

从您的客户端应用程序。 安装nuget Microsoft.Identity.Client

using Microsoft.Identity.Client;
using Newtonsoft.Json.Linq;
using System;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;

namespace TestAzureFunctionLogin
{
public class ManualTestApp
{
    static string ClientId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"; //replace with AppID from Client App Azure AD registration
    static string ServiceId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"; //replace with AppID from Service App Azure AD registration
    static string Scope = $"{ServiceId}/user_impersonation";
    static string Authority = "https://login.microsoftonline.com/organizations";

    string[] _scopes => new string[] { Scope };
    private PublicClientApplication _clientApp = new PublicClientApplication(ClientId, Authority);

    private AuthenticationResult authResult;
    public PublicClientApplication ClientApp => _clientApp;

    public async Task LoginAsync()
    {
        var user = (await ClientApp.GetAccountsAsync()).FirstOrDefault();
        authResult = await ClientApp.AcquireTokenAsync(_scopes, user);
    }

    public async Task<string> CallAzureFunction(string url)
    {
        return await GetHttpContentWithToken(url, authResult.AccessToken);
    }

    //Code taken from somewhere on the Microsoft Website
    public async Task<string> GetHttpContentWithToken(string url, string token)
    {
        var httpClient = new System.Net.Http.HttpClient();
        System.Net.Http.HttpResponseMessage response;
        try
        {
            var request = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, url);
            //Add the token in Authorization header
            request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
            response = await httpClient.SendAsync(request);

            var content = await response.Content.ReadAsStringAsync();
            return content;
        }
        catch (Exception ex)
        {
            return ex.ToString();
        }
    }
}

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM