4
votes

I have a simple web api project, which looks like this:

[Authorize]
        [Route("Get")]
        public ActionResult<string> SayHello()
        {
            return "Hello World";
        }

I am trying to test it with Postman. By following the steps here: https://kevinchalet.com/2016/07/13/creating-your-own-openid-connect-server-with-asos-testing-your-authorization-server-with-postman/

1) Send the request below and receive a token as expected:

enter image description here

2) Attempt to send another request with the authorization token as shown below:

enter image description here

Why do I get a 401 (unauthorized) error? The WWW-Authenticate response header says: Bearer error="invalid_token", error_description="The issuer is invalid". I am using .Net Core 3.1. I have commented out the sensitive information in the screenshots.

The web api works as expected when accessed from an MVC application.

Here is the startup code:

services.AddAuthentication("Bearer")
                .AddIdentityServerAuthentication(options =>
                {
                    options.Authority = identityUrl; //identityurl is a config item
                    options.RequireHttpsMetadata = false;
                    options.ApiName = apiName;

                });
3
The access token is in the certificate. It is failing. The security mode is TLS/SSL which has a number of different options like 16 bit, 32 bit, 64 bit. I've seen many people when upgrading to Net 4.7 the security was failing. I suspect the same is also happening with Core 3.1. So the token you are using and the mode set in the c# code aren't the same. You may want to see the wiki article to get better understanding : google.com/…jdweng
How do I find the mode in the C# code? Thanks.w0051977
I have added some C# code to the bottom of the question. Please take a look?w0051977
Good question. I have not gotten any real feedback from people on how this issue was fixed. I suspect it has to do with the Certificate2 class and the compiling mode x64 or x86. It seems like it broke when microsoft released Net 4.7. Since Core 3.1 is also new I suspect the same issue in Core3.1 You could try targeting to older version of Net or the compiler options.jdweng
what is the authority , it should be base-address of your identityserverNan Yu

3 Answers

4
votes

I ran into a similar issue. I was generating my token via Postman when sending in my request and using an external IP to access my Keycloak instance running inside of my kubernetes cluster. When my service inside the cluster tried to verify the token against the authority, it failed because the internal service name (http://keycloak) it used to validated the token was different than what Postman had used to generate the token (<external-keycloak-ip).

Since this was just for testing, I set the ValidateIssuer to false.

options.TokenValidationParameters = new TokenValidationParameters
{
    ValidateIssuer = false 
};
3
votes

I'm on dotnet 5.0, adding swagger (NSwag.AspNetCore) to my AzureAD "protected" web api and got a similar error about invalid issuer:

 date: Tue,16 Mar 2021 22:50:58 GMT 
 server: Microsoft-IIS/10.0 
 www-authenticate: Bearer error="invalid_token",error_description="The issuer 'https://sts.windows.net/<your-tenant-id>/' is invalid" 
 x-powered-by: ASP.NET 

So, instead of not validating the issuer, I just added sts.windows.net to the list (important parts in the end):

// Enable JWT Bearer Authentication
services.AddAuthentication(sharedOptions =>
{
    sharedOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
    Configuration.Bind("AzureAd", options);
    // Authority will be Your AzureAd Instance and Tenant Id
    options.Authority = $"{Configuration["AzureAd:Instance"]}{Configuration["AzureAd:TenantId"]}/v2.0";

    // The valid audiences are both the Client ID(options.Audience) and api://{ClientID}
    options.TokenValidationParameters.ValidAudiences = new[]
    {
        Configuration["AzureAd:ClientId"], $"api://{Configuration["AzureAd:ClientId"]}",

    };
    // Valid issuers here:
    options.TokenValidationParameters.ValidIssuers = new[]
    {
        $"https://sts.windows.net/{Configuration["AzureAd:TenantId"]}/",
        $"{Configuration["AzureAd:Instance"]}{Configuration["AzureAd:TenantId"]}/"
    };
});

This solved my problems. Now, why NSwag uses sts.windows.net as token issuer, I don't know. Seems wrong. I'm using these package versions:

    <PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" />
    <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="5.0.3" />
    <PackageReference Include="NSwag.AspNetCore" Version="13.10.8" />
2
votes

The Authority of AddIdentityServerAuthentication middleware should be the base-address of your identityserver , middleware will contact the identity server's OIDC metadata endpoint to get the public keys to validate the JWT token .

Please confirm that the Authority is the url of identity server where you issued the jwt token .