Search code examples
azureazure-functionsazure-ad-b2cazure-resource-managerazure-rm-template

ARM template for Azure Function with V2 Authentication


I have been using an ARM template to deploy an Azure Function with Azure Ad b2c authentication using V1 authentication.

    "resources": [{
        "name": "[concat(parameters('appName'), '/authsettings')]",
        "apiVersion": "2016-08-01",
        "type": "Microsoft.Web/sites/config",
        "location": "[resourceGroup().location]",
        "dependsOn": [
          "[resourceId('Microsoft.Web/sites', parameters('appName'))]"
        ],
        "properties": {
          "enabled": true,
          "unauthenticatedClientAction": "RedirectToLoginPage",
          "tokenStoreEnabled": true,
          "clientSecret":"[parameters('b2cClientSecret')]",
          "clientId": "[parameters('b2cClientId')]",
          "issuer": "[parameters('b2cMetadataDocumentUrl')]"
        }
      }] 

Everything has been working fine until I started getting messages to upgrade from the classic authentication experience in the Azure Portal.

enter image description here

Since getting this message deployments have failed with the message below

##[error]At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/DeployOperations for usage details.
##[error]Details:
##[error]undefined: Cannot execute the request for site app-fun-my-af because the site is running on auth version v2.
##[error]Check out the troubleshooting guide to see if your issue is addressed: https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/deploy/azure-resource-group-deployment?view=azure-devops#troubleshooting
##[error]Task failed while creating or updating the template deployment.
Finishing: AzureResourceManagerTemplateDeployment

I have fixed this by moving to the V2 template as below and using an app setting for the client secret:

"resources": [
       {
        "name": "[concat(parameters('appName'), '/authsettingsV2')]",
        "apiVersion": "2021-03-01",
        "type": "Microsoft.Web/sites/config",
        "location": "[resourceGroup().location]",
        "dependsOn": [
          "[resourceId('Microsoft.Web/sites', parameters('appName'))]"
        ],
        "properties": {
          "globalValidation": {            
            "requireAuthentication": true,
            "unauthenticatedClientAction": "RedirectToLoginPage"
          },
          "login": {
            "tokenStore": {
              "tokenStoreEnabled": true
            }
          },   
          "customOpenIdConnectProviders": {
            "clientSecretSettingName":"B2C_CLIENT_SECRET",
            "clientId": "[parameters('b2cClientId')]",
            "issuer": "[parameters('b2cMetadataDocumentUrl')]"
          }          
        }        
      }
      ]  

This doesn't error and adds authentication but does not correctly add the Identity Provider. Does anyone have an example of a working template with authsettingV2 for a custom provider they could share to give me an idea where I am going wrong?


Solution

  • The customOpenIdConnectProviders let you add multiple providers so you need to give it a name to the custom provider. Something like that should work:

    {
      ...
      "customOpenIdConnectProviders": {
        // name of the provider (could be anything)
        "b2c": {
          "registration": {
            "clientCredential": {
              "clientSecretSettingName": "B2C_CLIENT_SECRET"
            },
            "clientId": "[parameters('b2cClientId')]",
            "openIdConnectConfiguration": {
              "wellKnownOpenIdConfiguration": "[parameters('b2cMetadataDocumentUrl')]"
            }
          }
        }
      }
      ...
    }
    

    you could also configure it manually from the portal then query the ARM API to get the configuration:

    az rest --method get `
      --uri /subscriptions/<subscription-id>/resourceGroups/<resourcegroup-name>/providers/Microsoft.Web/sites/<function-app-name>/config/authsettingsV2?api-version=2022-03-01
    

    Full config:

    {
      "location": "[parameters('location')]",
      "type": "Microsoft.Web/sites/config",
      "apiVersion": "2021-03-01",
      "name": "[concat(parameters('appName'), '/authsettingsV2')]",
      "dependsOn": ["[resourceId('Microsoft.Web/sites', parameters('appName'))]"],
      "properties": {
        "globalValidation": {
          "requireAuthentication": true,
          "unauthenticatedClientAction": "Return401"
        },
        "httpSettings": {
          "forwardProxy": {
            "convention": "NoProxy"
          },
          "requireHttps": true,
          "routes": {
            "apiPrefix": "/.auth"
          }
        },
        "identityProviders": {
          "customOpenIdConnectProviders": {
            "b2c": {
              "registration": {
                "clientCredential": {
                  "clientSecretSettingName": "B2C_CLIENT_SECRET"
                },
                "clientId": "[parameters('b2cClientId')]",
                "openIdConnectConfiguration": {
                  "wellKnownOpenIdConfiguration": "[parameters('b2cMetadataDocumentUrl')]"
                }
              }
            }
          }
        },
        "login": {
          "cookieExpiration": {
            "convention": "FixedTime",
            "timeToExpiration": "08:00:00"
          },
          "nonce": {
            "nonceExpirationInterval": "00:05:00",
            "validateNonce": true
          },
          "preserveUrlFragmentsForLogins": false,
          "routes": {},
          "tokenStore": {
            "azureBlobStorage": {},
            "enabled": true,
            "fileSystem": {},
            "tokenRefreshExtensionHours": 72.0
          }
        },
        "platform": {
          "enabled": true,
          "runtimeVersion": "~1"
        }
      }
    }