有没有一种方法可以保护只能从特定的Azure逻辑应用程序调用的Azure功能? [英] Is there a way to secure an Azure Function that will only be called from a specific Azure Logic App?

查看:236
本文介绍了有没有一种方法可以保护只能从特定的Azure逻辑应用程序调用的Azure功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我了解,如果我正确阅读Microsoft的文档并与具有一定经验的朋友交谈,则Azure可能是Internet上的开放端点,该朋友具有一些使用Azure Functions所利用的Web开发范例的经验.粗略阅读安全论坛和有关该主题的堆栈溢出问题使我了解至少两种保护它们的方法,即

I understand that Azure Functions are potentially open endpoints on the internet if I read Microsoft’s documentation correctly and per conversations with a friend who has some experience working with web development paradigms that Azure Functions leverages. A cursory reading of security forums and stack overflow questions on the topic leads me to understand at least a couple options of securing them namely

  1. Azure Active Directory
  2. 共享访问签名(SAS)
  3. Azure虚拟网络.
  1. Azure Active Directory
  2. Shared Access Signatures (SAS) and
  3. Azure Virtual Networks.

上下文/我的Azure函数做什么?它管理与从SFTP源到SQL端点的供应商数据的ETL相关的Blob容器,该ETL使用中间Blob容器进行文件传输和源数据的长期冷存储.将Blob加载到SQL终结点后,Azure函数将这些Blob从一个容器移动到一个存档容器.为什么要使用Azure Function管理Blob容器?

Context/ What does my Azure Function do? It manages a blob container related to an ETL of vendor data from a SFTP source to a SQL Endpoint which this ETL utilizes an intermediary blob container for file transfer and long term cold storage of source data. The Azure Function moves the blobs from one container to an archive container after they have been loaded to the SQL endpoint. Why Azure Function to manage the blob containers?

  1. SSIS缺乏执行Blob操作(即复制和删除)的能力
  2. Logic App缺乏执行连接的能力(由加载到SQL端点的文件和blob容器中的文件名组成)

其中一个功能的示例如下所示:

An example of one of the functions is shown here below:

using System.IO;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Net.Http;
using System.Net;
using Microsoft.WindowsAzure.Storage.Blob;
using System.Collections.Generic;
using System.Text;

namespace AFA_ArchiveBlob
{
    public static class HttpTrigger_BlobInput
    {
        [FunctionName("HttpTrigger_BlobInput")]
        public static async Task<HttpResponseMessage> Run(
        //public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get",  Route = "{name}")] HttpRequest req,
            string name,
            ILogger log,
            [Blob("{name}/blobname",FileAccess.ReadWrite,Connection = "AzureWebJobsStorage")]  CloudBlobContainer myCloudBlobContainer
            )
        {
            //Execution Logged.
            log.LogInformation($"HttpTrigger_BlobInput - C# HTTP trigger function processed a request.");

            //Run the query against the blob to list the contents.
            BlobContinuationToken continuationToken = null;
            List<IListBlobItem> results = new List<IListBlobItem>();
            do
            {
                var response = await myCloudBlobContainer.ListBlobsSegmentedAsync(continuationToken);
                continuationToken = response.ContinuationToken;
                results.AddRange(response.Results);
            }
            while (continuationToken != null);

            //Query the names of the blobs. Todo: can this be a single line linq query select instead?
            List<string> listBlobNames = new List<string>();
            foreach (CloudBlockBlob b in results)
            {
                listBlobNames.Add(b.Name);
            }

            //Serialize the list of blob names to json for passing to function caller via return statement
            var jsonReturn = JsonConvert.SerializeObject(listBlobNames);

            log.LogInformation("Returning the following JSON");
            log.LogInformation(jsonReturn);

            return new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new StringContent(jsonReturn, Encoding.UTF8, "application/json")
            };
        }
    }
}

推荐答案

首先,尽管使用键可能很方便,但我看到

Firstly, even though using keys might be convenient, I see that official documentation advises against using keys to secure function endpoint in production scenarios.

我建议使用Azure Active Directory以获得安全性是一个更好的选择.如此处

