Reputation: 123
I have an Azure Function that is set up to use AAD Authentication (the latest (not Classic) method), and I can't get past the 401 error when I use Postman or a Custom Connector. I have followed the Microsoft Docs article on setting up a custom connector.
My initial test consisted of the following:
While this worked when configured using the Classic authentication method, I then configured Authentication the new way within the Function App, which caused all my requests to return a 401. When I configure the Function App to use a 302 for unauthenticated requests, I could authenticate with a browser request directed at HTTP triggered function. However, if I try to use Postman, test a Custom Connector or connect to the Function within a Logic App, I always get a 401. All the authentication configuration appears correct and user assignments are configured.
I have looked for tutorials or others that have configured a PowerApps connection with secured Azure Function, but I haven't been able to find what I'm looking for. I'd like to use the latest method to set up Authentication if possible, but if not, the alternative is the recreate the Function App and set up Authentication via the classic method (note: once you configure the new Authentication method, you can't go back and set it up via classic mode).
Within the Authentication
section, I have it set to Require Authentication (note: When changed to not require authentication, the api call works fine).
The application exposes the user_impersonation
api as described in the documentation (the custom app registration is authorized for this api)
The custom app registration (i.e. the connector app reg) is set up to use the api and is consented. I have generated a client secret as well for use by Postman.
Within LINQPad, I threw together some code to get the Access Token
using the connector app reg. However, I still get the same 401 error. I tried using both the hostname and the Function app auth app id - both resulted in a 401. The token come back successfully, but the call for the Function fails.
After following @bowman-zhu solution (removing /v2.0
from the Issuer URL), I was able to get past the 401 error. My next step was to test the custom connector again. Since this was the original pain point, I wanted to provide details of the solution.
Initially, I was still getting an error, so I decided to switch from Azure Active Directory
as the identity provider and instead use Generic Oauth 2
.
Having followed the Microsoft documentation for creating a custom connector, the Client id
and Client secret
were specific to the connector app registration. The Authorization URL
and Token URL
were pulled from the app registration as well (and even though they are v2.0, they still worked). I used the same value as the Authorization URL for the Refresh URL
. The scope was <guid>/.default
(where is the application id for the Function app's Authorization app registration).
After validating and updating the connector, I tested one of the API calls and everything finally worked as expected.
Upvotes: 0
Views: 1086
Reputation: 14080
Update:
Check your Issuer URL:
Or to change the accessTokenAcceptedVersion to 2:
Any way, make sure the issue url version is the same.
(I found there are still many problems with Authentication, and many things will not be automatically configured.)
Original Answer:
This is the problem you got:
You need to authorize:
For example, if you are using python, then:
1, The newest Authentication will not expose your function app automatically, so you need to add:
1, create a client ad app to access the api above.
2, use some code like below to get the token(client id and secret is getting from above ad app):
import requests
from azure.identity import ClientSecretCredential
import json
client_id = 'xxx'
tenant_id = 'xxx'
client_secret = 'xxx'
subscription_id = 'xxx'
credential = ClientSecretCredential(tenant_id=tenant_id, client_id=client_id, client_secret=client_secret)
print(credential.get_token('https://0416bowman.azurewebsites.net/.default'))
accesstoken = str(credential.get_token('https://0416bowman.azurewebsites.net/.default'))[19:1141]
print(accesstoken)
3, add the access token to the Authorization header, if you are using postman, you should do something like this:
And below url can let you check whether the token is correct:
Upvotes: 1