OWIN Bearer Token Authentication - c#

I have some questions related to Bearer Token. In Owin you can protect a ticket Protect(ticket) like this:
ClaimsIdentity identity = new ClaimsIdentity(Startup.OAuthServerOptions.AuthenticationType);
identity.AddClaim(new Claim(ClaimTypes.Name, user.UserName));
Dictionary<string, string> properties = new Dictionary<string, string>();
properties.Add("UserId", user.Id);
properties.Add("UserName", user.UserName);
properties.Add("Role", "user");
AuthenticationProperties properties = new AuthenticationProperties(properties);
AuthenticationTicket ticket = new AuthenticationTicket(identity, properties);
DateTime currentUtc = DateTime.UtcNow;
DateTime expireUtc = currentUtc.Add(TimeSpan.FromHours(24));
ticket.Properties.IssuedUtc = currentUtc;
ticket.Properties.ExpiresUtc = expireUtc;
string token = OAuthAuthorizationServerOptions.AccessTokenFormat.Protect(ticket)
Now the token will be something like this:
nqak-9R6U64Owsm_lqn_mJzKc_Djd8iVnIw0EX77v5x2rybhf4m_zg_UnrsoO5BxDZQl0HWrSvvd4efa4ChNSf5rAGhd13aOXZlvwOJOZ5v_9bhRCq8A7tqHyiM6DqVVOyYs3lh2SU-wU1m85HH2IcYDtdTY3ijaKZ_QnP1nsqO5LRnnEL4upbETPW9zqWIZzZBX7_Y2cXi2v0K7WnlRor3gFKIZlU9J-NfidRpWXqq5744NfWWHalYADGS7eUWyuxPJCj9ykHYzaXFksJEXBw
My questions:
How this token is generated/encrypted?
Are there any chances that somebody can try to mess'up with the token and add some custom claims to it?
Example:
If you have the token string you can do this:
AuthenticationTicket ticket = OAuthAuthorizationServerOptions.AccessTokenFormat.Unprotect(token);
Now you can add custom claims to it. For example if there is a role claim with value user then you can modify that claim and add admin then re encode the ticket and you get a token that has admin role.
I actually din some tests, encoded a token on a server and then try to modify it on another system but I couldn't Unprotect it. Therefore I am thinking maybe the ticket is encrypted/decrypted using the machine key on which was originally created. However if I try to Unprotect it from the same machine it works. I can decrypt it and modify it.
Can somebody explain this process please?

How this token is generated/encrypted?
The data protection provider can be set using the SetDataProtectionProvider extension method on the IAppBuilder object. When this is not done, the data protection provider of the host is used. In case of IIS + ASP.NET, this is MachineKeyDataProtector in the assembly Microsoft.Owin.Host.SystemWeb. For self-hosting, this will be DPAPI. Basically, the token is encrypted and then MACed and that is what Protect() is all about.
Are there any chances that somebody can try to mess'up with the token and add some custom > claims to it?
No. This is not possible. Token protected in a machine cannot be unprotected somewhere else. An exception to that will be the case of a web farm where you have multiple machines. One machine can protect and if the subsequent request goes to some other machine, that machine should have the ability to unprotect. With DPAPI, this is not possible. With MachineKeyDataProtector, this is possible by having the same machineKey section in all the machines. But then if you are concerned about some MITM being able to do this, then no, it is not possible.

Related

How to add custom claims to Jwt Token in OpenIdConnect in .Net Core

