你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

使用 Azure Functions 从 Azure 逻辑应用中的工作流创建和运行代码

适用于:Azure 逻辑应用(消耗)

若要运行在逻辑应用工作流中执行特定作业的代码,可以使用 Azure Functions 创建函数。 该服务有助于创建 Node.js、C# 和 F# 函数,使你无需为运行代码而构建完整的应用或基础结构。 Azure Functions 在云中提供无服务器计算,且对执行特定任务非常有用,例如:

  • 通过 Node.js 或 C# 函数扩展逻辑应用的行为。
  • 在逻辑应用工作流中执行计算。
  • 在逻辑应用工作流中应用高级格式设置或计算字段。

注意

Azure 逻辑应用不支持在启用了部署槽位的情况下使用 Azure Functions。 虽然此方案有时可能可行,但此行为是不可预测的,且在工作流尝试调用 Azure 函数时可能会导致授权问题。

本文演示如何从逻辑应用工作流调用 Azure 函数。 若要在不使用 Azure Functions 的情况下运行代码片段,请参阅添加和运行内联代码。 若要从函数内部调用和触发逻辑应用工作流,必须使用提供可调用终结点的触发器启动该工作流。 例如,可使用 HTTP 触发器、请求触发器、Azure 队列触发器或事件网格触发器启动工作流。 在函数内,向触发器的 URL 发送一个 HTTP POST 请求,并加入需要工作流处理的有效负载。 有关详细信息,请参阅调用、触发或嵌套逻辑应用工作流

先决条件

  • Azure 帐户和订阅。 如果没有订阅,可以注册免费的 Azure 帐户

  • 一个 Azure 函数应用资源,它是可以使用 Azure Functions 创建的函数以及想要使用的函数的容器。

    若没有函数应用,请先创建函数应用。 然后,可以在 Azure 门户中在逻辑应用外部创建函数,也可以在工作流设计器中从逻辑应用内部创建函数。

  • 使用逻辑应用资源时,相同的要求也同时适用于函数应用和函数(现有或新的):

    • 函数应用资源和逻辑应用资源必须使用相同的 Azure 订阅。

    • 新的函数应用必须使用 .NET 或 JavaScript 作为运行时堆栈。 将新函数添加到现有的函数应用时,可以选择 C# 或 JavaScript。

    • 你的函数使用 HTTP 触发器模板。

      此 HTTP 触发器模板可从逻辑应用工作流接受具有 application/json 类型的内容。 当你向工作流添加函数时,设计器会显示 Azure 订阅内基于此模板创建的自定义函数。

    • 函数不使用自定义路由,除非你定义了 OpenAPI 定义Swagger 文件)。

    • 如果你已为函数定义了 OpenAPI 定义,工作流设计器会在你使用函数参数时提供更丰富的体验。 在逻辑应用工作流查找并访问具有 OpenAPI 定义的函数之前,请先按照以下后续步骤设置函数应用

  • 要使用函数的消耗或标准逻辑应用资源和工作流。

    在添加在工作流中运行函数的操作之前,工作流第一步必须从触发器开始。 如果不熟悉逻辑应用工作流,请参阅什么是 Azure 逻辑应用快速入门:创建第一个逻辑应用工作流

查找包含 OpenAPI 说明的函数

为了在使用函数参数时在工作流设计器中获得更丰富的体验,请为函数生成 OpenAPI 定义Swagger 文件)。 若要设置函数应用以使其可查找和使用具备 Swagger 描述的函数,请按照以下步骤操作:

  1. Azure 门户中,打开函数应用。 确保函数应用正在运行。

  2. 按照以下步骤操作为函数应用设置跨源资源共享 (CORS),以便允许所有源:

    1. 在函数应用资源菜单的“API”下,选择“CORS”。

      显示 Azure 门户的屏幕截图,其中选中了带“CORS”选项的函数应用资源菜单。

    2. 在“CORS”下,添加星号 (*) 通配符,但删除列表中的其他所有源,然后选择“保存”。

      显示 Azure 门户、“CORS”窗格和在“允许来源”下输入的通配符“*”的屏幕截图。

访问 HTTP 请求中的属性值

Webhook 函数能接受 HTTP 请求作为输入,并将这些请求传递至其他函数。 例如,尽管 Azure 逻辑应用具有转换 DateTime 值的函数,但此基本示例 JavaScript 函数演示了如何访问传递给函数的请求对象中的属性,并对该属性值执行操作。 为访问对象内的属性,此示例使用点 (.) 运算符

function convertToDateString(request, response){
   var data = request.body;
   response = {
      body: data.date.ToDateString();
   }
}

下面是此函数内部发生的情况:

  1. 该函数创建 data 变量并将 request 对象内的 body 对象分配给该变量。 该函数使用点 (.) 运算符引用 request 对象内的 body 对象:

    var data = request.body;
    
  2. 该函数现在可以通过 data 变量访问 date 属性,并通过调用 ToDateString() 函数将该属性值从 DateTime 类型转换为 DateString 类型。 该函数还通过函数响应中的 body 属性返回结果:

    body: data.date.ToDateString();
    

现已在 Azure 中创建了自己的函数,请按步骤将函数添加到逻辑应用

从逻辑应用工作流内部创建函数

使用工作流设计器中的内置 Azure Functions 操作,可以直接通过逻辑应用的工作流创建函数,但这种方法只能用于使用 JavaScript 编写的函数。 对于其他语言,可以通过 Azure 门户中的 Azure Functions 体验来创建函数。 不过,必须已经有函数应用资源(即函数容器),然后才能在 Azure 中创建函数。 若没有函数应用,请先创建一个。 有关详细信息,请参阅在 Azure 门户中创建第一个函数

注意

目前,只能直接从消耗逻辑应用工作流创建函数,不能从标准逻辑应用工作流创建函数。 但是,可以使用 Azure 门户Visual StudioVisual Studio CodeAzure CLIAzure PowerShellARM 模板以其他方式创建该函数。 然后,可以使用名为“调用 Azure 函数”的 Azure Functions 操作从标准逻辑应用工作流调用该函数。

  1. Azure 门户中,打开设计器中的消耗逻辑应用工作流。

  2. 按照适用于自身方案的步骤,创建并添加函数:

    • 在工作流的最后一步,选择“新建步骤” 。

    • 在工作流中的现有步骤之间,将鼠标移至箭头上,然后依次选择加号 (+) 和“添加操作”。

  3. 在设计器的搜索框中,输入 azure functions。 在操作列表中,选择“选择 Azure 函数”操作,例如:

    显示用于消耗逻辑应用工作流的 Azure 门户和使用搜索框查找 Azure 函数的设计器的屏幕截图。

  4. 从函数应用列表中选择自己的函数应用。 在操作列表打开后,选择“新建函数”操作。

    显示带“新建函数”的操作选取器的屏幕截图。

  5. 在函数定义编辑器中定义函数:

    1. 在“函数名称”框中提供函数的名称。

    2. 在“代码”框中,将代码添加到函数模板中,包括你希望在函数运行结束后返回给逻辑应用的响应和有效负载。 完成后,选择“创建”,例如:

    显示具有模板函数定义的函数创作编辑器的屏幕截图。

    模板代码中的 context 对象表示在后续步骤中工作流通过“请求正文”属性发送的消息。 要从函数内访问 context 对象的属性,请使用以下语法:

    context.body.<property-name>

    例如,要引用 context 对象内的 content 属性,请使用以下语法:

    context.body.content

    此模板代码还包含一个 input 变量,此变量存储来自 data 参数的值,因此函数可对该值执行操作。 在 JavaScript 函数内,data 变量也是 context.body 的一种快捷方式。

    注意

    此处的 body 属性适用于 context 对象,但与来自操作输出的 Body 令牌不同,你可能也会希望将后者传递到函数。

  6. 在“请求正文”框中,提供函数的输入,其格式必须为 JavaScript 对象表示法 (JSON) 对象。

    此输入是逻辑应用发送到函数的上下文对象或消息。 点击“请求正文”字段时,界面会显示动态内容列表,以便你可以为先前步骤中的输出选择令牌。 此示例指定上下文有效负载包含名为 content 的属性,其中有来自电子邮件触发器的“发件人”标记的值。

    显示函数和具有示例上下文对象有效负载的“请求正文”属性的屏幕截图。

    此处的上下文对象没有强制转换为字符串,因此对象的内容被直接添加到 JSON 有效负载中。 但是,如果该上下文对象不是传递字符串、JSON 对象或 JSON 数组的 JSON 令牌,则会出现错误。 所以,如果此示例改用“接收时间”标记,则可以通过添加双引号将上下文对象强制转换为字符串,例如:

    显示将对象强制转换为字符串的“请求正文”属性的屏幕截图。

  7. 若要指定其他详细信息,例如要使用的方法、请求标头、查询参数或身份验证,请打开“添加新参数”列表,然后选择所需选项。 身份验证的选项因所选函数而异。 有关详细信息,请参阅为函数启用身份验证

