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

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

问题描述

我知道,如果我正确阅读了 Microsoft 的文档并与一位在使用 Azure Functions 所利用的 Web 开发范例方面有一定经验的朋友进行了对话,则 Azure Functions 可能是互联网上的开放端点.粗略阅读有关该主题的安全论坛和堆栈溢出问题,使我至少了解了几个保护它们的选项,即

  1. 为了安全起见,我建议使用 Azure Active Directory 是一个更好的选择..如此处所述

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

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

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

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

    现在转到 Azure Active Directory > 应用注册 > 函数应用的应用注册 > 清单

    添加一个新的应用程序角色..像这样使用json:

    "appRoles": [{允许的成员类型":[应用"],"displayName": "可以调用我的函数","id": "fc803414-3c61-4ebc-a5e5-cd1675c14bbb",已启用":真,"description": "具有此角色的应用程序可以调用我的 Azure 函数",值":MyFunctionValidClient"}]

    为您的逻辑应用启用托管服务标识.

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

    将应用权限分配给此托管服务身份..

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

    使用托管服务标识向 Azure 函数验证逻辑应用......如上面方法 1 中所述

    现在,在您的函数收到的身份验证令牌中,您可以检查 role 声明集合是否必须包含名为 "MyFunctionValidClient" 的角色,否则您可以拒绝调用未经授权的例外.

    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. Shared Access Signatures (SAS) and
    3. Azure Virtual Networks.

    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 lacks ability to perform blob manipulation (i.e copy and delete)
    2. Logic App lacks ability to perform a join (of files loaded to SQL endpoint and file names in blob container)

    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.

    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

    How to Implement

    I see two possible approaches:

    1. Simple Approach: Check that calling application is your Azure logic app specifically

    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.

    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)

    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.

    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. A more declarative Approach: Have an application permission defined for Azure function app and check for this permission/role being present in auth token from client calling your function

    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.

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

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

    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.

    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>
    

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

    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天全站免登陆