Reputation: 3688
I am using IdentiyServer to issue a JWT Token to a client, token contains role claims and some other claims, this part works fine, I get the the access token with desired claims.
And in my web API application I have added the following code to support JWT authentication:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.RequireHttpsMetadata = false;
options.Authority = "http://localhost:5004";
IdentityModelEventSource.ShowPII = true;
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateAudience = false,
ValidateIssuer = false,
ValidateLifetime = false,
ValidateIssuerSigningKey = true,
IssuerSigningKey = "what is this ?"
};
The question is, suppose a hacker generates a JWT token with whatever header and body and claims he wants and signs it, how does my web api application validate the signature? How can I share IssuerSigningKey with identityServer and my web api application?
Is IssuerSigningKey the same as ClientSecrets in identityServer?
I have gone through IdentityServer documentation, but couldn't find an answer.
Upvotes: 2
Views: 1937
Reputation: 11478
In the question as it seems, that complete OAuth flow using an OAuth or Open Id server is not very clear, let's consider various questions and options.
I am using IdentiyServer to issue a JWT Token to a client, token contains role claims and some other claims, this part works fine, I get the the access token with desired claims.
Let's segregate the Authentication server from Authorization, generally when we integrate any of the social logins, what they do is provide an access token and we use callback to generate a JWT Authroization token at our server, which we control like Backend server
What's the difference between two ?
Authentication server generally know very few details about us, mostly they just verify email and return success, they have no ability to assign roles and other details, which vary from application to application
What shall we do then ?
Receive Access Token, fetch details like email from it, fetch all details related to that email, create a json payload, use an algorithm with either Symmetric (only one key) or Asymmetric encryption (generate private public key pair), check this video to know details about JWT with much more clarity. In Symmetric encryption we use same key to encode / decode, while in Asymmetric encryption we encode using private key and decode using public key. As you would check In JWT encoding and decoding simply means hashing header.payload
and comparing the two to ensure no tampering
Remaining questions regarding type of encryption and hacker:
header.jsonpayload
ASP.Net Web API Specific Changes
I code in Python using Fast API, what we do is use a middleware
, which is similar to interceptor / filter in Asp.Net, which will intercept all the calls to the controller / api, fetch the token, decode, verify and allow the call to continue or throw an error to relogin, please note encoding happens in the callback
from the authentication server. A sample code in Python, https://pyjwt.readthedocs.io/en/latest/usage.html
For C# this link is a good option, https://www.c-sharpcorner.com/article/asp-net-web-api-2-creating-and-validating-jwt-json-web-token/
Here as you can see the code, where explicit Filter is added to verify the token. It use a decorator, [Authorize]
to invoke the authorization filter
public static void Register(HttpConfiguration config) {
// Web API configuration and services
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new {
id = RouteParameter.Optional
}
);
}
Upvotes: 1
Reputation: 19941
When you use AddJwtBearer, it will download the public signing key from your IdentityServer (http://localhost:5004) and use this public key to verify that the signature in the received JWT token was issued by the expected issuer. AddJwtBearer will refresh the downloaded public key every 24 hours by default.
IssuerSigningKey you do not need to set in the API. In general you should disable as few checks as possible in he TokenValidationParameters object.
In production you should try to set ShowPII to false, because otherwise things like tokens and other secrets might end up in the logs.
Is IssuerSigningKey the same as ClientSecrets in identityServer?
No, they are two separate things. ClientSecret is like a password for the client, when it authenticates against IdentityServer.
SigningKey you set in IdentityServer and it represents the public/private siging key. The key can either be an RSA or ECDSA key.
Upvotes: 3
Reputation: 521914
While a hacker can certainly generate a bogus JWT with some header and claims, he cannot sign the token using the server's private key, unless he also hacks your server to steal the key. So, in practice, a JWT usually bears a checksum at the end of the token, which is a hash based on the token's content and the server key. If your server receives an incoming JWT and the checksum does not validate, then it should reject that JWT.
Upvotes: 1