Just like AzureAD we have our own custom Firm ActiveDirectory which we are connecting from UI as well as API for Authentication in .NetCore using OpenIdConnect (AddOpenIdConnect extension method).
In my use case after authentication on UI side, I need additional application specific claims from my custom database which I am adding "OnTokenValidated" - this is needed for hiding or exposing the UI elements based on Roles and Claims.
OnTokenValidated = async ctx =>
{
//Get user's immutable object id from claims that came from Azure AD
string oid = ctx.Principal.FindFirstValue("http://schemas.microsoft.com/identity/claims/objectidentifier");
//Get EF context
var db = ctx.HttpContext.RequestServices.GetRequiredService<AuthorizationDbContext>();
//Check is user a super admin
bool isSuperAdmin = await db.SuperAdmins.AnyAsync(a => a.ObjectId == oid);
if (isSuperAdmin)
{
//Add claim if they are
var claims = new List<Claim>
{
new Claim(ClaimTypes.Role, "superadmin")
};
var appIdentity = new ClaimsIdentity(claims);
ctx.Principal.AddIdentity(appIdentity);
}
}
Now after token validation on API side again I have to call the custom database to fetch application specific roles. Is it possible to include these roles in JWT token itself so on API side all roles and claims(AD + Custom DB) are present. Or any other way by which I don't have to call CustomDB again in API.
Adding custom claims to access tokens is a capability of the Authorization Server (AS) and not all of them support this - though they should since it is an important feature. If you can say exactly what provider you are using I may be able to tell you whether it is possible.
These are the factors to think about:
Find out if the AS can reach out and get custom claims at the time of token issuance as in this Curity article.
Be careful to not return detailed JWTs to internet clients and aim to keep them within your back end instead. Opaque tokens can help with this as in this other Curity article
If custom claims are not possible for your provider then you can look them up in your API(s) when an access token is first received and then cache the claims in memory. This leads to more complex API code but is necessary for some providers.

How to set custom claims to aad token using C# code

I have a webapi which generates aad token and I have written token generation logic in Get() method in webapi.
I'm able generate aad jwt token from webapi get() method but, now I want to include some custom claims into the token.
How can I set custom claims to aad token using c#.
I have used below code for generating aad token.
var authenticationContext = new Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext("https://login.windows.net/" + ConfigurationManager.AppSettings["TenantID"].ToString());
var credential = new ClientCredential(clientId: ConfigurationManager.AppSettings["ClientID"].ToString(), clientSecret: secret);
var result = await authenticationContext.AcquireTokenAsync(
ConfigurationManager.AppSettings["Resource"].ToString(),
credential
).ConfigureAwait(false);
Kindly share any sample c# code to set custom claims to aad token generated from above code .
Note: I want to set a new custom claim for aad token where custom claim value obtained from external logic.
Update 1:
Looks like below post may be useful.
https://www.rahulpnath.com/blog/azure-ad-custom-attributes-and-optional-claims-from-an-asp-dot-net-application/
I tried below following above post.
Generated jwt token to call Graph API. But I got blocked at below code.
var dictionary = new Dictionary<string, object>();
dictionary.Add(employeeCodePropertyName, employee.Code);
//Here I can't use graphApiClient.Users because, I don't have any user info on my jwt token. It will be just Access token which as details related to aad application.I want to update extension attribute which is present in OptionalClaims -> Access Token of AAD Application Manifest.
await graphApiClient.Users[employee.EmailAddress]
.Request()
.UpdateAsync(new User()
{
AdditionalData = dictionary
});
How to update extension claim attribute present in access token of optional claims . I want to update through c# code.
How to do that. Kindly suggest.
Update 2:
I want to use code similar to below for updating custom extension claim attribute present in optional claims of azure ad app but UpdateAsync is not working.
await graphApiClient.Application[clientid]
.Request()
.UpdateAsync(new Application()
{
AdditionalData = dictionary
});
At UpdateAsync(), I'm getting issue as below
Specified HTTP method is not allowed for the request
Kindly let me know the solution to add custom user defined claim to azure ad access token.
Note: Since, I want to update access token ,there will be not be any user info on access token. So, graphApiClient.Users[employee.EmailAddress] won't work, as access token will not have any user info like EmailAddress
I have created extension claim attribute in azure ad ap manifest as below
I want to update extension claim attribute extension_clientid_moviename value dynamically with value obtained from external source through code. How to do that. Kindly suggest.
Update 3:
I have tried below code to update extension claim attribute present in Optional claims ID Token.
await graphApiServiceClient.Users["abcd#hotmail.com"]
.Request()
.UpdateAsync(new User()
{
AdditionalData = dictionary
});
I am getting error as below
Code: Request_ResourceNotFound\r\nMessage: Resource '' does not exist or one of its queried reference-property objects are not present.
That is because you are using OAuth 2.0 client credentials flow to get access token :
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow
That flow is commonly used for server-to-server interactions without immediate interaction with a user. So you can't find user information in access token .
The document you provided is adding User's extension property , update that value via Microsoft Graph :
await graphApiClient.Users[employee.EmailAddress]
.Request()
.UpdateAsync(new User()
{
AdditionalData = dictionary
});
That email is not from access token , you should manually provide the user's email who the api wants to update the properties value .
But since the property is a User's extension property , you can get the value from claims in ID token when user login with Azure AD in your client app . That claim won't include in access token which issued using client credential flow .
Regarding the issue in Update 3, we can not use the guest user email here. We should use ObjectId instead. That's why you got Request_ResourceNotFound error.
await graphApiServiceClient.Users["ObjectId"]
.Request()
.UpdateAsync(new User()
{
AdditionalData = dictionary
});

