Azure Function AAD Authentication - Client Credentials Flow - oauth-2.0

I'm trying to figure out how to secure an azure function (service func) that should only be called from another azure function (client func) in the same tenant.
Here's what I've tried in the azure portal:
created a windows function app on a consumption plan
added a hello-world http triggered function with authorization level of "Anonymous"
tested I'm able to call the function anonymously
on the blade for the service func, selected "Authentication"
selected "Add identity provider"
chose "Microsoft"
"Create new app registration"
"Current tenant - Single tenant"
"Require authentication", "HTTP 401"
created a new app registration for the client func, making a note of the client_id and client_secret
I then configured postman to acquire a token from the azure ad (using the only tenant id in play), passing the client_id and client_secret from the app registration of the client func. In the post to the /token endpoint, I gave a grant_type value of "client_credentials".
On posting the request from postman, I received a response containing an access_token. I copied this and pasted into https://jwt.ms to check that all looked ok.
I configured another request in postman to issue a get to the hello-world function. This contained a "Authorization" header with a value of "Bearer " + the access_token received in the previous step.
Despite passing what seems to be a valid access token, the function app (which has no authentication bindings) return a 401 Unauthorized error.
I don't need authorization, just authentication.
Can anyone spot where I went wrong?

I now have this working. I found the following page helpful: Microsoft Doc
Key points:
App roles declared on the app registration of the service app
I didn't manually enter anything into the "Expose an API" page
No authorized client applications listed on the "Expose an API" page
When getting the access token, the scope should be set to the Application ID URI of the target service app registration + "/.default"
API permissions set on the app registration of the client service - these are "Application permissions" NOT "Delegated permissions"
From the function app, select Authentication then edit the identity provider. The value for "Allowed token audiences" needs to be the api://guid value from the "Application ID URI" value of the app registration for the target app service. I noticed that I had problems when using a non-guid value for this

Related

OIDC Azure AD token?

