为具有身份验证的应用服务部署 ARM 模板时自动创建应用服务标识

Posted

技术标签:

【中文标题】为具有身份验证的应用服务部署 ARM 模板时自动创建应用服务标识【英文标题】:Automtically create app service identity when deploying an ARM template for App Service with authentication 【发布时间】:2018-12-09 15:23:58 【问题描述】:

我一直在努力解决 Azure 应用服务身份验证问题。我正在运行 CI/CD 管道,并希望使用 ARM 模板配置应用服务身份验证。请参阅此处(部分)我的模板:


  "name": "[parameters('apiAppName')]",
  "type": "Microsoft.Web/sites",
  "location": "[resourceGroup().location]",
  "apiVersion": "2015-08-01",
  "dependsOn": [
    "[resourceId('Microsoft.Web/serverfarms', parameters('apiHostingPlanName'))]"
  ],
  "properties": 
    "name": "[parameters('apiAppName')]",
    "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('apiHostingPlanName'))]",
    "siteConfig": 
      "siteAuthEnabled": true,
      "siteAuthSettings": 
        "unauthenticatedClientAction": 0,
        "defaultProvider": 0,
        "tokenStoreEnabled": true,
        "clientAffinityEnabled": false 
       
    
  

当部署它时,它仍然将所有身份验证提供程序显示为未配置。

要配置 AAD 提供程序,我只提出了两个解决方案:

使用门户配置它。不是我想要的,手动点击无法与持续交付相结合 在我的发布管道中使用 Azure Powershell 创建(如果不存在)具有客户端密码和客户端 ID 的应用注册,并在 ARM 模板中指定。

我想知道,有什么方法可以自动创建所需的应用程序身份?可能使用/结合托管服务标识

【问题讨论】:

【参考方案1】:

我测试了不同的选项以使其仅使用 Arm 模板来部署 web 应用程序并直接启用身份验证,但它似乎不起作用。我采用正确 CI/CD 方式的方法是使用 Azure CLI 命令添加额外任务,启用身份验证并分配应用程序 clientId。 我的任务:

- task: RalphJansen.Azure-AD-Application-Management.New-Azure-AD-Application.New-Azure-AD-Application@2
  displayName: 'New Azure AD Application'
  inputs:
   azureSubscription: 'SubscriptionID'
   name: '$(apiName)'
   signOnUrl: 'https://$(apiName).azurewebsites.net'

- task: AzureResourceGroupDeployment@2
    displayName: 'Create WebApp'
    inputs:
     azureSubscription: 'SubscriptionID'
     resourceGroupName: '$(ResourceGroup)'
     location: 'Canada East'
     csmFile: '$(System.DefaultWorkingDirectory)/_build/drop/azuredeploy.json'
     overrideParameters: '-apiName $(apiName) -appServicePlanName $(appServicePlanName)'

- task: AzureCLI@1
  displayName: 'Update WebApp to do Oauth authentification & enable Oauth2ImplicitFlow'
  inputs:
    azureSubscription: 'SubscriptionID'
    scriptLocation: inlineScript
    inlineScript: |
     call az webapp auth update --name $(apiName) --aad-client-id $(out.ApplicationId) --action LoginWithAzureActiveDirectory --enabled true --resource-group "$(ResourceGroup)" --aad-token-issuer-url "https://sts.windows.net/your AAD ID here" --token-store true
     call az ad app update --id $(out.ApplicationId) --oauth2-allow-implicit-flow true

【讨论】:

【参考方案2】:

可能类似于...在现有的 Microsoft.Web/sites 部分下添加一个资源数组。


    "name": "authsettings",
    "type": "config",
    "apiVersion": "2015-08-01",
    "dependsOn": [ 
       "[resourceId('Microsoft.Web/sites/', variables('webAppName'))]" 
    ],
    "properties": 
        "enabled": true,
        "httpApiPrefixPath": null,
        "unauthenticatedClientAction": "RedirectToLoginPage",
        "tokenStoreEnabled": true,
        "allowedExternalRedirectUrls": null,
        "defaultProvider": "AzureActiveDirectory",
        "clientId": "[variables('clientId')]",
        "clientSecret": "[variables('clientSecret')]",
        "issuer": "[concat('https://sts.windows.net/', subscription().tenantId, '/')]",
        "allowedAudiences": [
        "[concat('https://', variables('fqdn'), '/.auth/login/aad/callback')]"
        ],
        "additionalLoginParams": null,
        "isAadAutoProvisioned": false
    
  

【讨论】:

这个模板很可能适用于设置我认为的正确提供者。但是,这里我们又回到了必须指定 clientSecret 的问题上,而对于 App Service,您不会得到它。我认为结论仍然是,如果不先向 ADD 提供身份,这是不可能的。【参考方案3】:

可能有点晚了,但如果你还没有找到答案...

资源[]

        "apiVersion": "2018-02-01",
        "type": "Microsoft.Web/sites",
        "kind": "app",
        "name": "[variables('webAppName')]",
        "location": "[parameters('location')]",
        "identity": 
            "type": "SystemAssigned"
        ,

并将 servicePrincpalId 包含在输出中,以便它可以重新用于设置对所需资源 keyvault 的访问;斑点; sql等

    "outputs": 
        "appServicePrincipalId": 
            "type": "string",
            "value": "[reference(concat(resourceId('Microsoft.Web/sites/', variables('webAppName')),'/providers/Microsoft.ManagedIdentity/Identities/default'), '2015-08-31-PREVIEW').principalId]"
        ,

【讨论】:

这确实会为应用程序添加一个身份并将生成的主体 id 返回给调用者。但是,我看不出这如何有助于在应用程序自身上启用身份验证?我的意思是,应用程序的用户必须登录? 对不起,我误解了问题的最后一部分。 AFAIK 它仍然需要创建一个 AD 应用程序,而不是重新使用系统托管标识,尽管我可能需要在限制较少的租户中对此进行测试。有关设置的一些提示,请参阅 resources.azure.com/subscriptions/subscriptionid/resourceGroups/resource-group/providers/Microsoft.Web/sites/site-name/config/authsettings/list。

以上是关于为具有身份验证的应用服务部署 ARM 模板时自动创建应用服务标识的主要内容,如果未能解决你的问题,请参考以下文章

使用 arm 模板部署存储帐户时遇到问题

arm模板部署时动态获取管理组id的值

如何安排部署ARM模板?

使用ARM模板部署自动扩展的Linux VMSS

使用ARM模板部署自动扩展的Linux VMSS

具有 Azure 应用服务身份验证的 .NET Core 应用