Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

PostMan-token-retrieval

As you can see, it returned the token seen above ^.

I then took this token and put it through another Postman call:

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":

Azure-portal-settings

Anyone know any settings I can change to allow this sort of call to happen?

like image 348
LatentDenis Avatar asked Jun 02 '17 21:06

LatentDenis


People also ask

How do I get permission from postman?

next to the element name and select Manage Roles. Select Request Access. Select the person you want to send the request to, and select the Editor role. Select Request Access.


2 Answers

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.

like image 142
Fei Xue - MSFT Avatar answered Oct 07 '22 10:10

Fei Xue - MSFT


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.

like image 42
evilSnobu Avatar answered Oct 07 '22 12:10

evilSnobu