将现有函数添加至逻辑应用工作流

若要从逻辑应用工作流调用现有函数,可以添加函数,具体方法与在工作流设计器中执行的任何其他操作一样。

  1. Azure 门户中,打开设计器中的消耗逻辑应用工作流。

  2. 在要添加函数的步骤下,选择“新建步骤”。

  3. 在“选择操作”下的搜索框中输入 azure functions。 在操作列表中,选择“选择 Azure 函数”操作,例如:

    显示用于消耗逻辑应用工作流的 Azure 门户和使用搜索框查找 Azure 函数的设计器的屏幕截图。

  4. 从函数应用列表中选择自己的函数应用。 在显示的函数列表中选择函数。

    消耗的屏幕截图,显示选定的函数应用和函数。

    对于具备 API 定义(Swagger 描述)的函数以及那些设置为可供逻辑应用查找和访问的函数,可以选择“Swagger 操作”。

    消耗的屏幕截图,显示选定的函数应用,然后在“Swagger 操作”下选择函数。

  5. 在“请求正文”框中,提供函数的输入,其格式必须为 JavaScript 对象表示法 (JSON) 对象。

    此输入是逻辑应用发送到函数的上下文对象或消息。 单击“请求正文”字段时,会看到动态内容列表,这样就可以为前面步骤的输出选择标记。 本示例指定上下文有效负载包含一个名为 content 的属性,该属性具有来自电子邮件触发器的 From 标记的值。

    消耗的屏幕截图,显示具有“请求正文”示例的函数 - 上下文对象有效负载

    此处的上下文对象没有强制转换为字符串,因此对象的内容被直接添加到 JSON 有效负载中。 但是,如果该上下文对象不是传递字符串、JSON 对象或 JSON 数组的 JSON 令牌,则会出现错误。 因此,假如本示例使用 Received Time 令牌,则可通过添加双引号将此上下文对象强制转换为字符串:

    消耗的屏幕截图,显示具有“请求正文”示例的函数,该示例将对象强制转换为字符串。

  6. 若要指定其他详细信息,例如要使用的方法、请求标头、查询参数或身份验证,请打开“添加新参数”列表,然后选择所需选项。 身份验证的选项因所选函数而异。 有关详细信息,请参阅为函数启用身份验证

为函数调用启用身份验证

若要验证对受 Azure Active Directory (Azure AD) 保护的资源的访问,逻辑应用可以使用托管标识(以前称为托管服务标识或 MSI)。 此托管标识无需登录并提供凭据或机密即可对访问进行身份验证。 由于无需提供或轮换机密,因此 Azure 会为你管理此标识,并且会帮助保护凭据。 可以在逻辑应用上设置系统分配的标识或手动创建的、用户分配的标识。 从工作流调用的函数可以使用同一标识进行身份验证。

