Reputation: 5224
My client is sending the jwt token with some requests. Almost all requests is hitting a web api controller that is using the [Authorize] attribute. With this I am certain that my jwt token is properly validated, but for certain endpoints is really just want to grab the JWT token and get the sub value. I do this by using this extension method:
public static class HttpContextAccessorExtensions
{
public static string GetUserIdFromToken(this IHttpContextAccessor httpContextAccessor)
{
if (httpContextAccessor == null)
{
throw new ArgumentNullException(nameof(httpContextAccessor));
}
var context = httpContextAccessor.HttpContext;
string userId = null;
if (httpContextAccessor != null)
{
if (context != null)
{
var request = context.Request;
if (request != null)
{
request.Headers.TryGetValue("Authorization", out var bearer);
if (bearer.Any())
{
string t = bearer[0].Split(" ")[1];
var handler = new JwtSecurityTokenHandler();
var token = handler.ReadToken(t) as JwtSecurityToken;
var utcNow = DateTime.UtcNow;
if (utcNow >= token.ValidFrom &&
utcNow <= token.ValidTo)
{
userId = token.Claims.FirstOrDefault(_ => _.Type.Equals("sub")).Value;
}
else
{
userId = String.Empty;
}
}
}
}
}
return userId;
}
}
My only problem here is that the jwt token isn't validated, so I am guessing that a "bad person" could just mingle with the valid to datetime, and keep extending the token lifetime. Please correct me if I am wrong on this.
What i want to know is: is there a way for me to validate the token? I know the JwtSecurityTokenHandler can call "ValidateToken", but this method needs a signing key, and I really dont know how to get this. I use IdentityServer 4 to generate tokens. Is there some easy way of injecting the Key into the IoC so I can get it, or is there an easy way to validate the token, that I dont know of?
Any help is appreciated
Upvotes: 1
Views: 4079
Reputation: 27588
What i want to know is: is there a way for me to validate the token? I know the JwtSecurityTokenHandler can call "ValidateToken", but this method needs a signing key, and I really dont know how to get this. I use IdentityServer 4 to generate tokens.
When validating JWT token issued by Identity Server(using key pairs to issue/validate token) , specific for validating signature . API/resource server will pull down (and might cache) your identity providers discovery document located at OIDC endpoint : https://xxx/.well-known/openid-configuration
. This document contains materials that allow the resource server to validate the token ,read available keys from jwks_uri
.
Using key pairs menans the JWT token which is signed by IDS4 with private key. A JWT token is a non-encrypted digitally signed JSON payload which contains different attributes (claims) to identify the user/role. The signature is the last part of the JWT and needs to be used for verification of the payload. This signature was generated with the algorithm described in the header(RS256 for example) to prevent unauthorized access. In your api , you could use public key which published by IDS4(jwks_uri
) to validate the signature of the JWT token . Please refer to this document for more details about JWT token .
You can use JwtBearerAuthentication
middleware or IdentityServer.AccessTokenValidation
middleware will help do that process . Code sample here is for your reference . If you want to manually validating a JWT token . Click here for code sample .
My only problem here is that the jwt token isn't validated, so I am guessing that a "bad person" could just mingle with the valid to datetime, and keep extending the token lifetime.
It's not recommended to use token without validating it . Since the signature part of JWT token is encrypted/encode use (header+payload) , even someone change the claims(expire time) , it won't pass the validation since he can't know Identity Server's private key to issue a correct signature .
Upvotes: 2
Reputation: 59
Inside your controller you can just do this:
if(HttpContext.User.Identity.IsAuthenticated)
{
var claims = HttpContext.User.Claims;
}
and you can inspect the claims for whatever information is of interest. that authenticated user identity is already validated and is available regardless of if the Authorize attribute is applied. If the user's cookie has expired etc that will return false. .
Upvotes: 2
Reputation: 5977
Since your access token is generated by IdentityServer4, then you should validate it using the IS4 Introspection Endpoint. This will give you the definitive answer as to if it is valid and whether or not it is still active.
Information about the Introspection Endpoint is in the IS4 docs at: http://docs.identityserver.io/en/latest/endpoints/introspection.html
As referenced in those docs, perhaps the easiest way to interact with the endpoint is to use the IdentityModel client library (add package via NuGet), which adds the IntrospectTokenAsync() extension method to HttpClient and returns a TokenIntrospectionResponse object that has the information you need.
IdentityModel client Introspection Endpoint docs: https://identitymodel.readthedocs.io/en/latest/client/introspection.html
Upvotes: 2