Validating Azure AD token - c#

I have an angular app that I added Azure Active directory authentication and I got azure to return an access token with the user details.
I pass the ad token to my web api (running in .net 4.6.1 ) to check if the user has already been registered and I want to validate that the token is valid.
I've used the following code. But I am getting an error whenever I Tried to recover my configuration from ConfigurationManager
string tenantId = "someguid"; //not including these guids in here
var audience = "anotherguid";
var issuer = $"https://login.microsoftonline.com/{tenantId}/v2.0";
var stsDiscoveryEndpoint = $"https://login.microsoft.com/{tenantId}/v2.0/.well-known/openid-configuration";
var configManager = new ConfigurationManager<OpenIdConnectConfiguration>(stsDiscoveryEndpoint, new OpenIdConnectConfigurationRetriever());
try
{
CancellationToken cancellationToken = new CancellationToken();
var config = await configManager.GetConfigurationAsync(cancellationToken);
var tokenHandler = new JwtSecurityTokenHandler();
var validationParameters = new TokenValidationParameters
{
ValidAudience = audience,
ValidIssuer = issuer,
IssuerSigningKeys = config.SigningKeys,
ValidateAudience = true,
ValidateIssuerSigningKey = true,
RequireExpirationTime = true,
ValidateLifetime = true
};
SecurityToken validatedToken = new JwtSecurityToken();
tokenHandler.ValidateToken(token, validationParameters, out validatedToken);
return validatedToken;
}
IOException: IDX20807: Unable to retrieve document from: 'https://login.microsoft.com/145fa4fc-d5f6-489c-affn-6407cca77ef0/v2.0/.well-known/openid-configuration'. HttpResponseMessage: 'StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
Am I missing something in azure or should I be getting the config some other way? any direction would be appreciated.

The error IDX20807: Unable to retrieve document from: 'https://login.microsoft.com/145xxxxxxx7ccxxxxf0/v2.0/.well-known/openid-configuration
means : OIDC metadata
https://login.microsoftonline.com/.well-known/openid-configuration is
not valid due to something being wrong in web configuration or has
not been correctly configured in the application.Probably ,the
authority parameter is not recognized properly.
I see you have given wrong metadata url in place of https://login.microsoftonline.com as I see you have given wrong metadata url in place of https://login.microsoft.com
Also you need need to add "Authority" to the appsettings.json. which is the meta data url
Or else instance and domain must be given
(authority format: " https://login.microsoftonline.com/<tenantId>" )
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "yourtenantdomain",
"ClientId": "My Client Id",
"TenantId": "<common or organizations>", // must be there in Multi Tenant application
"CallbackPath": "/signin-oidc"
},
And try with dotnet version 4.7 or later and make sure to run on the tls version is 1.2 or later

Related

Azure AD B2C JWT Token Signature Validation Failed