有关详细信息,请查看以下文档:

若要设置函数应用和函数,以便它们可以使用逻辑应用的托管标识,请执行以下高级步骤:

  1. 启用并设置逻辑应用的托管标识

  2. 设置函数以进行匿名身份验证

  3. 查找设置 Azure AD 身份验证所需的值

  4. 为函数应用创建应用注册

设置函数以进行匿名身份验证

若要让函数使用逻辑应用的托管标识,则必须将函数的身份验证级别设置为“匿名”。 否则,逻辑应用工作流会抛出“BadRequest”错误。

  1. Azure 门户中,找到并选择你的函数应用。

    以下步骤使用名为 FabrikamFunctionApp 的示例函数应用。

  2. 在函数应用资源菜单的“开发工具”下,选择“高级工具”>“前往”。

    显示已选中“高级工具”和“Go”的函数应用菜单的屏幕截图。

  3. 在“Kudu 服务”页打开后,在 Kudu 网站的标题栏中,从“调试控制台”菜单中选择“CMD”。

    显示 Kudu 服务页面的屏幕截图,其中“调试控制台”菜单已打开,并且选中了“CMD”选项。

  4. 下一页出现后,从文件夹列表中选择“站点”>“wwwroot”>“<你的函数>”。

    以下步骤使用名为 FabrikamAzureFunction 的示例函数。

    显示“site”>“wwwroot”> 所选函数的文件夹列表的屏幕截图。

  5. 打开 function.json 文件以进行编辑。

    显示已选中“编辑”命令的“function.json”文件的屏幕截图。

  6. 在 bindings 对象中,检查 authLevel 属性是否存在。 若此属性存在,将属性值设置为“anonymous”。 否则,请添加该属性并设置值。

    显示“bindings”对象的屏幕截图,其中“authLevel”属性设置为“anonymous”。

  7. 完成后,保存设置。 请继续阅读下一节。

查找设置 Azure AD 身份验证所需的值

在将函数应用设置为使用 Azure AD 身份验证之前,需要先按照本节中的步骤查找并保存以下值。

  1. 查找逻辑应用的托管标识的对象(主体)ID
  2. 查找 Azure Active Directory (Azure AD) 的租户 ID

查找逻辑应用的托管标识的对象 ID

根据你使用的是消耗还是标准逻辑应用资源,执行相应的步骤:

  1. 当逻辑应用启用其托管标识后,在逻辑应用菜单上的“设置”下,选择“标识”,然后选择“系统分配”或“用户分配”。

    • 系统分配

      对于系统分配的标识,复制标识的对象 ID,例如:

      显示消耗逻辑应用“标识”窗格的屏幕截图,其中已选中“系统已分配”选项卡。

    • 用户分配

      1. 对于用户分配的标识,复制标识以查找对象 ID,例如:

        显示消耗逻辑应用“标识”窗格的屏幕截图,其中已选中“用户已分配”选项卡。

      2. 在托管标识的“概述”窗格上,可以找到标识的对象 ID,例如:

        显示用户分配标识的“概述”窗格的屏幕截图,其中已选中对象 ID。

查找 Azure AD 的租户 ID

若要查找 Azure AD 的租户 ID,请运行名为 Get-AzureAccount 的 PowerShell 命令,或在 Azure 门户中执行以下步骤:

  1. Azure 门户中,打开你的 Azure AD 租户。 这些步骤使用“Fabrikam”作为示例租户。

  2. 在 Azure AD 租户菜单上的“管理”下,选择“属性”。

  3. 复制并保存租户 ID 供以后使用,例如:

    显示 Azure AD“属性”窗格的屏幕截图,其中已选中租户 ID 的“复制”按钮。

为函数应用创建应用注册