I suggest it would be a better choice to go with Azure Active Directory for security.. as explained here Secure an HTTP endpoint in production

如何实施

我看到两种可能的方法:

I see two possible approaches:

1.简单方法:检查调用的应用程序是否特别是您的Azure逻辑应用程序

为您的Azure Function应用启用Azure Active Directory身份验证.您可以简单地使用Express设置(通过创建新的Azure AD应用程序)

Enable Azure Active Directory Authentication for your Azure Function App. You can simply use Express settings (with create a new Azure AD app)

为您的逻辑应用程序启用托管服务身份.

Enable Managed Service Identity for your Logic App.

查找与逻辑应用程序关联的托管服务标识的appid..转到Azure门户> Azure Active Directory>企业应用程序>所有应用程序>相关服务主体(有关详细信息,请参见

Find out appid for Managed Service Identity associated with your logic app.. go to Azure Portal > Azure Active Directory > Enterprise Applications > All Applications > Relevant Service Principal (Explained in more detail with screenshots in another SO post here)

使用托管服务身份将逻辑应用程序授权给Azure功能,如此处所述..

Authenticate your logic app to Azure function using Managed Service Identity as explained here.. Authenticate with managed identity in logic app.. note that resource being accessed will be your Azure function.

在您的函数代码中,现在您可以检查访问令牌中的appid声明是否与逻辑应用程序的appid完全匹配(即,逻辑应用程序是调用函数的那个​​).未经授权的例外.

In your function code, now you can check that appid claim in access token should exactly match the appid for logic app (i.e. logic app is the one calling your function).. otherwise you can reject the call with Unauthorized exception.

2.一种更具说明性的方法:为Azure函数应用程序定义一个应用程序权限,并从客户端调用您的函数的auth令牌中检查此权限/角色是否存在

此方法更具声明性,因为您定义了一个应用程序权限,该权限需要分配给可以调用您的Azure函数的任何应用程序.

This approach is a little more declarative, as you define an application permission that needs to be assigned to any application that can call your Azure function.

为您的Azure Function应用启用Azure Active Directory身份验证.您可以简单地使用Express设置(通过创建新的Azure AD应用程序)

Enable Azure Active Directory Authentication for your Azure Function App. You can simply use Express settings (with create a new Azure AD app)

现在转到Azure Active Directory>应用程序注册>功能应用程序的应用程序注册>清单

Now go to Azure Active Directory > App Registrations > App registration for your function app > Manifest

使用json这样添加新的应用程序角色:

Add a new application role.. using json like this:

"appRoles": [
{
  "allowedMemberTypes": [
    "Application"
  ],
  "displayName": "Can invoke my function",
  "id": "fc803414-3c61-4ebc-a5e5-cd1675c14bbb",
  "isEnabled": true,
  "description": "Apps that have this role have the ability to invoke my Azure function",
  "value": "MyFunctionValidClient"
}]

为您的逻辑应用程序启用托管服务身份.

Enable Managed Service Identity for your Logic App.

找出与您的逻辑应用相关联的托管服务标识的appid ..如上面方法1中所述

Find out appid for Managed Service Identity associated with your logic app.. as already explained in approach 1 above

将应用权限分配给此托管服务标识.

Assign the app permission to this managed service identity..

New-AzureADServiceAppRoleAssignment -ObjectId <logicappmsi.ObjectId> -PrincipalId <logicappmsi.ObjectId> -Id "fc803414-3c61-4ebc-a5e5-cd1675c14bbb" -ResourceId <yourfunctionaadapp.ObjectId>

如上文方法1中所述,使用托管服务身份将逻辑应用授权到Azure功能.

Authenticate your logic app to Azure function using Managed Service Identity.. as already explained in approach 1 above

现在,在函数接收的auth令牌中,您可以检查role声明集合必须包含名为"MyFunctionValidClient"的角色,否则可以拒绝带有未授权异常的调用.

Now, in the auth token received by your function, you can check that the role claims collection must contain a role named "MyFunctionValidClient" otherwise you can reject the call with Unauthorized exception.

这篇关于有没有一种方法可以保护只能从特定的Azure逻辑应用程序调用的Azure功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