Client Credentials authorization with Azure Active directory and Swagger - azure

Need to get the authorization token to access my app running on localhost. I query the AAD token endpoint for the token from the Swagger OAuth2 client in UseSwaggerUi3. I get the CORS error that endpoint is not allowing the cross origin requests from my localhost. How can I fix this?
[Edit]
I'm able to get the token if I send a POST request to the same endpoint using Fiddler.

You can't use client credentials flow from the front-end. Firstly because your secret is visible to anyone who sees the page.
Secondly because Azure AD blocks cross origin requests to its token endpoint. (as you saw)
You need to use authorization code or implicit flow with user context. Or build another API which gets the token in the back-end and calls the other API with it.

CORS are the cross origin resource, it will allow two different web apps working on 2 different origin to communicate with each other.
There are two ways to enable cors
1) go-to azure - web apps - setting column search - cors.
2) add new cors header as "*", which means it will allow all the urls which are requesting the web app, you also provide specific one url.
3) save it.
4) second approach is allow cors header from your code in web config headers.

Related

How to use Oauth 2.0 Authorization in Logic App's HTTP connector

There is an API that I need to iteratively return data from in an Azure Logic App. To do this I need two HTTP steps, 1 to receive an access token and the other to use the token to be returned the data. Unfortunately, I can only receive the token through Oauth 2.0 Authorization and Azure Logic App does NOT have that authorization feature built into the connector (But I see Active Directory OAuth which seems different). Is there any way around this?
Trying to achieve the below. But the only concern I have is with Step 2: Logic doesn't have Oauth 2.0 Authorization
The available OAuth Authentication option is OAuth Active Directory which is specific to Azure and my requirement is for an external URL which only has client Id & client secret information
Tried below. Getting error
Logic app DOES have the Authorization feature built into the http connector. Click on the Add new parameter dropdown.
But this is for specific cases. In your case the credentials are in the body so you can use the native connector without any Authorization. Just add the headers and body that you need as below.
The body I used is like below (to match your body requirements):
{"client_id":"#{triggerBody()?['client_id']}","client_secret":"#{triggerBody()?['client_secret']}","grant_type":"client_credentials"}
If successful, You will need to parse the response so you can use the token from the response in the next actual call to the API.

CORS issue while trying to access https://login.microsoftonline.com/common/oauth2/v2.0/token' to "acquireTokenOnBehalfOf" from localhost & app domains

We are enabling SSO for our Teams App using the below documentation:
https://learn.microsoft.com/en-us/microsoftteams/platform/tabs/how-to/authentication/tab-sso-graph-api?tabs=nodejs#configure-code-to-fetch-access-token-using-msal
This is the code that is used to acquire a token using MSAL:
msalClient.acquireTokenOnBehalfOf({
authority: `https://login.microsoftonline.com/${tid}`,
oboAssertion: token,
scopes: scopes,
skipCache: true
})
When we try to acquire token by passing tenantId or common as authority, the token API is failing because of CORS issue in both local as well as the development environment.
Access to XMLHttpRequest at 'https://login.microsoftonline.com/common/oauth2/v2.0/token' from origin *** has been blocked by CORS policy
We have added the domains in expose API during registration.
Is there any other config which is needed to allow requests from other defined origins (localhost and other domains)?
It sounds like you're using client-side code to get this token - if so, very importantly, you've misunderstood how this works. An 'OnBehalfOf' token call should ONLY be made from a backend server, in which case CORS would not apply. There is 'javascript' code for this because you might have a Node-based backend, NOT because you're meant to use it from in the browser.
The only call you need to make from your front-end code is to
microsoftTeams.authentication.getAuthToken()
Here's a more detailed answer I've given before - please have a look and also check out the excellent video and blog post I've linked in there: Problem with getting SSO Auth token from Microsoft Teams

Azure api OAuth2 implicit flow works on http but not on htt