Token based implementation in webapi to secure endpoints

I am having a web application with web service and client will register their application using my web application.
Now client will have application of type SPA or mobile apps and they will consume my webservices from their apps.
So I would be implementing token based mechanism for securing access to my endpoints.
1) But here I am confused that shall I use any framework to generate access token or I can use any library which will generate any random string which i will send in response.for instance something like this :
TokenId = Convert.ToBase64String(Guid.NewGuid().ToByteArray()).Replace("+", "_")
So while registering application if client have enabled authentication for their application then user will be validated and then I will return access token and also save accesstoken in my database with that user id.
So my database table would be like below for storing validated accesstoken :
Id(autogenerated) accesstoken userid clientid createdat expiresat
So after user is authenticated and now if user want to access any protected resources then user need to pass this access token in subsequent call in header.
So what I will do I will get access token from header and then validate that accesstoken against that database and then allow access to my protected resource other wise user would get authorized.
I have seen lots of things related to this so basically this is oauth2 and I want to implement this.
I have seen Openid connect(this project doesnt even compile) which is on top of oauth2 and which is used for authentication and oauth2 will be used for authorization.
But here as I am storing access token in my database so here is my doubt related to that :
2) Now do I need openconnectid (but this project doesn't even compile) for validating access token or as I am having storing access token in my database I don't need openconnectid?
3) I want to implement asp.net identity but then I will receive dynamic database connection string and as i have seen asp.net identity mostly works with entity framework I couldn't find any source where I could use ado.net to validate username and password using SQL query. I know I can do something like this :
Make a custom user class which implements IUser as described here
Define a custom user store which implements
public class UserStoreService
: IUserStore<CustomUser>, IUserPasswordStore<CustomUser>
But I won't be having this information as I don't have fixed connection string.connection string again is stored in database with client registration.
4) We have given user a fixed endpoint through which client can create an admin so for that I will use my RSA algorithm for password hashing and then store it in database. So with this now do i need to use asp.net identity?
5) I have seen lots of following link with token based implementation but I am not getting where they are validating accesstoken in which part but now as I am having accesstoken stored in my database do I need to use any of the following implementation?
http://bitoftech.net/2014/10/27/json-web-token-asp-net-web-api-2-jwt-owin-authorization-server/
http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/
6) Moreover if for any client if client don't want authentication for its respective application then what I will do is I will don't have that username password validation but I will simply generate accesstoken and then send in response so then in every subsequent request that access token will be pass to access protected resources.Do you think this make sense?
I have never seen any example where access token is store in database and problem with storing access token in database would be I have to make a call to database every time to validate access token for each endpoint.
Update :
Use case of my webservice engine would be:
1) Support multiple client application.
2) Manage user session in the form of token management for each client application. So here as most of the article is storing accesstoken in identity and that identity is validated inside [Authorize] attribute in which accesstoken is also validated and based on that user is allowed to access protected resources.This is what my understanding is up until now.
So if I also user identity and store user context inside identity supporting multiple client application is a good idea?
From “7.1. Access Token Representation” in “Full-Scratch Implementor of OAuth and OpenID Connect Talks About Findings” :
How should an access token be represented? There are two major ways.
As a meaningless random string. Information associated with an access
token is stored in a database table behind an authorization server.
As a self-contained string which is a result of encoding access token
information by base64url or something similar.
Pros and cons of these two ways are described in the blog.
If access tokens are random strings, pieces of information associated with the access tokens (user ID, client ID, scopes, lifetime, etc.) are stored in a database which is managed by the authorization server which have issued the access tokens.
Whenever a resource server which exposes APIs accepts an API call from a client application, the resource server has to get the information about the access token in some way or other.
If the resource server can access the database managed by the authorization server (in other words, if the resource server and the authorization server shares the database), the resource server can get the information about the access token from the database directly.
Otherwise, the resource server has to make an API call to the authorization server to get the information. In this case, it can be expected that the authorization server exposes an API which complies with RFC 7662 (OAuth 2.0 Token Introspection). Note that some implementations may provide a more developer-friendly API than RFC 7662 (e.g. “4. Introspection Access Token”).
Anyway, your resource server doesn't necessarily have to make a DB call (or an introspection API call to the authorization server) every time if the server caches information about access tokens in a memory cache or somewhere else appropriate.
BTW, what you need when you want to protect APIs is access tokens. Therefore, your system doesn't have to support OpenID Connect which is a specification as to how to request and issue ID tokens. You may be confused because a server which supports OpenID Connect can issue access tokens, too, in addition to ID tokens. See “Diagrams of All The OpenID Connect Flows” to understand what a server which supports OpenID Connect issues.
Finally, identity management, user authentication, and OAuth 2.0 & OpenID Connect don't necessarily have to be implemented in a monolithic way. See “New Architecture of OAuth 2.0 and OpenID Connect Implementation” for details.
No, you don't need to store the access_token on the database. You can decrypt the JWT and read the information as you are the one who encrypts it with a secret key. (By default it's the machine key.)
Identity has a off the self support for Oauth. You have to just configure it properly. You can set-up the configuration for OAuthAuthorizationServerOptions in the Startup.Auth.cs. Sample code as follows. I have tried to answer most of your question in comments in the code.
public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
public static string PublicClientId { get; private set; }
public void ConfigureOAuth(IAppBuilder app)
{
// Configure the application for OAuth based flow
PublicClientId = "theDragonIsAlive";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new YourOwnApplicationOAuthProvider(PublicClientId),
//AuthorizeEndpointPath = new PathString("/Access/Account"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(7)
//AllowInsecureHttp = true
};
// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);
}
public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
{
private readonly string _publicClientId;
public ApplicationOAuthProvider(string publicClientId)
{
if (publicClientId == null)
{
throw new ArgumentNullException("publicClientId");
}
_publicClientId = publicClientId;
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
// This where you are validating the username and password credentials.
ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);
if (user == null)
{
context.SetError("Dragon Fire:", "The user name or password is incorrect. You shall be burnt.");
return;
}
ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager,
OAuthDefaults.AuthenticationType);
AuthenticationProperties properties = CreateProperties(user.UserName);
AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
context.Validated(ticket);
context.Request.Context.Authentication.SignIn(oAuthIdentity);
}
public override Task TokenEndpoint(OAuthTokenEndpointContext context)
{
foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
{
context.AdditionalResponseParameters.Add(property.Key, property.Value);
}
return Task.FromResult<object>(null);
}
// This method is where you will create the client access token.
// First you get the client, you can place values from the client record into the tokens claim collection.
// You then create a new ClaimsIdentity.
// You add some claims, in the example client name is added.
// Create an AuthenticationTicket using your claims identity.
// Validate the ticket (you do need to do this or the client will be considered unauthenticated)
//public override Task GrantClientCredentials(OAuthGrantClientCredentialsContext context)
//{
// var client = clientService.GetClient(context.ClientId);
// var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
// oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, client.ClientName));
// var ticket = new AuthenticationTicket(oAuthIdentity, new AuthenticationProperties());
// context.Validated(ticket);
// return base.GrantClientCredentials(context);
//}
// This method has to be implmented when you are maintaining a list of clients which you will allow.
// This method is for validating the input, you can used this method to verify the client id and secret are valid.
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
//string clientId;
//string clientSecret;
//context.TryGetFormCredentials(out clientId, out clientSecret);
//if (clientId == "1234" && clientSecret == "12345")
//{
// context.Validated(clientId);
//}
//return base.ValidateClientAuthentication(context);
// Resource owner password credentials does not provide a client ID.
if (context.ClientId == null)
{
context.Validated();
}
return Task.FromResult<object>(null);
}
public override Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context)
{
if (context.ClientId == _publicClientId)
{
Uri expectedRootUri = new Uri(context.Request.Uri, "/");
if (expectedRootUri.AbsoluteUri == context.RedirectUri)
{
context.Validated();
}
}
return Task.FromResult<object>(null);
}
public static AuthenticationProperties CreateProperties(string userName)
{
IDictionary<string, string> data = new Dictionary<string, string>
{
{ "userName", userName }
};
return new AuthenticationProperties(data);
}
}
The sample code above does not have separate client classifications. It will treat all users as a single type of client. But I have given some example code in the comments which will guide you to get started in the right direction.
Disclaimer: I am not an expert on this(yet) and my setup is different. I had an existing MVC application with Owin and I had to build a webapi on top of it. This was my prototype code and it did the job. You will have to improve in it for your production code. Have fun and good luck.

