1
votes

I'm trying to implement Bearer token (only) authentication in a .NET Core 3.1 API, using Azure AD.

I'm able to retrieve a token from Azure AD after verifying the authorization_code and the browser posts back to my redirect URL with the following:

{"token_type":"Bearer","scope":"User.Read","expires_in":3600,"ext_expires_in":3600,"access_token":"EwBwA8l6...SzT3qoxGbSMg=="} (shortened)

Once I have this token, should I be able to use the [Authorize] attribute directly on my APIs and request using a Bearer token in the header? When I do, I get a 401 response.

I have this in my ConfigureServices():

services.AddAuthentication(options =>
{
    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
    options.Audience = "<guid>";

    options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
    {
        ValidateIssuerSigningKey = false,
        ValidateAudience = false,
        ValidateIssuer = false,
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("abc123")),
        TokenDecryptionKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("abc123"))
    };
});
services.AddControllers();

And in Configure() I have:

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseCookiePolicy();
app.UseAuthentication();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
});

In my error log, the message I'm seeing is:

"Bearer" was not authenticated. Failure message: "No SecurityTokenValidator available for token

I've tried many, many combinations of settings in Startup.cs, and no matter what I can only seem to get a 401 when calling my API from Postman. I'm able to get Cookie authentication working with code samples I've found online, but I don't want that.

Is the issue that the token is encrypted? Am I trying to use the wrong token? Or is there some other issue? Do I need to have identity set up in my app with database tables for AspNetUser, etc.?

In short, I'm just trying to generate a Bearer token using Azure AD as the auth provider, and make calls to my APIs by passing in a Bearer token header.

1

1 Answers

2
votes

Looks a bit like you are trying to use a Microsoft Graph API token in your API. (based on this: "scope":"User.Read")

Your front-end app needs to use a scope for your API, not User.Read. This way it will get an access token which is meant for your API. Register a scope on your API app registration through the Expose an API section and use the full scope value in your front-end when acquiring the token.

Your back-end needs the following config:

.AddJwtBearer(options =>
{
    // add v2.0 to the end if your API is set to get v2 tokens in its manifest
    options.Authority = "https://login.microsoftonline.com/your-aad-tenant-id";
    options.Audience = "your-api-client-id";
});

This should be the minimum configuration needed for authentication. It'll look up signing keys etc. automatically from the authority at startup.