I am trying to configure a third party web application to use Azure AD as the OIDC provider. The authentication works fine, however I am looking for some claims and not able to find an ID or Access Token. Here is the flow as I am seeing it
Call to the login page of the web application. This gets a 302 redirect to the Microsoft OAuth endpoint as below
The URL is https://login.microsoftonline.com/-tenantid-/oauth2/v2.0/authorize?client_id=-clientid-&redirect_uri=-encodedCallbackURI-&response_type=code&scope=openid+email+profile&state=123 This does a 302 to below URL
Next call is to https://login.microsoftonline.com/-tenantid-/oauth2/v2.0/authorize?client_id=-clientid-&redirect_uri=-encodedCallbackURI-&response_type=code&scope=openid+email+profile&state=123&**sso_nonce=O.eyJ0eXAiOiJK......**&client-request-id=-guid-&mscrid=-guid- This returns a 200
Next is the redirect back to the hosted web application indicated in teh callback - https://webApplicationURL/callback?code=0.AQ4Ayjxg80......&state=123&session_state=5b7c2e43-9eab-4bb1-9f24-d020f144d30d
At this point, the user has successfully been authenticated. However, I would like to find the ID or Access Token received.
The sso_nonce(in #3) is in a JWT format but has no claims.
The code(in #4) doesn't have any of the claims either and doesnt really seem to be a JWT token format.
So where is the ID Token or Access Token that I can use to decode and see what claims are getting passed (or not)?
Thanks in advance,
Jake.
To get tokens while calling login page of the web application, you can execute the below request in browser by including response_type as id_token+token:
https://login.microsoftonline.com/<tenant_ID>/oauth2/v2.0/authorize?
client_id=da5daf42-xxxx-xxxx-xxxxxx04a52 //your AppID
&response_type=id_token+token //Required
&redirect_uri=https://jwt.ms //your Redirect URL
&response_mode=fragment
&scope=openid+profile+email
&state=12345
&nonce=678910
Make sure to enable tokens for your web application before executing the above request like below:
Go to Azure Active Directory -> App Registrations -> Your App -> Authentication -> Enable tokens -> Save
I tried to reproduce the same in my environment and got the below results:
When I executed the above-mentioned request in the browser, it asked me to sign in like below:
After successful sign-in, it took me to the redirect URL with tokens in the address bar like below:
When you copy-paste the above in Notepad or any, you can find both access_token and id_token like this:
I got the claims successfully when I decoded the token like below:
Reference:
OpenID Connect (OIDC) | Microsoft Docs

Configuring OAuth 2 for Sendgrid event webhook

I’m totally new to OAuth 2 but my current task requires me to use it to authenticate request from Sendgrid event webhook.
The only manual I found is this:
https://docs.sendgrid.com/for-developers/tracking-events/getting-started-event-webhook-security-features#oauth-20
And I tried the following:
1. I tried creating a new OAuth 2.0 Client IDs from google cloud console
I got the json file which contains: client_id, client_secret, token_uri; then I inputted them to Sendgrid.
However, when I tested it (by clicking the “Test your intergration”), nothing was sent to my endpoint.
I think that sendgrid couldn’t get the access token from the OAuth service or authorization server so it didn’t send any request to my URL.
2. I tried creating a Auth0 account and I also got client_id, client_secret, token_uri
I tested it again and nothing is sent to my endpoint, but this time, when I checked the log from Auth0, I saw this error:
No audience parameter was provided, and no default audience has been configured.
Faced with the same issue.
On the Auth0 side, we can set 'default audience' on the Tenant level (not on each application). It isn't enjoyable.
On Sendgrid they don't send audience param (they expect that you can fetch access token only by client id and client secret)...

Authenticate Azure API Management with OAuth2 using Azure AD

I am trying to secure APIM APIs using OAuth2 via AzureAD by reading the article: Protect a web API backend in Azure API Management by using OAuth 2.0 authorization with Azure AD
AzureAPIM - OAuth2
Authorization endpoint URL (v1): https://login.microsoftonline.com/{tenant}/oauth2/authorize
Token endpoint URL (v1): https://login.microsoftonline.com/{tenant}/oauth2/token
Client ID: client-app id
Redirect URI: (deprecated portal): https://xxx-api.portal.azure-api.net/docs/services/auth1/console/oauth2/authorizationcode/callback
AzureAD - backend-app:
scope: Files.All
AzureAD - client-app:
secret key: xxx
Redirect url: ONLY WORK with deprecated portal in APIM (https://xxx-api.portal.azure-api.net/docs/services/auth1/console/oauth2/authorizationcode/callback)
For Demo Conference API, Add Validate JWT policy to Inbound processing where 3a0cf09b- is tenant id and b7c31179- is backend-app application id:
In Developer portal, the authentication to AzureAD is successful with a return token:
However the authorization is failed with calling the API:
Inspecting the received token in jwt.io, I found that the "aud": "00000003-0000-0000-c000-000000000000" is not backend-app application id:
{
"aud": "00000003-0000-0000-c000-000000000000",
"iss": "https://sts.windows.net/3a0cf09b-xxx/",
"app_displayname": "client-app",
"appid": "05a245fb-xxx",
"scp": "Files.Read User.Read profile openid email",
"tenant_region_scope": "OC",
"tid": "3a0cf09b-2952-4673-9ace-0e1bf69ee23a",
"unique_name": "user1#xxx.onmicrosoft.com",
}
API Test HTTP response trace shows the error on validate-jwt:
validate-jwt (-0.138 ms)
{
"message": "JWT Validation Failed: Claim value mismatch: aud=b7c31179-xxx.."
}
Replacing aud by the value in the token 00000003-0000-0000-c000-000000000000 or removing the required-claims in the validate-jwt policy to get it working.
Any idea please?
From your error report, it is indeed a 401 error, that is, your aud does not match the api you want to call, I use the auth code flow to do a simple demonstration for you:
First expose the api of the back-end application and add the client application.
Next,under 'API permissions', give your front-end application access to your backend api:
Under 'API permissions' click on 'Add permission', then click on the 'My APIs' tab.
Find your backend application and select the appropriate scope.
Click 'Add permissions'.
Grant admin consent for your APIs.
Get token:
Parse the token:
It seems you choose v1 endpoint of OAuth2 authorization but not v2 endpoint, so the value of aud in access token should be like b7c31179-xxxx.... but not api://b7c31179-xxxx..... So there are no mistakes in your steps of get access token.
According to some test in my side, the cause of this problem is you did not specify a parameter resource with the value of the backend-app application id when you configure OAuth2.0 in your APIM. The document you refer to also mentions this (I test with not specify this parameter, it shows same problem with yours)
So to solve this problem, please go to your APIM and click "OAuth 2.0" tab, edit the item you created. Add a parameter resource with value of the backend-app application id.
Note: When you add the parameter resource and click "Save" button, please open the item again and check if the "Client secret" box is empty. When I test in my side, the "Client secret" box shows empty after add parameter resource, it may be a bug on that page. If "Client secret" is empty, it might show error message like The request body must contain the following parameter: 'client_assertion' or 'client_secret' when you get the access token in Developer portal.

Bad response from IdP in Auth Code Exchange when Linking account for Google Assistant

I'm having issues with trying to set up account linking with Google Assistant.
I'm using Azure AD B2C for my identity provider.
I've created a User flow so I have a authorize and token endpoint set up and I created an Azure AD Application so I have an App Id, and App Secret and I set the redirect URL as https://oauth-redirect.googleusercontent.com/r/{google-project-name}/.
My Google account linking settings are show below:
Client ID is the App Id of the application I created in Azure AD.
Client Secret is the app secret of of the application I created in Azure AD
Auth URL is:
https://{b2c-name}.b2clogin.com/{b2c-name}.onmicrosoft.com/oauth2/v2.0/authorize?p={sign-in-policy-name}
Token URL is:
https://{b2c-name}.b2clogin.com/{b2c-name}.onmicrosoft.com/oauth2/v2.0/token?p={sign-in-policy-name}
When I got to https://console.actions.google.com/project/{google-project-name}/simulatorand try to go through the auth flow it pops up the box I put in my user name and password and then just stops.
I can see in Fiddler it redirects back to the redirect URL and then there is a 400.
{
"error": {
"code": 400,
"message": "Bad response from IdP in Auth Code Exchange",
"status": "FAILED_PRECONDITION"
}
}
When I look in Fiddler at the request to the redirect URL it looks as expected with a state and code like this documentation says it should so I'm not sure what I'm doing wrong. I've double checked my App Id and regenerated the key.
https://oauth-redirect.googleusercontent.com/r/YOUR_PROJECT_ID?code=AUTHORIZATION_CODE&state=STATE_STRING
I've seen a few questions with similar error messages but none of the fixes suggested helped or applied.
Any help would be appreciated.

Calling customer service results in 401 Unauthorized

We are trying to connect to a custom Dynamics 365 Finance service operation but are struggling to authorize.
We've set up an app registration
Redirect_uri set to the dynamics url (root)
Enabled implicit grant (both for access tokens and ID tokens)
Single tenant
Assigned the "Dynamics ERP > CustomService.FullAccess" API permission
Assigned the "Dynamics ERP > Odata.FullAccess" API permission
Assigned "Dynamicd ERP > Connector.FullAccess" API permission + granted admin consent for entire AD
Created a secret
We've added the Application (client ID) within the Dynamics 365 environment with a user which has System Administrator role
We can successfully retrieve access tokens both via Postman and .NET (Microsoft.IdentityModel.Clients.ActiveDirectory)
we tried to reach both https://xxxxxxdevaossoap.cloudax.dynamics.com &https://xxxxxxdevaos.cloudax.dynamics.com
Yet when we call custom services, we get a 401 UnAuthorized
A call to Odata also fails for the same reason.
Verify resource in your request for OAuth token (and verify token at https://jwt.io for aud (Audience) field).
It should be same as your primary url without / at the end (like https://d365fo-10-12345678baef10230aos.cloudax.dynamics.com).
Also verify that Azure Active Directory applications (mi=SysAADClientTable) Client Id is equal to appid field in the token (and without any special characters).
You can always inspect Windows Event Log Microsoft-Dynamics-AX-WebApi/Operational
There is good information like this:
Source: Microsoft-Dynamics-AX-WebApi
Category: WebApiOwinConfigurationMissingError
Level: Error
Description: Web API Owin Authentication Configuration Missing Error
infoMessage: Can read the token but failed validating token with exception
'IDX10214: Audience validation failed.
Audiences: 'https://d365fo-10-12345678baef10230aos.cloudax.dynamics.com/'.
Did not match: validationParameters.
ValidAudience: 'null' or validationParameters.ValidAudiences:
'https://d365fo-10-12345678baef10230aos.cloudax.dynamics.com,
00000015-0000-0000-c000-000000000000,
Microsoft.ERP''

Resources