JWT Refresh Token in ASP.Net Core (a deep dive)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everyone and welcome to dotnet course central in last four videos I have been talking about authentication and authorization I started with GWT authentication then custom authentication then I went to role based authorization and then finally policy based authorization in today's video I'm going to cover a topic which I missed on my first video which is about refresh token in JWT authentication mechanism this is a request I got from one of my viewer as well so I wanted to tackle this in this video if you want to get a refresher on the JWT token I have provided the link up here so you can view it fast so let's start with the Refresh token so what is the Refresh token now when we create JWT token and this is the code where we were creating the JWT token so you can see that every GW token has an expiry and it can be in minutes or hours now the thing is that after the token is expired the client has to create a new token every time if they have to pass user ID and password that's kind of annoying and that's where the Refresh token comes in handy so in terms of the flow how it happens is when we create authentication token or JWT token we can create a refresh token as well and send it back to client and then refresh token is something which is much longer lived and the client can just keep it safely away and when the JWT token expert client can make a call with the JWT token as well as the refresh token and then based on the authenticity of the refresh token and the identity of the JWT token will create a new JWT token with an extended expiry and send it back that's essentially the flow so to start with that first what I'm going to do is I'm going to create a refresh token generator a class which will be responsible for creating refresh token so for that first I'm going to create an interface and I'm going to name it as I refresh token generator and this interface will have just one method it will have generate token next thing I am going to do is I am going to create a class to implement this interface for this implementation I am going to keep it simple I am going to create random number and I am going to create instead of generating a normal random number I am going to create an encrypted random number so for that first I am going to create white array and I am going to keep it as a 32-byte and this class random number generator is part of system dot security dot cryptography so I'm just going to add this namespace and this class has a static method called create and this will give me a random number and the next thing I'm going to do is from the random number generated I am going to get the bytes and put it into the random number I created earlier and then finally I am going to return base64 string of this byte so now I have the class which is responsible for generating a refresh token once I have that I'm going to go back to my GWT authentication manager where I was creating the token and here I'm going to change the implementation a little bit so instead of returning a string I'm going to return a tuple of string string so I'll return both JWT token as well as the refresh token but let me go back to the API fast so here we had the authentication and this was just returning a string token so now instead of just string token it will return an object so what I'm going to do is instead of returning a tuple I'll just go ahead and create a model which will represent the data so I'm going to create a new class and I'm going to name it as authentication response and this class is going to have two properties first one is the JWT token and the second one is going to be the refresh token the next thing I'm going to do is I'm going to go back to the authentication manager and here I'll change the implementation of the interface instead of string it's going to be a authentication response same is going to happen here so once I have that I'm also going to pass the interface which is the Refresh token generator so I'll have the Refresh token generator also part of the constructor and here after I generate this particular token I can have the Refresh token also so now I have both the token and here instead of filtering this I'm just going to do new of authentication response and here JWT token is what I was already returning and the Refresh token is going to be their refresh token so now that this implementation is done now I'm sending both JWT token as well as refresh token as a part of my implementation and now I'll go back here and here I'll change this implementation so instead of custom authentication manager I'll have JWT authentication manager get rid of the custom authentication manager and here I'm going to use JW the authentication manager to authenticate and of course it's token is now and returning unauthorized otherwise I am returning the token is at the newly created class in the dependency injection container because it is expected by the manager so I'll just add single term and this is I refresh token generator the class is refresh token generator and after I add the refresh token I also have to add the JWT authentication manager and for that I'm going to add and it's going to be authentic Asian manager I have to pass the token key which I have it here if you see my last video on JWT authentication you can see that this key is something which I use for encryption of the token and then I'll pass the I refresh token generator so I can just do get service off I refresh token generator here once I have this two configured I should be able to run now I will execute the HTTP endpoint and I can see that I have JWT as well as refresh token showing up here the other thing I have to make sure is that the authentication handler needs to be changed from custom to JWT authentication handler so I'm just going to do that I'm just going to remove this code and get the old code back of the JWT authentication handler so I'm just going to paste that code here so once I paste the authentication for the JWT let me add namespaces ok I'm going to get rid of the authorization code because it is not needed I'm also going to get rid of the indication manager just keep it to the JWT authentication related dll's so I have the Refresh token the JWT authentication manager and the JWT authentication handler and i'm going to go ahead and go into the inventory controller and change the authorization also because i don't need any authorization right now as long as i have authentication enabled that's all i need so all I'm going to do is setup the authorization attribute at the top level that's all I need now I'm going to run this application and once I run this I'm going to get the token so I got the JWT and refresh token both I'm going to take the JWT authentication token go to the gate and here I'm going to pass the new authentication token execute and I can see I'm getting 200 and I'm getting the values from the get method so now we are all set we got an authentication token now doesn't matter how many times I call my token is valid now I'm going to go ahead and implementation the method for the Refresh token so what's going to happen when we want to create refresh or when we want to refresh our token so for that I'm going to create a new method and I'm going to call it as refresh method or refresh token so let's go back to the name controller where we have authentication and let's create a new method here and just like I have used a credential object or user credential type I can create another class for accepting the user token and refresh token and I can name it as refresh cred and this one is going to have two property the first one is going to be the JWT token and the second one is going to be their refresh token so once I created that here in the Refresh method I'm going to expect that as my parameter now inside of this method first thing we have to do is we have to get the principal from the expire token which is extremely important we don't want to just assume that the expert token actually had a principal that might be compromised or it might be you know an invalid token we cannot just rely on the Refresh token so first thing we are going to do is we are going to get the principal from the token so for that what we have to do is we have to go ahead and create validation so we can do that using the standard token handler instead of doing all these things inside of this method itself I'm just going to create a class who is responsible for the refresh part so I'm going to go ahead and create a class called token refresher and this token refresher is going to have a single method and we can say it properly so this class is going to return the authentication response and then we'll say refresh and it's going to take the Refresh credentials okay so once I have that instead of this implementation first thing I'm going to do is I'm going to as I said get the principal we want to ensure that it's a valid principle so for that let's create a token handler so once we have that we can create a principle and we're going to do token handler dot validate token right and in the validation we have to pass the token which is from refresh credential parameter thought the JWT token and the next thing is the validation token validation parameters for that will create a new token validation parameter and inside of that we are going to say at the properties validate audience we are going to set it as false and then this is going to be exactly same as in the startup right so here we said these these are essentially the values so we can just copy paste things from here and paste them here and what we need is the key so the key is something which can be injected into the token refresher so I'm just going to create a constructor and I can have the key and we can expect the key let me also create an interface out of it for better testability okay so we have the key here and the key is I think this is not the string key is the bide array which is created out of this drink so we have the key now so so you have the validation parameter and then the third thing is out parameter of security token or Belgrade token so so we can declare it here so now we have the out validation token from this one so now we can have we just converted into JWT security token now here we have to ensure that the security token is not null because if security token is null then it's an invalid and then also the algorithm is equal to the algorithm we asked it to use so if we go back to the authentication manager the algorithm that we are using during signing is char 265 so we have to make sure that great them also matches so here we will say if JWT token is null or the JWT token dot header dot algorithm equals of this particular value and if it is not then in this two cases we just want to throw our new security exception so throw new security token exception and we can say in valid token passed so once we have this beyond this point means the token it is a valid token now we have the principal with us so once we have the principal the next thing is to do is figure out what the username is so we will be say bar equal to principal dot identity dot name and if you remember from the video username is something which we added into the claim type in the claim so username is something which is available in the identity so now once we have that got the username now next thing we have to do is make sure that the refresh token of this username is same as the refresh token that we are getting here as a part of refresh credential so do that what we have to ensure that the refresh token generated need to be saved as a part of the user which we are not saving today what we can do is and create a dictionary of the Refresh tokens just for the simplicity which will keep username and the Refresh token associated to it so we can create a dictionary called users refresh tokens and for the time being I'll just keep it public because it needs to be we should be able to access it from outside and we'll create is as a dictionary and here after everything is done what we are going to do is after the Refresh token is created we are going to add it to the users refresh token so we're going to do add and here we're going to use the user name as the key and then the Refresh token is the value so now we have the Refresh token saved and for this example it's an in-memory dictionary but in a real life scenario we'll keep it in some sort of you know data store so we have that now next thing I'm going to do is I'm going to have to get the eye kwt authentication manager because I need to get these objects I'll pass it in the constructor so that I can access it and here I'm going to say JWT authentication manager thought I have to expose this in the interface also expose the get so now if I come here I should be able to do use the Refresh token and then the key is nothing but the username so this will give me the Refresh token I can just compare it here so I can say that refresh cred dot refresh token if it is not equal to the Refresh token that we are getting right now it's not equal to the Refresh token in that case you know we're going to do the same thing we're just going to throw a security token exception because you know the refresh token is not matching so once we do that now we know that our refresh token and JWT or token are both valid we should be able to refresh the token now and for refreshing the token we can do something similar to this now this method needs a user ID password and does all the things but we don't need to do all of these all we have to do is we just have to generate the token we already have the principal right so we just need to generate JWT token and the Refresh token and then you know pass it along so for that what we can do is can just overload here JWT authentication manager so it makes sense creating an overload here so I can create can create an overload and this method instead of taking username and password is just going to take the claims which is what we are going to pass it to this because at this point we have the principal object which will have the claim of the user so we can have a claim array claims so once I have this overloaded authentication method what I need is I'm going to create the JWT Sakura tokens so if I save our JWT security token equal to new of JWT security token and instead of the security token the parameter that I'm going to pass are going to be the first one is going to be the claims which is from the parameter and the next one is going to be expiry which is going to be same as before which is the date time dot now and the third one is going to be the signing credential I'm just going to copy these two so Express is this and then here it's not signing credentials is this so and I need the key so I'm going to copy paste this line of the chord yeah so I have provided the key and everything and now my GWT token is ready so once I have this I'm going to create a new JWT security handler just like before and to write token and pass the JWT security token just like before so this will give me the JWT security token but I also need the Refresh token right I'm going to copy this line of code and this as well because it's very similar with a little bit of difference between the two method so give these and let's say I don't need this I can't just say token go to this and then yep and the other thing is I need username so I'm going to pass the username as a part of this method as well so now I have the username using which I'm going to save the Refresh token again back to the user refresh tokens so here it's not going to be straight forward and ideally it will be if use the token dot contains key a username then it will be user name of this username is equal to the Refresh token otherwise we are going to just add it's going to be the code and the same code will be here and just copy paste this code here I mean this code definitely would need refactoring but for the time being in the interest of time I'm just keeping it like this so we have this method as well now let's go and update the interface with this so this interface is getting a little bit ugly now if we go back here what we can do is we can now call the new method created GWT authentication manager dot authenticate and here we can pass the overload of username which we have the username and then for the claims we can say principal dot claims and I can just do two area and this one already returns the dis will return the authentication response the first thing I have to do is before I forget I have to add it to the startup so here I'm just going to add services dot add single turn and I'm going to add this guy and then I can do a token refresher it takes the key and next one is the GWT authentication manager I did about the authentication manager we can do that and this should be it so let me also get this to the new line so we have now everything set up so now the other thing I had to do is I have to go back to the controller in the in here and the Refresh token is I don't have to do any of these I'm just going to ask the new interface here in my constructor token refresher add it and here I'm going to say or token equal to token refresher tour to refresh and I'm going to pass the Refresh credential which I am getting as a part of parameter and I'll have similar code here if it is now then you know unauthorized as authorized and I'll also have same thing here because it is refreshing and instead of authenticate I'm going to name it as refresh so once I do that I'm going to run this application again so once the application is up and running I'm going to execute this so I got a new JWT - okay and I'll just validate that my token is working as expected and to go here and I'm going to run this I'm getting both the value now it's time to call the refresh token the Refresh method so just like this endpoint I can create another post which is going to go to refresh and here just like this post instead of username and password we are going to send the two token and and the header is going to be pretty much same it's going to be application Jason so the header is going to be content type application Jason and the body is going to provide raw body and in the row body I want to make sure I am using the appropriate value for the refresh credential JWT token and refresh token I'm going to come here and pass token and the next one is the Refresh token token and I'm going to copy the JWT token and refresh token from here and paste it because that's how the user is going to call this method to get a new refresh token as well as jwd token and for this one I'm just going to put a breakpoint so that we can walk through the method get here the breakpoint and send this so our big point is here now I'm going to do an element so we'll go here and then here so we are going to fill a date let's see the principal so the principal is back and we can see the principal has claims which is expected the identity is there and the identity has the username so it is so far so good now JWT token is also returned we can see is 256 yeah it's 256 I'm killing it the signature I should just give it the sha-256 let's just ignore case I also have to make a change to that user refresh token it has to be get and set here and here instead of plain and simple so on I'll have to have a get and set and then in the constructor I'm just going to create it so use a refresh token equal to new New York dictionary string string so once I have that I'm going to run these then execute these I get the new JWT token and refresh token which I am going to use in this method once I have that I'm going to send this request go inside and I can see my username is there my DW token is valid the first token is there and this one contains one and this should match exactly and I should get back a new claim so it will get insert the new authentication method and this is pretty much going to create a new security token update the refresh token create the new authentication and return here I can see I have got 200 back and the new JW token as well as a refresh token so this is all I have to cover today thank you so much for watching this video if you liked the video please give me a thumbs up and if you have been getting value from this channel please subscribe thank you so much
Info
Channel: DotNet Core Central
Views: 28,869
Rating: undefined out of 5
Keywords: jwt token, asp.net core, authentication, jwt, jwt refresh token, asp.net core authentication, asp.net core jwt token, asp.net core jwt refresh token
Id: 7JP7V59X1sk
Channel Id: undefined
Length: 33min 13sec (1993 seconds)
Published: Mon Jan 27 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.