为逻辑应用的托管标识查找对象 ID 和为 Azure AD 查找租户 ID 之后,可以通过创建应用注册将函数应用设置为使用 Azure AD 身份验证。 有关详细信息,请参阅将应用服务或 Azure Functions 应用配置为使用 Azure AD 登录

  1. Azure 门户中,打开函数应用。

  2. 在函数应用菜单的“设置”下,选择“身份验证”,然后选择“添加标识提供者”。

    显示函数应用菜单的屏幕截图,其中已选中“身份验证”窗格和“添加标识提供者”。

  3. 在“添加标识提供者”窗格的“基本信息”下,从“标识提供者”列表中选择“Microsoft”。

  4. 在“应用注册”下,对于“应用注册类型”,选择“提供现有应用注册的详细信息”,然后输入之前保存的值。

    属性 必选 描述
    应用程序(客户端) ID <object-ID> 用于此应用注册的唯一标识符。 在此方案中,请使用逻辑应用的托管标识中的对象 ID。
    客户端机密 可选,但建议提供 <client-secret> 应用在请求令牌时用来证明其身份的机密值。 客户端机密作为名为 MICROSOFT_PROVIDER_AUTHENTICATION_SECRET 的槽粘滞应用程序设置创建并存储在应用的配置中。 如果你想要在 Azure Key Vault 中管理机密,稍后可以将该设置更新为使用密钥保管库引用。 - 如果提供客户端机密值,登录操作将使用混合流,同时返回访问令牌和刷新令牌。 - 如果未提供客户端机密,登录操作将使用 OAuth 2.0 隐式授权流,仅返回 ID 令牌。 这些令牌由提供程序发送并存储在 EasyAuth 令牌存储中。
    颁发者 URL < authentication-endpoint-URL>/<Azure-AD-tenant-ID>/v2.0 此 URL 可将用户重定向到正确的 Azure AD 租户,并下载适当的元数据,以确定相应的令牌签名密钥和令牌颁发者声明值。 对于使用 Azure AD v1 的应用,请省略 URL 中的 /v2.0。 在此方案中,请使用以下 URL:https://sts.windows.net/<Azure-AD-tenant-ID>
    允许的令牌受众 < application-ID-URI> 函数应用的应用 ID URI(资源 ID)。 对于你希望允许使用 Web 应用中的身份验证令牌的云应用或服务器应用,请在此处添加 Web 应用的应用 ID URI。 配置的客户端 ID 始终被隐式地视为允许的受众。 在此方案中,值为 https://management.azure.com。 稍后,在工作流中将函数操作设置为使用托管标识时,可以在“受众”属性中使用相同的 URI。 重要说明:此应用 ID URI 必须与 Azure AD 所需的值完全匹配,包括任何必需的尾随斜线。

    现在,你的版本如以下示例所示:

    显示逻辑应用注册和函数应用的标识提供者的屏幕截图。

    如果你是首次使用标识提供者设置函数应用,则还会显示“应用服务身份验证设置”部分。 这些选项可确定函数应用如何响应未经身份验证的请求。 默认选择将重定向所有使用新标识提供者登录的请求。 现在可以自定义此行为,也可以稍后通过选择“身份验证”设置旁边的“编辑”,在主“身份验证”页调整这些设置。 若要详细了解这些选项,请查看身份验证流 - Azure 应用服务和 Azure Functions 中的身份验证和授权

    否则,可以继续执行下一步。

  5. 若要完成创建应用注册的过程,请选择“添加”。

    完成后,“身份验证”页现在会列出应用注册的标识提供者和应用 ID(客户端 ID)。 函数应用现在可以使用此应用注册进行身份验证。

    有关详细信息,请参阅将应用服务或 Azure Functions 应用配置为使用 Azure AD 登录

  6. 将应用 ID(客户端 ID),供函数稍后在工作流的“受众”属性中使用。

  7. 返回到设计器,并使用内置的 Azure Functions 操作,按照使用托管标识验证访问权限的步骤操作。

后续步骤