Token Authentication In ASP.NET Core 7 With JWT | Clean Architecture

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi everyone it's about time that we talked about authentication in today's video we're going to implement Json web token authentication for our web API we're going to create an endpoint that is going to accept our login credentials and it's going to return our Json web token as a response then we're going to use this Json web token to authenticate our API requests so let's see how we can implement this we're going to start out in the application layer and let's create a feature folder for our login feature we're first going to add our login command that is going to contain the information that is required for us to authenticate our user I'm going to make it into a record instead of a class and all I need from the properties on the login command is going to be the email of the user in a real world scenario you also want to pass in a password for that user and then hash that password and compare it with some hashed password that you can safely store in the database but I'm not going to implementing that today I want to focus on generating the actual Json web token to make this an actual command I need to inherit from the I command interface and I'm going to make the return type of this command a string which is going to represent our Json web token so this is everything that I need for the login command I'm also going to add a simple request class that I'm going to expose on the API endpoint and it is going to represent the request body on our post endpoint that we're going to create later in this video so I'm going to call it login request I'm also going to make it a record and it's going to have the same properties as our login command because we are going to be mapping from the login request to our login command so this is everything that I need for the login request and now I'm going to add the Handler for our login command so let's create the login command Handler and this is where the implementation for generating the Json web token is going to live I'm going to make this class shield and I'm going to inherit from the I command Handler interface the command that we are handling is the login command and the response is just the string which is going to be our Json map token let's implement the missing members so what do I need to actually log in the user and generate a Json web token I think we can divide this implementation into three steps so our user is actually the member of our system so the first step is going to be to get the member if a member exists then we can just generate the Json web token and the last step is just going to be to return the Json web token so the first step that we need is to fetch the member from the database based on the email that we have in the login command so for that I'm just going to inject the eye member repository we need to initialize this field from The Constructor and now that I have the member repository I can fetch the member from the database I'm going to make the handle method asynchronous so that we can await our database Cloud so the method that we are going to call on the member repository is going to be to get the member by the email if I take a look at the member repository get by email async method you can see that I need an email value object instance to pass in as the argument so I'm first going to do that I'm going to create an email using the email create method and we can just pass in the email that we received from our login command the email create method returns a result of email object you may want to check that the result is actually a success result but I'm not going to do that now I'm going to focus on the actual implementation so I need to pass in the actual email value object in into the get by email method and also the cancellation token and of course we need to await the execution of this method because it is a asynchronous and store the result inside of a variable so I'm going to rename this into member now that we have our member we have to notice that it can be null because we may not have a member with that email in the database so in that case I want to return a failure result and map that into a 400 bed request response so I'm going to go ahead and check for that if the member is now then I want to return a failure result so I'm going to say result failure of string and the error that I'm going to specify is going to be the invalid credentials we should return the same error in case of a password mismatch if we had added a password to our login command we would also check for that password and return the same invalid credentials response when the password does not match the password that belongs to this member so this covers the first step for getting the member and I'm going to get rid of the comment and now we have to tackle the second step to generate the Json web token for this step I'm just going to create an abstraction for providing the Json web token I'm going to add an interface inside of the abstractions folder that is going to represent our Json web token provider I'm going to name it I JWT provider and we're going to be injecting this provider into the login command Handler and it's only going to have one method that Returns the string which is going to represent our Json web token and let's name the method generate what we are going to pass as an argument to the generate method is going to be the member that we have previously fetched inside of the login command Handler so this takes care of the definition for our Json web token provider and let's move back to the login command Handler and use this interface I'm going to add a field inside the login command Handler for the Json web token provider and we're going to inject this field from The Constructor now that we have injected our Json web token provider let's go ahead and use it inside of the handle method so the Second Step here becomes very simple I'm just going to capture the token inside of a variable and we're going to call the Json web token provider generate method and pass in the member and now that we have our token we can just return it from this command Handler and we can get rid of these comments so this is going to be our login command Handler implementation I'm going to implement the Json web token provider in just a moment but first I want to create an API endpoint that is going to send this command and return a Json web token as the response so inside of the presentation project I'm going to go over to the members controller and let's add a new post request just before the register member endpoint I'm going to quickly create the method it's going to be public casing it's going to return a task of I action result and I'm just going to call it login member we're going to send the login credentials inside of the request body so I'm going to use the front body attribute and we're going to use the login request that we just created as the request for the login member endpoint and I'll also add the cancellation token here and now we can Define our endpoint we first need to create an instance of our login command so I'm going to use the email that comes from the login request I'm going to capture the result of sending this command inside of a variable it's going to be a result of string and I'll name it token result and to get this result we have to await the sender.send call and pass in our Command and cancellation token if the token result is failure property resolves to true then we are going to return the call to handle failure and I'm going to pass in the token result this is going to handle the case when we specify the invalid credentials and it's going to return the appropriate response from this endpoint in this case that's going to be a 400 belt request response otherwise if it's not a failure result then we have a successful result and we can return the token result value from this endpoint which is going to return the actual Json web token to the API consumer so with that out of the way let's handle the Json web token provider implementation I'm going to add that inside of the infrastructure folder and I'll add a new folder here for holding the implementation which I will call authentication we're going to be adding more stuff inside of this folder in the future videos because I'm going to be implementing permission authorization where it was a very requested feature by the viewers so make sure that you don't miss those videos because they are going to be very valuable I'm going to add a class here which is going to hold our Json web token provider implementation I'm going to make it sealed and it has to implement our Json web token provider interface so all we have is just one method that takes in the member and generates our Json web token to be able to generate Json web tokens I need to add a nuget package here so I'm going to go ahead and do that I'm going to type in JWT for Json web token and the library that we are looking for is the Microsoft SP net core authentication JWT Bearer so I'm going to go ahead and install this nuget package and now that we have installed it we can return to our JWT provider and Implement generating the Json web token so now that we added the nougat package that we were missing we have access to a new class that I'm going to use to generate the token and this is going to be the JWT security token class we're going to create a new instance of this class and then serialize it into a string and return that as the actual Json web token so the Constructor that we are going to call is going to accept a few arguments we are going to specify the issuer as a string we are also going to specify the audience then we are going to add an array of claims I'm just going to pass in null for now and we're going to get back to this in just a moment I'm going to pass in null for the not before argument for the expiration time we can use the current UTC time and specify an expiration date that is for example one hour into the future so that our Json web token has a one hour Lifetime and lastly we need to specify the signing credentials and I'm also going to specify now and now we're going to handle all of the arguments one by one we need an array that is going to create the claims for this Json web token so I'm going to create a new array of claims and for now I'm going to leave it empty and we're going to populate this array in just a moment but let's pass it in as the argument here so that we don't forget another thing that we needed was the signing credentials so let's create that I'm going to create a new instance of the signing credentials class and you can see that it accepts two arguments the security key and the algorithm that we're going to use for the security key argument I'm going to use a new symmetric security key to create a symmetric security key we need an array of bytes I'm going to use a string as a security key and then convert it into an array of bytes we are going to do that by calling and calling utf-8 and the method that we need is the get bytes method and we are going to be passing our secret key here in just a moment so this takes care of our symmetric security key and the second argument is the algorithm that we're going to be using for encrypting our Json web token I'm going to access the security algorithms class so let's use the hmac shot 256 as the security algorithm for the signing credentials now that we have our signing credentials instance we can pass it as the argument to the JWT security token and this takes care of actually creating our token and now that we have our token we can convert it into a string I'm going to capture the string value inside of a variable we are going to create a new instance of the JWT security token Handler and on it we can call the right token method and specify our Json web token and it's going to serialize it into a JWT string then we can return from this method so we can just return the token value and this completes our implementation we have a few missing pieces to make this a complete implementation you can see that I'm hard coding the issue and the audience of the Json web token and also I'm not passing in a proper secret key to the signing credentials so let's handle that before we move on I'm going to add a new class here which is going to hold the JWT options we're going to use the options pattern to inject this class and it's going to contain the configuration information that we need for our JWT provider so I'm going to create a few properties I need the issue property first so I'm going to create a get an init property the second property that I need is the audience and the last one is going to be our secret key so now that we have our JWT options class we're going to inject it inside of the Json web token provider so I'm going to create a field that is going to hold the Json web token options so let's go ahead and do that I'm going to name the variable options and I'm going to inject it from The Constructor the problem is I can't inject the JWT options directly I have to go through the i options interface and access the value on the injected options to get our actual JWT options instance so now that we use the options pattern to inject our configuration let's go ahead and use that in the generate method here instead of hard coding the secret key I'm going to pass it from the options and here below I'm going to say options issue and also options audience to specify the configurable values and this nearly completes our JWT provider implementation the only thing that is missing is to specify a few claims that are going to be added to our Json web token so let's go ahead and do that we're going to add a few claims here by creating a new instance of a claim for the type of the claim we can use the JWT registered claim names to get access to predefined claim names that we can use the one that I'm interested in is the subject claim and I'm going to specify the member ID as the value for the subject claim and I'm going to add one more claim here which is going to hold the member email so let's go ahead and do that I'm going to use the JWT registered claim names we're going to use the email claim and specify the member email value as the value for our claim so this takes care of adding our claims signing our Json web token and then serializing the Json web token into a string which we are returning as the result of this method so what's missing now is just a few pieces of configuration inside of our web API to actually enable authentication using Json web tokens and then we can test out our implementation and see how it actually works before I show you the rest of the implementation I'm going to kindly ask of you to smash that subscribe button to make sure that you receive the notifications when I release my new videos because you definitely don't want to miss those with that out of the way let's tackle configuring authentication inside of our web API I'm going to go over to program.cs and we're going to add a few missing pieces to make authentication properly work in our application I'm going to add a few middlewares that aren't configured the first is going to be the authentication middleware and I'm going to add it by calling use authentication and I'm also going to add authorization middleware right afterwards and this is going to add the proper middleware to our HTTP request pipeline and now we need to add a few services to enable authentication to do that we're going to access the Builder Services here and we're going to call add authentication on it this method accepts a default authentication scheme and we're going to use the JWT Bearer default class and specify the authentication scheme from there now I'm going to chain a call to the add JWT Bearer method which allows us to configure the Json web token better options and this is the typical example for how people configure the Json web token options they usually access the token validation parameters here and provide a new instance and just set the properties here for example we can set the validate issuer to true and the valid issuer to some string value and then we can do the same for the audience and the assigning credentials but I want to show you an alternative approach to configuring the Json web token options I'm going to add a new folder inside of our web API which I'm going to call options setup and I'm going to add a few classes here that are going to handle configuring our options that we have in the application so the first one that I want to tackle is the JWT options that we just created so I'm going to add a new class which I will call JWT options setup what I want to do with this class is inherit from the iconfigure options interface and specify the JWT options as the generic argument I'm going to implement this interface and it has just the configure method allowing me to set the properties on the JWT options instance so how am I going to do that I'm going to inject a new instance here of the eye configuration interface and we're going to use the eye configuration to configure our JWT options what we can do is use the configuration to get the configuration section and I'm going to specify some key here in just a moment and once we have the configuration section we can call bind and specify our options and this is going to bind the values from this configuration section into the properties of our options class for the name of the section I'm just going to add JWT here a better approach will probably be to just create a constant here so let's go ahead and do that I'm going to call it section name and I'm going to give it a value of JWT which we had below and just replace the hard-coded JWT string with the section name so I added the iconfigure options implementation for the JWT options class to tell the framework to actually use this we need to go here all that we need to do here is say Builder services and call the configure options method and specify the JWT options setup class as the configure options argument what this is going to do is when somebody injects an i options of JWT options which is our options class it's going to trigger the configure method on this JWT option setup class and that's going to configure our options instance and we're going to populate it with the proper values I'm going to use the same approach to configure the Json web token better options so let's go ahead and add another class here it's going to be the JWT Bearer options setup let's make it inherit from iconfigure options and the argument is going to be the JWT Bearer options let's go ahead and add the configure method and because we have support for dependency injection here I'm going to inject an instance of JWT options which contains our configuration values and we're going to use that to configure the JWT Bearer options so if you recall to inject this we need to use the i options interface and access the value property on the i options and now we have the proper value set for the JWT options instance and now what I can do is access the options here the token validation parameters and set the values that I need to configure authentication so let's provide a new instance here and we're going to set a few properties let's say we want to set the validated shirt to True validate audience also to True validate lifetime to True validate issuer signing key to true and now I want to provide a few values using our options class so I'm going to say that the valid issuer is going to come from our JWT options issue the valid audience is going to come from JWT options audience and the last value that I'm going to set is the issue signing key we need to create a new instance of symmetric security key and provide an array of bytes we're going to use encoding utf-8 get byte and I'm going to specify JWT options secret key as the value and this takes care of configuring our token validation parameters on the JWT better options we also need to tell the framework to use this setup class so if I go back to program.cs I'm just going to copy over this class and instead of JWT option setup it's going to be JWT Bearer options setup so this takes care of wiring up everything that's required for Json web token authentication to work inside of our API and now all that's left for us is to actually use this so how are we going to use it I'll go over to the members controller class and let's for example say that I want to authenticate the access to the get member by ID method all we need to do is just add the authorized attribute on this method and that's going to require anyone that is hitting this API endpoint to be authenticated using a Json web token so let's first go through the flow of creating our Json web token and then we're going to see if authentication actually works on the get member by ID endpoint I'll go over to the login command Handler and I'll place a breakpoint at the start of the handle method and now we can start the application and move over to postman where we are going to be sending our API request I already prepared a login request that we are just going to send to our API all that we have in the request body is the email of Our member so I'm going to send the request to our API and we hit the breakpoint inside of the login command Handler so we create a new email instance we fetch the member from the repository using this email and as you can see the member is not null I'm going to step into the Json web token provider so that we can see what's going on inside so we first create our array of claims it's going to contain two claims one for the sub and another for the email of Our member then we are going to create a new instance of the signing credentials after we have that we can create our Json web token and we can serialize that Json web token into a string and return that value from our Json webtocin provider as you can see we get our Json web token back and we are going to return this from our API so I'm going to press continue and as you can see in Postman I get a Json web tokenstring as a response let's copy this string and head over to jwt.io to check out what we have inside so I'm on the jwt.io website which you can use to decode your Json web token and see if what you got is a valid Json web token so I'm going to paste in the response from our API and we're going to examine it you can see that the algorithm that was used was indeed hmugsha 250 6 just as we specified inside of the Json web token provider we properly added the subject claim which matches the ID of Our member here is the email claim which matches the email of Our member also the expiration is one hour from now and the issue and the audience are both properly set based on the values that were provided in our JWT options instance so now I'm going to use this Json web token to authenticate our request to the get member by ID endpoint first I'm going to send an unauthenticated request where I won't specify the Json web token and let's see what happens and you can see that we get a 401 unauthorized response because we added the authorized attribute on the endpoint and that requires us to provide a Json web token to authenticate with our API so now I'm going to add authorization here in Postman I'm going to specify Bearer token as a type and I'm going to specify the Json web token that I got as a response from the login method so if I send the API request again with the Json web token present we are going to be able to authenticate with our API and should see our response back and indeed we do get a response pack which contains the ID and the email of Our member I hope that you enjoyed this video about implementing Json web token authentication with our web API in the future videos I'm going to tackle implementing authorization for our API using permissions so be on the lookout for that take a look at these two videos that I prepared for you and until next time stay awesome
Info
Channel: Milan Jovanović
Views: 55,311
Rating: undefined out of 5
Keywords: token authentication, token authentication explained, token authentication c#, token authentication vs jwt, token authentication postman, jwt, jwt token, jwt authentication, opaque token, jwt.io, asp.net core authentication, asp.net core 7 authentication, asp.net core jwt, asp.net core token authentication, json web token, json web token authentication, jwt token authentication
Id: 4cFhYUK8wnc
Channel Id: undefined
Length: 25min 21sec (1521 seconds)
Published: Tue Nov 29 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.