I am trying to validate a valid JWT using this code below but am getting a strange error
[Error] IDX10516: Signature validation failed. Unable to match key:
kid: '-KI3Q9nNR7bRofxmeZoXqbHZGew'.
Number of keys in TokenValidationParameters: '1'.
Number of keys in Configuration: '0'.
Exceptions caught:
'[PII of type 'System.Text.StringBuilder' is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.
token: '[PII of type 'System.IdentityModel.Tokens.Jwt.JwtSecurityToken' is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'. Valid Lifetime: 'True'. Valid Issuer: 'False'
Code:
I had seen a lot of reference links on this issue but still not getting what am I missing?
I tried to test locally, its worked perfectly but after deployed to Azure Function its failing.
Configuration Settings:
"JwtSettings:TenantName": "OSHDev.onmicrosoft.com",
"JwtSettings:TenantId": "5492b240-96ee-44a1-bdcb-fa0ba0200111",
"JwtSettings:AadB2cInstance": "https://OSHDev.b2clogin.com/{0}/v2.0/",
"JwtSettings:OpeinConfigUrl":"https://OSHDev.b2clogin.com/OSHDev.onmicrosoft.com/B2C_1A_SIGNUP_SIGNIN/v2.0/.well-known/openid-configuration",
public async Task<ClaimsPrincipal> ValidateAccessToken(string accessToken, JwtSettings jwtSettings, ILogger logger)
{
var audience = jwtSettings.Audience;
var tenant = jwtSettings.TenantName;
var tenantid = jwtSettings.TenantId;
var aadb2cInstance = jwtSettings.AadB2cInstance;
var openidconfigurl = jwtSettings.OpeinConfigUrl;
//Debugging purposes only, set this to false for production
Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = false;
ConfigurationManager<OpenIdConnectConfiguration> configManager =
new ConfigurationManager<OpenIdConnectConfiguration>(
openidconfigurl,
new OpenIdConnectConfigurationRetriever());
OpenIdConnectConfiguration config;
config = await configManager.GetConfigurationAsync();
//Microsoft Identity to override claim names . If we remove below code line, "sub" claim will not be visible. Its visible under "nameidentifier"
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
JwtSecurityTokenHandler? tokenValidator = new JwtSecurityTokenHandler();
// Initialize the token validation parameters
TokenValidationParameters validationParameters = new TokenValidationParameters
{
// App Id URI and AppId of this service application are both valid audiences.
ValidateAudience = true,
ValidAudiences = new[] { audience },
ValidateIssuer= true,
ValidIssuers = new List<string>()
{
string.Format(CultureInfo.InvariantCulture, aadb2cInstance, tenantid),
string.Format(CultureInfo.InvariantCulture, aadb2cInstance, tenant)
},
ValidateIssuerSigningKey = true,
// Support Azure AD V1 and V2 endpoints.
IssuerSigningKeys = config.SigningKeys,
RequireSignedTokens = true,
//Debugging purposes only, set this to true for production
ValidateLifetime = true
};
try
{
//Validate JwTToken and return Claims Prinicpals
ClaimsPrincipal? claimsPrincipal = tokenValidator.ValidateToken(accessToken, validationParameters, out SecurityToken securityToken);
return claimsPrincipal;
}
catch (Exception ex)
{
logger.LogError(ex.Message);
}
return null;
}
Like the error said, your token validator try to find the public key that is used to sign your token in the jwks_uri, you can find it in your well-known URL.
In each token there is a header "KID", this header indicate the ID of the public key used to sign your token.
When i check your jwks_uri there is no KID with ID :
"-KI3Q9nNR7bRofxmeZoXqbHZGew"
But:
"veMP2TrHLgs4XvKYJhumvhPW6O-WpbdSGqKdetRmvxI"

Minimal API NET 7: JSON Web Token (JWT) generation failed

I am trying to use the minimal API in NET 7 and failing to generate JWT tokens.
I have collected the following from several sites and youtube videos. Unfortunately I couldn't find a JWT authentication for NET 7 in any post or video, so I had to combine something from NET 6 (maybe that's where the error comes from?).
to keep from building the config, I used the new function in NET 7:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer();
in appsettings.json I then added the following:
"Jwt": {
"Key": "gfdsgf789087fgfdsgfds087807dfgfdsfg",
"Issuer": "https://localhost:7285",
"Audience": "https://localhost:7285"
}
Then I created an endpoint to request the token:
app.MapPost("/security/createToken",
[AllowAnonymous] (User user) =>.
{
if (user.UserName == "user" && user.Password == "123")
{
var claims = new[]
{
new Claim(ClaimTypes.NameIdentifier, user.UserName)
};
var token = new JwtSecurityToken
(
issuer: builder.Configuration["Jwt:Issuer"],
audience: builder.Configuration["Jwt:Audience"],
claims: claims,
expires: DateTime.UtcNow.AddDays(60),
notBefore: DateTime.UtcNow,
signingCredentials: new SigningCredentials(
new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])),
SecurityAlgorithms.HmacSha256)
);
var tokenString = new JwtSecurityTokenHandler().WriteToken(token);
return Results.Ok(tokenString);
}
return Results.Unauthorized();
});
now when I run the API then I get the token via Swagger. Then if I want to use it on another endpoint:
app.MapGet("/secret",
[Authorize(AuthenticationSchemes =
JwtBearerDefaults.AuthenticationScheme)] () => $"Hello You. This is asecret!!!");
...then I get the error message in Swagger:
Error: response status is 401
www-authenticate: Bearer error="invalid_token",error_description="The signature key was not found".
When I look at tokens via jwt.io I get "Invalid Signature".
Under PAYLOAD:DATA I see my data but without KEY !!!!
{
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier": "user",
"nbf": 1670946236,
"exp": 1676130236,
"iss": "https://localhost:7285",
"aud": "https://localhost:7285"
}
As I see, KEY is not inserted in the token!? I assume that I forgot something, but what?
Can anyone see what the error is and why my token is not valid?
Thanks
I have finally deleted the Jwt definition from appsettings.json and filled the options as they were given in NET 6 examples.
builder.Services.AddAuthentication().AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "https://localhost:7285",
ValidAudience = "https://localhost:7285",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("superSecretKey#345"))
};
});
Now it works.

