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

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.

Related

Getting Business Central API access through node application

I have an issue when trying to hit an endpoint in business central though a node application.
Using OAuth2 in postman I am able to get a desired response as seen below
This my configuration for Authorization:
but when trying to hit the same endpoint in Node using MSAL I get a 401 response.
This my configuration
I even tried taking the token generated by postman and inserted it into my application and was able to hit the endpoint with the desired response. I'm not sure what is missing from my application that's causing it to get a token that when used returns a 401 response.
What's missing from my application or is it something that I need to do in Azure or Business Central ?
I'm not an expert on Node, but I have used MSAL with PowerShell.
Getting the token through MSAL.PS (the PowerShell module for MSAL) you have to set the Scopes that you are requesting a token for.
In this case the scope should be https://api.businesscentral.dynamics.com/.default when you want to access the Business Central APIs.

Azure Data Factory - REST Linked Service - OAuth2 Client Credentials

From Azure Data Factory, I'm trying to connect to a REST service that requires an access token (OAuth2).
Tried in Postman with the client credentials flow (client_id/client_secret) and it works fine:
Calling the token endpoint to get an access_token
Use the token in a subsequent request to retrieve data.
I configured the linked service like that as It supposed to support the OAuth2 client credentials flow:
But when testing the connection, it fails with this message:
The request body must contain the following parameter: 'client_secret'.
I don't really understand why the client_secret is not added in the request body as it is a client credentials flow.
Not sure if I'm missing some configuration ?
For the moment, I'm using Web Activity as a workaround.
This error may occurred because Allow public client flows is disabled for the application registered in Azure AD.
Enabling it may fixed the issue.
Refer - https://learn.microsoft.com/en-us/azure/data-factory/parameterize-linked-services?tabs=data-factory
Refer - https://learn.microsoft.com/en-gb/azure/active-directory/develop/scenario-desktop-acquire-token?tabs=python#username-and-password

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

Azure AD JWT Token Error in .NET Core 3.1

I have react app, which can login user via Azure AD. After that, I created from react app request into my .net core mvc app with header Authorize. But when I added [Authorize] attr into my controller, I get error:
Bearer error="invalid_token", error_description="The signature is invalid"
All I need that my backend app only check scope or role from JWT token and allow to get some data. I know that JWT is correct and react app login user without any problems.
Similar issue to this one:
https://forum.ionicframework.com/t/validating-token-signatures-in-asp-net-core/108226
I summarize the comments and post it as an answer:
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.
When you expose an api protected by Azure, then you need to set the scope to your custom api, usually api://{api app client id}/scope name, and then you need to add the client application to the api application.

POSTMAN: "You do not have permission to view this directory or page" with Bearer Token

I've got a website hosted on HostGator, let's say it's domain is https://example.com.
I also have an application hosted on Azure, with Active Directory Authentication enabled on the entire site (including the API component), let's say it's domain is https://example.azurewebsites.net
THE GOAL - To have a PHP file be executed (as a CRON job) on https://example.com and have the file first Authenticate itself with Azure's Active Directory, and then to pull data from https://example.azurewebsites.net/api/getValues via an HTTP GET call.
THE PROBLEM - Obviously, just calling the API without a bearer token will cause a 401, but I'm still getting a 401 even though I'm passing in what appears to be a valid Bearer Token.
Here's what I did:
Using https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-code -
I visited https://login.microsoftonline.com/{{tenant_id}}/oauth2/authorize?response_type=code&client_id={{client_id}} that was given to me through Azure AD Management Portal.
This returned:
https://example.com/?code={{really_long_string_of_code}}
I took this really_long_string_of_code and put it through postman as a body parameter called code, seen below:
As you can see, it returned the token seen above ^.
I then took this token and put it through another Postman call:
But the problem is, I still get that exact error message:
You do not have permission to view this directory or page.
I feel like I've tried everything. I've even went into the portal.azure and set the "allowed token audiences":
Anyone know any settings I can change to allow this sort of call to happen?
The evilSnobu have already explained this issue which caused by incorrect audience. I want to explain it more general to help understand this issue.
There are two concepts client and resource server in the OAuth 2.0 Authorization Framework(refer rfc6749). When the client calls the resource server, the resource server will verify the token passed in the request. For example, it will verify the signature, issuer, client id, audience etc.
client:
An application making protected resource requests on behalf of the
resource owner and with its authorization. The term "client" does
not imply any particular implementation characteristics (e.g.,
whether the application executes on a server, a desktop, or other
devices).
resource server:
The server hosting the protected resources, capable of accepting
and responding to protected resource requests using access tokens.
In your scenario, you were acquire the access_token for the Azure AD Graph(https://graph.windows.net). However, the audience you config at the portal doesn't match the aud claim in the access_token. To fix the issue, we can use the app registered at Azure AD as both client and resource. If that, we need to acquire the access token using the Application ID instead of App ID URI. And config this value as the ALLOWED TOKEN AUDIENCES on the Azure portal.
Or we can just to register two apps in Azure AD to represent the client app and resource app separately. And using the client app to acquire the token for the resource app. If this, the value of resource should the App ID URI of resource app and we also need to config it as the ALLOWED TOKEN AUDIENCES on the Azure portal.
Remove the trailing slash from Allowed Token Audiences, e.g.:
https://example.com
http://example.com
..or was is the other way around.. hmm..
401 Unauthorized when everything looks right is usually a trailing slash in the audience. Sometimes you need one, sometimes you don't. It should match whatever you or your middleware define as valid audience in the app code. You can also use the app GUID (Application ID) as audience.
Also, you seem to have graph.windows.net as resource, is that intentional?
You should really open that token and check the contents. The audience must match your API's URL.
This to me doesn't feel like the right way to authenticate machine2machine calls. You should probably just use TLS mutual authentication or simply send a hard coded secret over HTTPS in a header (yes, just like a Bearer token, but without the trust chain). On the API side, store it in App Settings and pick it up in your code from the associated environment variable. Use the same App Settings mechanism in the calling app code.
You could rotate this secret using a Function App that changes the App Setting every X days (PowerShell Function Apps have the Resource Management cmdlets available so you could use an SPN to login (Add-AzureRmAccount) and then call Set-AzureRmWebApp -AppSettings [...]).
Alternatively, you can store the secret in Azure Key Vault, and while a great service it borders on overengineering for your use case.

Resources