OAuth Bearer Access Token sliding expiration

Let's suppose that we're using OAuth Bearer tokens to secure our API. There is NuGet package with OWIN middleware that will do it for us: https://www.nuget.org/packages/Microsoft.Owin.Security.OAuth.
Everethig looks great, until raises question about access token expiration - we don't want to force use to re-login over and over again. As far as I understand there are three basic ways:
Make Access Token expiration time very big (1 month for instance)
Use OAuth Refresh Tokens that adds much difficulties to both Authentication Server and the user application code (described in following article http://bitoftech.net/2014/07/16/enable-oauth-refresh-tokens-angularjs-app-using-asp-net-web-api-2-owin/)
I'm curious is it possible to create the endpoint that will require access token that is about to expire and just answer with new access token to simulate kind of sliding expiration for OAuth Access Tokens?
WARNING! Here is the solution that NO ONE SHOULD USE if you're not 100% sure that your application guarantees (which is impossible) that Access Token can not be compomised (for instance, XSS vulnerability allows to steal Access Token). In this solution once Access Token leaked it can be used to indefinitely prolong the access. OAuth Refresh Tokens solve exactly this problem, limiting access in case of compromising Access Token with very short amount of time, usually about 15 minutes.
[Authorize]
public class RefreshTokenController : ApiController
{
[HttpGet]
public HttpResponseMessage ReissueToken()
{
// just use old identity
var identity = ((ClaimsPrincipal)User).Identity as ClaimsIdentity;
var ticket = new AuthenticationTicket(identity, new AuthenticationProperties());
DateTimeOffset currentUtc = new SystemClock().UtcNow;
ticket.Properties.IssuedUtc = currentUtc;
ticket.Properties.ExpiresUtc = currentUtc.AddMinutes(30);
string token = Startup.OAuthBearerAuthOptions.AccessTokenFormat.Protect(ticket);
return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ObjectContent<object>(new
{
accessToken = token,
expiresIn = (int)((ticket.Properties.ExpiresUtc.Value - ticket.Properties.IssuedUtc.Value).TotalSeconds),
}, Configuration.Formatters.JsonFormatter)
};
}
}

Dealing with long bearer tokens from webapi by providing a surrogate token

I am building a web api using ASP.NET WebApi 2 using claims authentication, and my users can have very large number of claims. With a large number of claims the bearer token grows very large quickly, so I am attempting to find a way of returning a much shorter bearer token.
SO far I have discovered that I can provide a IAuthenticationTokenProvider to the OAuth options OAuthAuthorizationServerOptions.AccessTokenProvider property:
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AccessTokenExpireTimeSpan = TimeSpan.FromHours(12),
AccessTokenProvider = new GuidProvider() // <-- here
};
And this gives me a chance to intercept the AuthenticationTicket and stash it away, replacing it with something simpler - in my example below a hashed guid. (Note: At the moment this class simply holds a ConcurrentDictionary<string,AuthenticationTicket> with my sessions - in a real-world example I intend to store the sessions in some persistent storage)
public class GuidProvider : IAuthenticationTokenProvider
{
private static ConcurrentDictionary<string, AuthenticationTicket> tokens
= new ConcurrentDictionary<string, AuthenticationTicket>();
public void Create(AuthenticationTokenCreateContext context)
{
throw new NotImplementedException();
}
public async System.Threading.Tasks.Task CreateAsync(AuthenticationTokenCreateContext context)
{
var guid = Guid.NewGuid().ToString();
var ticket = Crypto.Hash(guid);
tokens.TryAdd(ticket, context.Ticket);
context.SetToken(ticket);
}
public void Receive(AuthenticationTokenReceiveContext context)
{
throw new NotImplementedException();
}
public async System.Threading.Tasks.Task ReceiveAsync(AuthenticationTokenReceiveContext context)
{
AuthenticationTicket ticket;
if (tokens.TryGetValue(context.Token, out ticket))
{
if (ticket.Properties.ExpiresUtc.Value < DateTime.UtcNow)
{
tokens.TryRemove(context.Token, out ticket);
}
context.SetTicket(ticket);
}
}
}
So my questions:
Is this an appropriate (and secure!) way of providing a surrogate key in place of my long claims-generated token?
Is there perhaps a better/easier place where I should be doing this within the webapi/OAuth stack?
Another thing to note is that I intend to support refresh tokens, and in fact the example above was pulled from examples which use this sort of mechanism for the Refresh token - except with a refresh token they appear to be single-use, so the ReceiveAsync method would usually always remove the refresh token supplied from the ConcurrentDictionary, I'm not entirely sure I understand why?
I do not recommend to do this because you are eventually going to store the authentication tickets into the database or Redis server, the draw back here that with each request containing a bearer token, you are going to check this permanent store in order to resolve the Guid and get the ticket again to construct it.
I suggest that you use JSON Web Token JWT instead of the default bearer access tokens format, to do this you need implement your custom access token format CustomOAuthProvider in property Provider in OAuthAuthorizationServerOptions as the code below:
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
//For Dev enviroment only (on production should be AllowInsecureHttp = false)
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/oauth2/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
Provider = new CustomOAuthProvider(),
AccessTokenFormat = new CustomJwtFormat("http://jwtauthzsrv.azurewebsites.net")
};
I've noticed that adding more claims to the JWT token won't increase its size dramatically as the case of default access token format.
Below a sample of 2 JWTs with different claims inside each one, the second one is larger than the first by only 50 chars. I recommend you to check the encoded content of each one using jwt.io
First JWT:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1bmlxdWVfbmFtZSI6InRhaXNlZXIiLCJzdWIiOiJ0YWlzZWVyIiwicm9sZSI6WyJNYW5hZ2VyIiwiU3VwZXJ2aXNvciJdLCJpc3MiOiJodHRwOi8vand0YXV0aHpzcnYuYXp1cmV3ZWJzaXRlcy5uZXQiLCJhdWQiOiIwOTkxNTNjMjYyNTE0OWJjOGVjYjNlODVlMDNmMDAyMiIsImV4cCI6MTQxODY0NzMyNywibmJmIjoxNDE4NjQ1NTI3fQ.vH9XPtjtAv2-6SwlyX4fKNJfm5ZTVHd_9a3bRgkA_LI
Second JWT (More claims):
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1bmlxdWVfbmFtZSI6InRhaXNlZXIiLCJzdWIiOiJ0YWlzZWVyIiwicm9sZSI6WyJNYW5hZ2VyIiwiU3VwZXJ2aXNvciIsIlN1cGVydmlzb3IxIiwiU3VwZXJ2aXNvcjIiLCJTdXBlcnZpc29yMyJdLCJpc3MiOiJodHRwOi8vand0YXV0aHpzcnYuYXp1cmV3ZWJzaXRlcy5uZXQiLCJhdWQiOiIwOTkxNTNjMjYyNTE0OWJjOGVjYjNlODVlMDNmMDAyMiIsImV4cCI6MTQxODY0NzQ1NiwibmJmIjoxNDE4NjQ1NjU2fQ.TFEGDtz1RN8VmCQu7JH4Iug0B8UlWDLVrIlvc-7IK3E
The JWT format is becoming the standard way to issue OAuth 2.0 bearer tokens, as well it will work with refresh token grant. But keep in mind that JWT is only signed tokens and not encrypted as the case in default access token format, so do not store confidential data in.
I've written detailed blog post on bitoftech.net on how to use JWT tokens in ASP.NET Web API along with a live demo API and source code on GIthub, feel free to check it and let me know if you need more help.
Good luck!

Categories

Resources