简体   繁体   English

使用服务主体对 Azure 函数应用进行身份验证的正确方法是什么?

[英]What is the correct way to authenticate an Azure function app using a service principal?

I have some code I want to automate with an Azure function app.我有一些代码想用 Azure 函数应用程序自动化。 The code is for cloud governance purposes and will only be used internally by the governance team.该代码用于云治理目的,仅供治理团队内部使用。 The purpose of the code is to retrieve information about public IP addresses and write it to a blob.该代码的目的是检索有关公共 IP 地址的信息并将其写入 blob。 It will do this automatically every day.它会每天自动执行此操作。

I would like to use a dedicated cloud governance service principal to carry out the actions instead of a user account.我想使用专用的云治理服务主体而不是用户帐户来执行操作。 How can I authenticate the service principal for the function?如何验证函数的服务主体? Do I need to use Key Vault and authenticate within the code?我是否需要使用 Key Vault 并在代码中进行身份验证? If so, how can I give the function permissions to use Key Vault?如果是这样,我如何授予该功能使用 Key Vault 的权限?

The high level steps are:高级步骤是:

  1. Create an AAD Application (service principal).创建 AAD 应用程序(服务主体)。 Assign it whatever permissions you want.为其分配任何您想要的权限。
  2. Create a Key Vault创建密钥保管库
  3. Create a certificate in Key Vault (see CreateKVSPNCertificate.ps1 below)在 Key Vault 中创建证书(请参阅下面的 CreateKVSPNertificate.ps1)
  4. Add that certificate to the AAD Application (see CreateKVSPNCertificate.ps1 below)将该证书添加到 AAD 应用程序(请参阅下面的 CreateKVSPNertificate.ps1)
  5. Create a managed identity for the Azure Function app为 Azure Function 应用创建托管标识
  6. Give the Function app's managed identity Get Secrets permission on the Key Vault在 Key Vault 上授予 Function 应用的托管标识获取机密权限
  7. In your Functions code, use AzureServiceTokenProvider along with a connectionstring to your KeyVault to authenticate your Functions code as the service principal from step #1.在您的 Functions 代码中,使用 AzureServiceTokenProvider 和 KeyVault 的连接字符串将您的 Functions 代码作为第 1 步中的服务主体进行身份验证。 (see GetAuthCredsFromKeyVault below) (请参阅下面的 GetAuthCredsFromKeyVault)

CreateKVSPNCertificate.ps1创建KVSPN证书.ps1

# This script will have Key Vault create a certificate and associate the certificate with an Azure AD Application.  
# This allows applications to get the private key (secret) from Key Vault to authenticate as the service principal associated with the Azure AD app.

[CmdletBinding()]
param(
  [Parameter(Mandatory = $true)]
  [String]$keyVaultName,
  [Parameter(Mandatory = $true)]
  [String]$appId,
  [Parameter()]
  [int]$validityInMonths = 12
)