JWT validation - sts.windows.net vs login.windows.net: Why are the issuers not consistent?

I am developing an application that is spread across multiple Function App running on .net5.
I need to authenticate HTTP calls between functions. To do so, I am using Azure Active Directory. I have created a registered application in my tenant and generated a new secret. Whenever Function1 needs to contact Function2, I retrieve an access token from AAD, like this:
var stringContent = new StringContent($"grant_type=client_credentials&client_id={Uri.EscapeUriString(clientId)}&client_secret={Uri.EscapeUriString(clientSecret)}&scope={Uri.EscapeUriString(scope)}", Encoding.UTF8, "application/x-www-form-urlencoded");
string tokenUrl = "https://login.microsoftonline.com/57cc008d-ba7c-4887-acfd-93089c705640/oauth2/v2.0/token";
HttpResponseMessage result = await _httpClient.PostAsync(tokenUrl, stringContent);
string content = await result.Content.ReadAsStringAsync();
With this call, I get a token which has the following information:
{
"typ": "JWT",
"alg": "RS256",
"x5t": "XXXXXXXXXXXXX_KXEg",
"kid": "XXXXXXXXXXXXX_KXEg"
}.{
"aud": "api://f87cc6ac-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"iss": "https://sts.windows.net/57cc008d-XXXX-XXXX-XXXX-XXXXXXXXXXXX/",
"iat": 1628443017,
"nbf": 1628443017,
"exp": 1628446917,
"aio": "E2ZgYOg4qv7qZsTRKv5v+XXXXXXXXXXX",
"appid": "f87cc6ac-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"appidacr": "1",
"idp": "https://sts.windows.net/57cc008d-XXXX-XXXX-XXXX-XXXXXXXXXXXX/",
"oid": "39b2e6b8-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"rh": "0.AVsAjQDMV3y6h0is_ZMInHBWQKzGfPhOtBZEj3l003jzIFFbAAA.",
"sub": "39b2e6b8-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"tid": "57cc008d-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"uti": "U7pMFAzw_XXXXXXXXXXXXX",
"ver": "1.0"
}.[Signature]
Now, the access token is used as a bearer token when Function2 is called. Function2 gets the token from the Authorization header and tries to validate it, like this:
ConfigurationManager<OpenIdConnectConfiguration> configurationManager = new ("https://login.microsoftonline.com/57cc008d-ba7c-4887-acfd-93089c705640/v2.0/.well-known/openid-configuration", new OpenIdConnectConfigurationRetriever());
OpenIdConnectConfiguration openIdConnectConfiguration = await configurationManager.GetConfigurationAsync();
TokenValidationParameters validationParameters = new TokenValidationParameters
{
ValidateAudience = false,
ValidateIssuer = true,
ValidIssuers = new[]
{
openIdConnectConfiguration.Issuer
},
ValidateIssuerSigningKey = true,
IssuerSigningKeys = openIdConnectConfiguration.SigningKeys,
RequireExpirationTime = true,
ValidateLifetime = true,
RequireSignedTokens = true,
};
JwtSecurityTokenHandler securityTokenHandler = new();
if (!securityTokenHandler.CanReadToken(cleanedBearerToken))
throw new ArgumentException("Unable to read the token. It is malformed.");
try
{
ClaimsPrincipal claimsPrincipal = securityTokenHandler.ValidateToken(cleanedBearerToken, validationParameters, out SecurityToken _);
return claimsPrincipal;
}
catch (Exception unhandledException)
{
throw new AuthenticationException("The token could not be validated.", unhandledException);
}
Aside from the issuer, the validation works. With this setup, the issuer can't be validated. The token indicates that the issuer is from sts.windows.net. However, the OpenID configuration states that the issuer must be login.microsoft.com.
To make it work, I have fall back to something like this which is less ideal since I have to ignore a parameter returned by the openid-configuration endpoint (which must know better that I):
TokenValidationParameters validationParameters = new TokenValidationParameters
{
ValidateAudience = false,
ValidateIssuer = true,
ValidIssuers = new[]
{
// --> Force the use of the following issuer!!
"https://sts.windows.net/57cc008d-ba7c-4887-acfd-93089c705640/"
},
ValidateIssuerSigningKey = true,
IssuerSigningKeys = openIdConnectConfiguration.SigningKeys,
RequireExpirationTime = true,
ValidateLifetime = true,
RequireSignedTokens = true,
};
Question
Is the override of issuer a good practice? If not, what can I do to get consistent issuer from Azure Active Directory and avoid specifying the issuer myself?
The issuer value depends on the Access token version. If you view the Sample Tokens in jwt.ms, you will see the issuer for Access token V1 is https://sts.windows.net/... and for Access token V2 it is https://login.microsoft.com/...
Also, if you check OIDC metadata endpoint v1 (https://login.microsoftonline.com/common/.well-known/openid-configuration), issuer will be sts.windows.net and for OIDC metadata endpoint v2 (https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration), issuer will be login.microsoft.com.
Update
In registered application's manifest, look for the value of accessTokenAcceptedVersion:
Change it to 2 and the issuer will become login.microsoft.com instead of sts.windows.net.

Validating JWT getting a strange “ Unable to match key kid” error

I am trying to validate a valid JWT using this code below but am getting a strange error
"IDX10501: Signature validation failed. Unable to match key:
kid: 'System.String'.
Exceptions caught:
'System.Text.StringBuilder'.
token: 'System.IdentityModel.Tokens.Jwt.JwtSecurityToken'."
Here is my validation method
ClaimsPrincipal principal = null;
var token = "JWT GOES HERE"
try
{
string sec = "000uVmTXj5EzRjlnqruWF78JQZMT";
var securityKey = new SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(sec));
var now = DateTime.UtcNow;
SecurityToken securityToken;
string tokenIssuer = "https://MyIssuer.com";
TokenValidationParameters validationParameters = new TokenValidationParameters()
{
ValidIssuer = tokenIssuer,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = securityKey
};
JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
principal = handler.ValidateToken(token, validationParameters, out securityToken); <---Errors here
}
Here is the value of my JWT. I am using the correct issuer
{
"alg": "RS256",
"kid": "dev",
"x5t": "Sm7aAUSt4Fdv7X1b9jQDf8XwbvQ",
"pi.atm": "xxe8"
}.{
"scope": [],
"client_id": "ClientABC",
"iss": "https://MyIssuer.com",
"jti": "1JLDz",
"sub": "ClientABC",
"exp": 1601609852
}.[Signature]
What am I missing here? Is the the SymmetricSecurityKey since this algorithm is RS256? Am I missing something in my TokenValidationParameter?
Update
After futher investigation I am getting the error of.
IDX10501: Signature validation failed. Unable to match key:
kid: 'dev'.
Exceptions caught:
'System.NotSupportedException: IDX10634: Unable to create the SignatureProvider.
Algorithm: 'RS256', SecurityKey: 'Microsoft.IdentityModel.Tokens.SymmetricSecurityKey, KeyId: '', InternalId: 'TdfWgWjCVeM60F3C5TOogJuka1aR5FA_xchwhY9MHH4'.'
is not supported. The list of supported algorithms is available here: https://aka.ms/IdentityModel/supported-algorithms
at Microsoft.IdentityModel.Tokens.CryptoProviderFactory.CreateSignatureProvider(SecurityKey key, String algorithm, Boolean willCreateSignatures, Boolean cacheProvider)
try to use SecurityAlgorithms.HmacSha256
Example when you issue the token:
Users user = _context.Users.FirstOrDefault(c => c.UserName == userName && c.Password == password);
if(user == null)
{
return Unauthorized();
}
Claim[] claims = new Claim[]
{
new Claim("Id", user.Id.ToString()),
new Claim("Name", user.Name),
new Claim("Email", user.Email),
};
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("000uVmTXj5EzRjlnqruWF78JQZMT"));
var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
var token = new
JwtSecurityToken(
"MyProject",
"MyClient",
claims,
expires: DateTime.Now.AddMinutes(30),
signingCredentials: signingCredentials);
return Ok(new JwtSecurityTokenHandler().WriteToken(token));
If you are using .net core app, then in Startup.cs, in ConfigureServices method write this code to validate the token:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.RequireHttpsMetadata = false;
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidateAudience = true,
ValidAudience = "MyClient",
ValidIssuer = "MyProject",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("000uVmTXj5EzRjlnqruWF78JQZMT"))
};
});
Also don't forget to add the following lines to the Configure method in Startup.cs
app.UseAuthentication();
app.UseAuthorization();
The issue is that you are trying to use a symmetric key with an asymmetric algorithm. The RSA algorithm requires both a public and a private key.
Try using a symmetric algorithm instead, like HS256 (HMAC-SHA256).
Having come here looking for answers myself, let me share another scenario which may crop up in a production setting. So we were having this same cryptic authentication error. In our case, the client application was using our development environment's Token service to generate their bearer token and then sending it to production.
I don't know why it didn't outright just deny instead of failing on "Unable to match Key kid", but using the production token service solved it for us. So be sure to verify that first, since it's a relatively quick and simple thing to do.

Bearer error - invalid_token - The signature key was not found

I have an Angular 7 application interfacing with a .Net Core 2.2 API back-end. This is interfacing with Azure Active Directory.
On the Angular 7 side, it is authenticating properly with AAD and I am getting a valid JWT back as verified on jwt.io.
On the .Net Core API side I created a simple test API that has [Authorize] on it.
When I call this method from Angular, after adding the Bearer token, I am getting (as seen in Chrome Debug Tools, Network tab, "Headers"):
WWW-Authenticate: Bearer error="invalid_token", error_description="The
signature key was not found"
With a HTTP/1.1 401 Unauthorized.
The simplistic test API is:
[Route("Secure")]
[Authorize]
public IActionResult Secure() => Ok("Secure works");
The Angular calling code is also as simple as I can get it:
let params : any = {
responseType: 'text',
headers: new HttpHeaders({
"Authorization": "Bearer " + token,
"Content-Type": "application/json"
})
}
this.http
.get("https://localhost:5001/api/azureauth/secure", params)
.subscribe(
data => { },
error => { console.error(error); }
);
If I remove the [Authorize] attribute and just call this as a standard GET request from Angular it works fine.
My Startup.cs contains:
services
.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureADBearer(options => this.Configuration.Bind("AzureAd", options));
The options are all properly set (such as ClientId, TenantId, etc) in the appsettings.json and options here is populating as expected.
I was facing the same issue. i was missing the authority..make sure authority and api name is correct now this code in configure services in startup file works for me:
services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication( x =>
{
x.Authority = "http://localhost:5000"; //idp address
x.RequireHttpsMetadata = false;
x.ApiName = "api2"; //api name
});
I had a unique scenario, hopefully this will help someone.
I was building an API which has Windows Negotiate authentication enabled (.NET Core 5.0, running from IIS) and unit testing the API using the CustomWebApplicationFactory (see documentation for CustomWebApplicationFactory) through XUnit which does not support Negotiate authentication.
For the purposes of unit testing, I told CustomWebApplicationFactory to use a "UnitTest" environment (ASPNETCORE_ENVIRONMENT variable) and specifically coded logic into my application Startup.cs file to only add JWT authentication for the "UnitTest" environment.
I came across this error because my Startup.cs configuration did not have the signing key I used to create the token (IssuerSigningKey below).
if (_env.IsEnvironment("UnitTest"))
{
// for unit testing, use a mocked up JWT auth, so claims can be overridden
// for testing specific authentication scenarios
services.AddAuthentication()
.AddJwtBearer("UnitTestAuth", opt =>
{
opt.Audience = "api://local-unit-test";
opt.RequireHttpsMetadata = false;
opt.TokenValidationParameters = new TokenValidationParameters()
{
ClockSkew = TokenValidationParameters.DefaultClockSkew,
ValidateAudience = true,
ValidateIssuer = true,
ValidateIssuerSigningKey = true,
ValidAudience = "api://local-unit-test",
ValidIssuer = "unit-test",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("abcdefghijklmnopqrstuvwxyz123456"))
};
});
} else {
// Negotiate configuration here...
}
Regardless of the ValidateIssuerSigningKey being true or false, I still received the "invalid_token" 401 response, same as the OP. I even tried specifying a custom IssuerSigningKeyValidator delegate to always override the result, but did not have luck with that either.
WWW-Authenticate: Bearer error="invalid_token", error_description="The signature key was not found"
When I added IssuerSigningKey to the TokenValidationParameters object (of course matching the key I used when generating the token in my unit test), everything worked as expected.
There could be two reason:
You might have missed registering service :
services.AddAuthorization(auth =>
{
auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme‌​)
.RequireAuthenticatedUser().Build());
});
Or
2. You might have missed assigning value to key "IssuerSigningKey" as shown below
validate.TokenValidationParameters = new TokenValidationParameters()
{
ValidateAudience = true,
ValidAudience = "Audience",
ValidateIssuer = true,
ValidIssuer = "http://localhost:5000",
RequireExpirationTime = false,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("abcdefghi12345"))
});
This resolved my problem
My problem was that I needed to set the ValidIssuer option in the AddJwtBearer TokenValidationParameters, in addition to the authority
For example:
services.AddAuthentication("Bearer")
.AddJwtBearer(options =>
{
options.Audience = "My Audience";
options.Authority = "My issuer";
options.TokenValidationParameters = new TokenValidationParameters {
ValidateIssuerSigningKey = true,
ValidateLifetime = true,
ValidateIssuer = true,
ValidIssuer = "Also My Issuer", //Missing line here
ValidateAudience = true
};
});
Verify the values that you send for request the jwt token (eg: grant_type, client_secret, scope, client_id, etc)
Ensuere that you are using the appropiate token. That's all!
Here is my mistake:
I was using Postman, and request a token and set it to a varibale "Var_Token1":
pm.environment.set("Var_Token1", pm.response.json().access_token);
But when I need to use the token for my final request, I selected and use the wrong token (Var_Token2):
Authorization: Bearer {{Var_Token2}}
For me, this error was coming because the URL in appsettings.json was incorrect. I fixed it and it's working fine now.
This can also happen if you are using a different SignedOutCallbackPath/SignUpSignInPolicyId policy id than which is being passed in the token as tfp/acr.
My Core API uses different services configuration (and it works :)):
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
Configuration.Bind("JwtBearer", options);
}
Are you sure you are passing an access token and not an id_token? Is the aud claim present in the token exactly the same as the clientid your API is configured with? You may want to add some events to your options to see what you are receiving and where the validation fails.
I had this issue, and it was caused by jwtOptions.Authority not being set in config.
If you are using:
services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme,
And jwtOptions.Authority is set to null or "" you can get this error message.

Categories