Search code examples
asp.net-web-apiasp.net-web-api2azure-ad-b2c

Securing .NET Framework Web API with Azure AD (Client credentials flow)


I have a .NET 4.7 Web API project (not .NET CORE).

I am trying to setup authentication with an Azure AD directory, I setup an application in my AD, and I got the client id (application id)

I would like to use the Client Credentials grant type. So I went ahead and retrieved a token via the access token URL https://login.microsoftonline.com/HIDDEN/oauth2/v2.0/token I am passing in the client id, and secret, for this I am using Postman

Now in my project I've implemented the following logic in my web api project:

var clientId = "AZURE APPLICATION ID";
app.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions
{
    
    AllowedAudiences = new List<string> { clientId },
    TokenValidationParameters = new TokenValidationParameters
    {

        ValidateAudience = false,
        ValidAudience = clientId
    }
});

On my controller, I applied the [Authorize] attribute

When calling the API controller endpoint (making sure I am passing in the Authorization header with the value "Bearer MYTOKEN") I get the error returned in Postman:

"Message": "Authorization has been denied for this request."

Is there a way I can dive deeper to figure out what might be wrong?

I don't see anything in my output window in visual studio, are there some events I can hook into why it is failing?

EDIT: Adding more information per Carl:

The token seems to be valid, here are the results from jwt.ms, i even setup an "admin" role via the manifest:

enter image description here

Here is my code, I am not specifying the public signature (not sure how to do that yet), but I've even turned off IssueSignature validation. enter image description here

This is what my controller looks like: enter image description here

My fiddler request and response (does having an http endpoint instead of https for local development make a difference?) I don't believe it does: enter image description here


Solution

  • You should get a 401 error, which means that the aud of your token is not your api. The cause of the error is usually that you set the wrong scope when requesting the token. I used the client credential flow Make a demo for you:

    You need to create two applications in Azure ad, one representing the client application and the other representing the api application, and then use the client application to call the Web api application.

    First, you need to expose the api of the application representing the web api, you can configure it according to the following process:

    Azure portal>App registrations>Expose an API>Add a scope>Add a client application

    Next, you need to define the manifest of api applications and grant application permissions to your client applications (this is the role permissions you define yourself, you can find it in My APIs when you add permissions)

    This is the process of defining the manifest.

    enter image description here

    This is to grant permissions for the client application (You can find your expose api permissions in My APIs.):

    enter image description here

    Request access token: enter image description here

    Parse the token:

    enter image description here