# Key Vault will create a certificate, returning the cert from this function so the public key can be added to the AAD Application
function New-KeyVaultSelfSignedCert {
    param($keyVault, $certificateName, $subjectName, $validityInMonths, $renewDaysBefore)

    # Define the configuration for how the certificate will be created
    $policy = New-AzKeyVaultCertificatePolicy `
                -SubjectName $subjectName `
                -ReuseKeyOnRenewal `
                -IssuerName 'Self' `
                -ValidityInMonths $validityInMonths `
                -RenewAtNumberOfDaysBeforeExpiry $renewDaysBefore

    # Have Key Vault create the certificate.  This returns an operation status that needs to be waited on until it is complete
    $op = Add-AzKeyVaultCertificate `
                -VaultName $keyVault `
                -CertificatePolicy $policy `
                -Name $certificateName

    if ($op -eq $null)
    {
        # Certificate may have been soft-deleted which means the name is still reserved.
        if ((Get-AzKeyVaultCertificate -VaultName $keyvault -InRemovedState).Count -gt 0)
        {
            # Purge the soft deleted key and try adding the new one again
            # If the Purge fails with "Operation returned an invalid status code 'Forbidden'", then make sure your account explicitly has the Purge feature enabled in the Key Vault Access Policies (this access is not automatically granted)
            Write-Host "Previous certificate with same name $certificateName was in soft-delete state.  Attempting to Purge previous certificate and create new one.  Purge may take some time, in case of failure retry after a couple minutes."
            Remove-AzKeyVaultCertificate -VaultName $keyVault -Name $certificateName -InRemovedState -Force
            Start-Sleep -Seconds 15
            $op = Add-AzKeyVaultCertificate `
                -VaultName $keyVault `
                -CertificatePolicy $policy `
                -Name $certificateName
        }
    }

    while ( $op.Status -eq 'inProgress' ) 
    {
        Start-Sleep -Seconds 1
        $op = Get-AzKeyVaultCertificateOperation -VaultName $keyVault -Name $certificateName
    }
    if ($op.Status -ne 'completed')
    {
        Write-Error "Add-AzKeyVaultCertificate failed to complete"
        Write-Error $op
        return $null
    }

    # Get the certificate that was just created and return it.  This gets the public cert, not the private cert
    (Get-AzKeyVaultCertificate -VaultName $keyVault -Name $certificateName).Certificate
}

# Get the Azure AD Application in order to get the display name
$existingApp = Get-AzADApplication -ApplicationId $appId
$appName = $existingApp.DisplayName

if ($existingApp = $null)
{
    Write-Error "Couldn't find existing AAD Application $appId"
    break
}

# Have Key Vault create a certificate
$certName = "SPCert-" + $appName
$cert = New-KeyVaultSelfSignedCert -keyVault $keyVaultName `
                                   -certificateName $certName `
                                   -subjectName "CN=$appName" `
                                   -validityInMonths $validityInMonths `
                                   -renewDaysBefore 1

if ($cert -eq $null) { break }

Write-Output ""
Write-Output "Certificate generated with:"
Write-Output "   Thumbprint = $($cert.Thumbprint)"
Write-Output "   Secret Name = $certName"
$certString = [Convert]::ToBase64String($cert.GetRawCertData())
# Associate the public key with the Azure AD Application
New-AzADAppCredential -ApplicationId $appId -CertValue $certString -EndDate $cert.NotAfter.AddDays(-1)

In Functions code, authenticate using the Key Vault certificate在 Functions 代码中,使用 Key Vault 证书进行身份验证

        private AzureCredentials GetAuthCredsFromKeyVault()
        {
            string AuthVaultName = System.Environment.GetEnvironmentVariable("AuthVaultName");
            string AuthAppId = System.Environment.GetEnvironmentVariable("AuthAppId");
            string AuthSecretName = System.Environment.GetEnvironmentVariable("AuthSecretName");
            string connectionString = string.Format("RunAs = App; AppId = {0}; KeyVaultCertificateSecretIdentifier = https://{1}.vault.azure.net/secrets/{2}", AuthAppId, AuthVaultName, AuthSecretName);

            AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider(connectionString);
            string accessTokenARM = azureServiceTokenProvider.GetAccessTokenAsync("https://management.azure.com").Result;
            string accessTokenGraph = azureServiceTokenProvider.GetAccessTokenAsync("https://graph.windows.net").Result;
            AzureCredentials creds = new AzureCredentials(new TokenCredentials(accessTokenARM), new TokenCredentials(accessTokenGraph), Constants.TenantId, AzureEnvironment.AzureGlobalCloud);

            return creds;
        }

暂无
暂无

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

相关问题 Azure 服务主体创建 - 使用 Azure 函数 - Azure Service Principal creation - using Azure function 如何使用应用程序 ID(服务主体)的令牌向 Azure Devops 进行身份验证? - How to authenticate to Azure Devops by using token of an Application ID(service principal)? 在 Azure 中存储服务主体凭据以使用 Python 对 Key Vault 进行身份验证 - Storing Service Principal Credentials in Azure to Authenticate Key Vault using Python 是否可以通过Java Azure SDK使用服务主体向CosmosDB进行身份验证? - Is it possible to authenticate to CosmosDB using a service principal with the Java Azure SDK? Azure DevOps 版本 - terraform 导入失败,并显示“使用服务主体进行身份验证” - Azure DevOps Release - terraform import fails with 'Authenticate using a Service Principal' 如何使用服务主体和 Python SDK 对 Azure 进行身份验证? - How do I authenticate to Azure using a Service Principal and the Python SDK? 什么是 Azure 服务主体? - What is Azure Service Principal? How to call a protected API from an Azure Function App using the identity of the authenticated caller (Service Principal) to the Function App? - How to call a protected API from an Azure Function App using the identity of the authenticated caller (Service Principal) to the Function App? 有没有办法通过 Azure 函数向 Azure 服务主体发送电子邮件? - Is there any way of sending an email to Azure Service principal through an Azure function? 使用 ACR 访问权限配置 azure 应用服务实例的正确方法是什么? - What is the correct way to provision an azure app service instance with ACR access?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM