2

I designed a PowerShell script that it's able to properly configure various settings of a Function App (including CORS e.g.). The Function App works and can be called from an Api Manegement service.

When the need arose to configure Azure AD, I've used Az/CLI to replicate exactly what I do using Portal UI (and what I set manually perfectly works). But it stopped working, APIM returns HTTP status code 401 (unauthorized).

The part of the script that configures Azure AD is the following:

# $add is a simple class that contains value to be configured
# actually AllowedTokens is always empty
if ($aad) {
    'Setting Function App AAD configuration.' | Write-Verbose
    $allowedTokens = if ($aad.AllowedTokens) { "--aad-allowed-token-audiences $($aad.AllowedTokens -join ' ')"  } else { '' }
    "az webapp auth update --name $name --resource-group $group --enabled $($aad.Enabled.ToString().ToLower())" +
        " --action LoginWithAzureActiveDirectory --aad-client-id $($aad.ClientId) --aad-client-secret $($aad.ClientSecret)" +
        " --token-store true" +
        " --aad-token-issuer-url $($aad.TokenIssuerUrl) $allowedTokens" |
        Invoke-Expression
    'Function App AAD configuration set.' | Write-Verbose
}

The first strange thing is that if I disable authentication/authorization,

enter image description here

I save settings, enable and save again everything start working.

So I've started again and launched the script. I've examined the resource.

az auth show says that unauthenticatedClientAction is set to RedirectToLoginpage.

az resource show says that unauthenticatedClientAction is set to null.

When I do the trick described above:

az auth show says that unauthenticatedClientAction is set to AllowAnonymous.

az resource show says that unauthenticatedClientAction is set to null.

So I think this is the important difference to make the Function App properly works (or better this is the way to properly configure it).

Since I've used this method with success for other settings, I've tried to set this property with Az/CLI:

az resource update --name web --resource-group $group --namespace Microsoft.Web --resource-type config `
    --parent "sites/$funcName" --set properties.siteAuthSettings.unauthenticatedClientAction=AllowAnonymous

The JSON returned as response shows nothing changed. Inspecting the resource confirms it.

One more thing, when I export the resource group I can't see any unauthenticatedClientAction in any Function App template.

What's the correct way to set unauthenticatedClientAction to AllowAnonymous?

Any help will be really appreciated!

gsscoder
  • 3,088
  • 4
  • 33
  • 49

1 Answers1

2

First, answer your question, to set unauthenticatedClientAction to AllowAnonymous, just use

az webapp auth update --name <functionapp-name> --resource-group <group-name> --action AllowAnonymous

enter image description here


Actually, when you do the trick in the portal, it will change the

enter image description here

to

enter image description here

This is the unauthenticatedClientAction setting.

Then the question is coming, I am not sure if you want to secure your azure function with Azure AD or not. Because when you set unauthenticatedClientAction to AllowAnonymous, your function will allow the anonymous request, the Azure AD auth will not take effect.

When the need arose to configure Azure AD, I've used Az/CLI to replicate exactly what I do using Portal UI (and what I set manually perfectly works). But it stopped working, APIM returns HTTP status code 401 (unauthorized).

Yes, the 401 error represents the Azure AD auth toke effect, if you enable the Azure AD auth(set Log in with Azure Active Directory), you need to get the access token for your client/user, then use the token to access the function. (Not sure how to implement it in APIM, I am not an expert in APIM:-))

For more details, you could check this blog and this post.

Joy Wang
  • 39,905
  • 3
  • 30
  • 54
  • Thanks for replying. Yes I want to secure **Function App** with **Azure AD**. I'll try to go deeply on this issue. The strange thing still persists. I can configure it manually and it works, same configuration with **Az/CLI** fails. It's weird! – gsscoder Apr 30 '20 at 08:42
  • @gsscoder Looks you don't understand my answer, it works because the `Action to take when request is not authenticated` setting was set as `Allow Anonymous requests(no action).` No matter which way you use to configure the function with Azure AD auth, if you don't pass the access token, it will not work. – Joy Wang Apr 30 '20 at 08:47
  • It's more clear now. I need time to ponder. Thank you – gsscoder Apr 30 '20 at 09:26
  • @gsscoder To get the token, you could refer to the way in this [question](https://stackoverflow.com/questions/61209502/how-to-enforce-aad-application-role-authorization-with-azure-functions/), all the AD Apps in the same tenant of your function could get the token to access the function. You could also restrict access the function to only AD Apps that have a specific application role, check my [solution](https://stackoverflow.com/a/61224922/9455659). You can also use a user account in your tenant to login the function directly, it depends on your requirement. – Joy Wang Apr 30 '20 at 09:36
  • 1
    Thank you. I've done further investigation. The real problem is the token. Now I'll try to solve it. :) – gsscoder Apr 30 '20 at 14:38
  • The consumer of the APIM didn't passed the token and it was set an unnecessary **Token Issuer Url** setting. Passing the _token_ and removed that settings, everything works fine. I think I've also made some confusion comparing automation and UI settings (worked too much these days!). Sorry. Now everything it's clear. – gsscoder May 01 '20 at 04:03