Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Postman Client Credentials Flow with Azure AD protected ressource

I am currently using this example:

https://docs.microsoft.com/en-us/azure/active-directory/active-directory-authentication-scenarios#daemon-or-server-application-to-web-api

To check the Client Credentials Flow with OAuth in Azure AD. Theoretically the example works OK. Client App successfully communicates with the server App, obtaining first the OAuth Token from Azure AD token url. No problems there. However, I am trying to use Postman to check the Client Credentials Flow and I cannot get it to work.

In Postman, I should provide an Access Token Url, a Client ID and a Client Secret, Grant Type is set to Client Credentials. Using the same parameters as in the example provided by Microsoft's sample in https://github.com/Azure-Samples/active-directory-dotnet-daemon, I get a 401 response when trying to access the web service. I think the main reason is because in Postman, I can not type the resource I want to access, so the received token is not "linked" to any resource and that is why the authorization fails in the web server? Could this be the reason? If that is the reason, then what should I do in the server, because, somehow it seems as if Postman's requirements should be the ones valid in the Client Credentials Flow (I mean, no resource should be given, according to the OAuth2 Client Credentials Flow, right?

This is the code for the Starup class in the sample downloaded from Microsoft's example

    // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
    public void ConfigureAuth(IAppBuilder app)
    {
        app.UseWindowsAzureActiveDirectoryBearerAuthentication(
            new WindowsAzureActiveDirectoryBearerAuthenticationOptions
            {
                Audience = ConfigurationManager.AppSettings["ida:Audience"],
                Tenant = ConfigurationManager.AppSettings["ida:Tenant"]
            });
    }

ConfigurationManager.AppSettings["ida:Tenant"] is my Azure AD tentant, while ConfigurationManager.AppSettings["ida:Audience"] is the protected resource I need to access. Both values are required, if I do not provide the Audience, I get an error in .NET web API initialization.

like image 520
Alfredo A. Avatar asked Nov 16 '16 20:11

Alfredo A.


People also ask

What credentials can the OAuth 2.0 client credentials grant flow use?

You can use the OAuth 2.0 client credentials grant specified in RFC 6749, sometimes called two-legged OAuth, to access web-hosted resources by using the identity of an application.

How do I add client credentials to my postman?

Go to https://api-console.zoho.com/ and click Add Client to create a new one. Provide a name for the client and select the Type as Server-based Application. Fill in the rest of the form and click Create. The Client ID and Client Secret will be generated for the respective client.


2 Answers

EDIT

I think the problem is that Azure Token server doesn't accept client credentials sent as an Authorization header. e.g.

Authorization: Basic YmE1NTZlYmItZGY2OS00NjBhLWEwMjItNTI0NWQ0MzA2N2UxOmVxVzlqaXRobXF2cVFiVWY5dmxaWnhZN2wwUzZhQ0pHSkExSGt0eUd3N0W6

but that's how Postman's "Get new access token" tool sends it. So it's isn't going to work.

If you look at Microsoft's documentation and search for "get a token" you will see it implies that client credentials should be supplied in the body.

POST /common/oauth2/v2.0/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

client_id=535fb089-9ff3-47b6-9bfb-4f1264799865&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret=qWgdYAmab0YSkuL1qKv5bPX&grant_type=client_credentials

This works fine but seems to contradict the Oauth 2.0 spec which says:

The authorization server MUST support the HTTP Basic authentication scheme for authenticating clients that were issued a client password.

END EDIT

You definitely can get a bearer token back without supplying a resource.

Notice that resource isn't even spelt correctly in the postman http body of the previous answer - it's spelt as resrource which is why it's value of https://graph.microsoft.com is ignored and does not match the resource sent back in the response (00000002-0000-0000-c000-000000000000). Although funny enough they both relate to the api graph...but that's a digression.

Confusingly there are two ways of supplying client credentials to an Oauth 2.0 server and some servers don't accept both ways!

  • 1 is adding a basic auth header which is set to Base64(ClientId + ":" + ClientSecret)
  • 2 is adding clientId and clientSecret in the body of the request.

I guess that's the problem with Oauth 2.0 being a spec rather than a protocol... See - https://www.rfc-editor.org/rfc/rfc6749#section-2.3.1

Postman's Request Token UI (see image below) uses method 1, but Azure auth server expects method 2. I know because I ran fiddler, and could see the request postman put together.

If you manually put the client credentials in the body e.g.

grant_type=client_credentials&scope=&client_id=ba556ebb-xxxx9-460a-ax2x-5245d43067e1&client_secret=eqW9jighghghgvlZZxY7l0S6aCJGJA1HktyGw7E=

and don't use a Basic Auth http header. You can get a bearer token back even without suppyling a resource.

This works fine - but obviously that's no good for you in terms of using postman to get and store your tokens!

enter image description here

like image 72
iandayman Avatar answered Nov 15 '22 11:11

iandayman


I think the main reason is because in Postman, I can not type the resource I want to access, so the received token is not "linked" to any resource and that is why the authorization fails in the web server? Could this be the reason?

You are correct. To get the access token via client credential flow, we need to provide the resource in the request.

What did you mean that not able to type the resource? The resource parameter is a parameter we can contain it in the body and here is a figure for your reference:

enter image description here

And be ensure that the value of resrouce is eaque to the audience config used to protect the resource.

like image 38
Fei Xue - MSFT Avatar answered Nov 15 '22 11:11

Fei Xue - MSFT