I created an Api in azure and recently tried to change to authentication method to access it via OAuth2.
I requested a token using https://login.microsoftonline.com/[TENANT]/oauth2/v2.0/token/ and tried to use it to access my api via postman.
Then I tried to use the received token to make a request to my api:
I used Postman's Authorization pane to specify OAuth2.0 as the authentication method and set the Grant Type configuration to "implicit" and sent a request.
Configured like this, the request goes through using the "http" version of my api but as soon as I try to use the "https" version, I get a 401 error "Unauthorized".
Have I configured my api wrong ? Or am I using the wrong url to authenticate ?
Thanks a lot for your time.
After a lot of research I found out what was wrong :
I had to add the application ID in the allowed token audiences of identity provider (in the azure app service, navigate to authentication > locate the identity provider > click on edit > at the bottom of the page add the your app registration's application ID. For good measure I also added api://[APPLICATION ID]/.default and api://[APPLICATION ID]
There was still some authentication code left in the source code of my api. When I was trying to connect I sometime had a response which consisted of HTML titled "Sign in to your account". It was caused by a segment of code in the startup.cs file of my api which verified the user who made the request against my Azure AAD. After removing it I no longer had the error

Can a browser app (spa) access MS Graph without a logged in user?

I can register an app in Azure as 'Web' application, specify the permissions it needs to read from Graph, consent to the permissions as an admin, create a client secret.
I try using the client secret in the app to request an access token. But MS identity platform rejects grant_type=client_credentials /token endpoint requests that come from a browser.
But how does it even know the caller is a browser? The same requests works when it is sent via Postman!
Obviously, CORS makes the difference: When a browser executes the request from myserver/myapp.js, it sets the 'Origin' header in the request going to login.microsoftonline.com and, by registration as a 'Web' app, does not send back an Access-Control-Allow-Origin response to the browser - the browser refuses to get the response. On the other hand, when Postman executes the request, it uses it's cloud agent to run the request. The agent doesn't send an 'Origin' header and doesn't check the response header.
Is there a different way an app in a browser can call Graph without a logged in user?
The answer is No. based on this Azure AD official doc, if you want to get an access token on SPA, only OAuth 2.0 implicit grant flow and OAuth 2.0 authorization code + PKCE flow are supported but both of these two flows require users' interaction to login.
Cross-origin resource sharing (CORS) is a browser mechanism. Your request is blocked by your browser, Azure AD endpoint does not care about what kind of app sends the request.
This is a similar question answered by MVP: #juunas.

Azure FHIR Proxy using Postman - 401 You do not have permission to view this directory or page

I have set up an instance of Azure FHIR with an Azure FHIR proxy using this tutorial:
https://github.com/microsoft/health-architectures/tree/master/FHIR/FHIRProxy##configuration
I am unable to call the proxy without getting the following error message:
You do not have permission to view this directory or page.
I have created a token successfully using the following tutorial:
https://learn.microsoft.com/en-us/azure/healthcare-apis/access-fhir-postman-tutorial
I have created an app service principal in Azure with the permissions to access the FHIR proxy:
https://func-fhir-proxy-2.azurewebsites.net
I am generating the token using the following in postman:
Auth URL: https://login.microsoftonline.com/e34c8e67-182a-4085-9dc0-39a38dddea12/oauth2/authorize/?resource=https://func-fhir-proxy-2.azurewebsites.net
Access Token URL: https://login.microsoftonline.com/e34c8e67-182a-4085-9dc0-39a38dddea12/oauth2/token
Client ID: 4d138742-44c0-42cb-9878-8647a1d2ef17
Client Secret: Well..that's a secret!
Scope: openid profile
State: 12345
Postman returns 3 tokens: Access_token, Refresh_token, Id_token.
I have tried each token and all return the same 401 error.
ID token JWT looks like this:
I have tried calling the FHIR proxy API's, due to the tutorial I am not 100% which are the correct URLs:
https://func-fhir-proxy-2.azurewebsites.net/api/fhirproxy/Patient
https://fhir-test-apis.azurehealthcareapis.com/Patient/
None of this works, I just keep getting the same error. Does anyone know what I am doing wrong? Should I be calling the FHIR proxy API using the token? If so, why is the API not letting me in?
I managed to fix the issue. I found that the resource ID was needed in the auth URL:
This can be obtained from Enterprise Applications:
Also, creating two separate app registrations:
The link ending with ".../api/fhirproxy/Patient" is correct for the proxy deployment.
I'd suggest that you do a quick test that you can access the FHIR API without the proxy. You can use the existing deployment and follow instructions at https://learn.microsoft.com/en-us/azure/healthcare-apis/access-fhir-postman-tutorial.
Once you get that working, test the FHIR API with the proxy. You can start with the proxy that has the its security disabled (The FHIR api still requires security and you cannot disable it). Once you get that working, you can enable the proxy's security.
Since the proxy is a web app acting as a proxy, you will need two sets of credentials, one set for the FHIR api itself, which you specify in the proxy app, and one set for the proxy web app, which you specify in your client app, e.g. Postman or curl.
The reason for the error is actually very simple, you are using the wrong scope.
Usually the 401 error means that the audience of your token does not match your api. When you use the token to call the api, you will receive a 401 unauthorized error. The access token is issued based on the audience, so you must Make sure to set the scope to your api when you request the token. Of course you can also parse the token, check the aud claim, and make sure it is the api you want to call.
Therefore, according to your requirements, try to change the scope to: https://func-fhir-proxy-2.azurewebsites.net/.default
By the way, if you want to call api, you should use access token instead of refresh token and id token.

Resources