ASP.NET Core Web API Authentication and Authorization with JWT (Json Web Token)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
today i'll show you how to add authentication and authorization in your asp.net core web application with json web token so let's get coding okay open up a visual studio create a new project this will be an asp.net core web application select that if you can't find it search search it in the search bar right there click next give it a name give it a location and then click next again and then here i'm going to choose.net core 3.1 no authentication type and click create so here we are a few things that we need to do is to install three uh packages so if you open up solution explorer uh then right click on the dependencies and manage new get packages the first one is microsoft asp.net core authentication dot jwt better one important thing to note is that if you have created a dot net core 3.1 application then make sure you choose 3.1.24 jwt bearer because anything above that will not be compatible with the sp net core with dot-net core 3.1 so just make sure that you choose that if you're working with net 5 then higher versions of the jwt barrier package will work but in this case 3.1 that's um that's all you need to do okay the next package that we need to install is um dot tokens so identity model dot tokens this is it and you can choose this one it's fine for the rest of the packages to install the data stable versions and then last but not least is identity models tokens dot jwt okay let's finish installing so i'm gonna paste in the description section um all the all the packages so that you can go ahead and copy and paste them as you wish okay so installing the latest one that's finished okay following the next step is to uh setup app settings.json so if we close everything and then we go to the root of our project and then open up settings app settings.json i've got a snippet that i've already created i'm just gonna paste that in so this is a new section jwt that i have created that's got a key that's randomly generated link in the description with a website that's just uh generated a random string of of characters uh and numbers uh and then we've got an issuer and an audience and uh we need two addresses here which in our case are going to be um similar so if we right click on the on the web project on the web app and then go to properties and then navigate to the debug tab scroll down and you will see that right next to so in the web server setting in the settings section we've got enable ssl and then we've got an address here uh that url is what we need to paste in here so both the issuer and the audience so um the server that's gonna issue the jwt token and the audience uh the one that's that's gonna use it are gonna have the same address so that's uh it with uh setting up app settings.json following we need to set up startup.cs file so if we open up startup.cs and scroll down to configure services so we've got that method right here it should be on line 24. okay so inside the configure services inside startup.cs we need to add the configuration part for the jwt bearer so that's the first thing so we do services.add authentication and then in here we define jwt we say um we pass in the authentication scheme as jwt better defaults and that's not it by the way if you haven't got this already um imported in your startup.cs just press ctrl dot and then hit enter and then one of the packages uh should just import automatically inside the insert inside startup.cs then following we don't put a semicolon at the end we do a dot jwt bearer and then we define an options object that we need to define so we need in order to in order for this to work properly we need to set this up with our custom properties we've got our custom options we need to define the options.tokenvalidation parameters um and obviously we need to initialize that with the tokenvalidationparameters object so uh we need to uh tell the api that every time you receive a request with where you've got the authorized tag in it then validate the issuer that we have defined earlier inside appsettings.json obviously validate the audience as well validate lifetime and then validate issuer sign-in key so we need to validate that as well if we are going to provide a signing key it could be optional but just to make it more secure to add an extra layer of security we are going to define a private key then the valid issuer that we define is um from the configuration so from appsettings.json and we're accessing it using jwt colon issuer that's the path to it right so jt is the section and then issuer is the actual value so this is what we're going to import in there and this um this is better than just pasting this string in here because this is an app secret so um when you get to deploy this you'll obviously be able to replace the the value in app settings.json with um the issuer on the server and the audience address on the server and so on um so that following we define the uh the valid audience this is going to be that the token will be validated against uh in here as well and then the issuer signing key we are doing a symmetric key so we're creating a symmetric security key um and obviously we're encoding that jwt key um so that we can create the symmetric security key so that's how we um that's how we uh define the options of the token validation parameters following we need to add a couple of lines again in this configure services method that's going to be services dot add mvc and services dot add controllers and that is it with configure services then in the next part what we need to do is add a couple of lines a couple of configurations inside the startup.cs configure method so this is different to configure services in here we we are aiming for the configure method and in here we need to add authentication and uh map the controllers because if we don't do that uh when we get to create the api controllers that we're gonna use throughout the application we won't be able to access them so very important uh to do this step um so the first thing that we want to do in here is app dot use authentication yeah so that we can uh we can allow for the api endpoints to authenticate the users and then last but not least endpoints dot map controllers map controllers that's it with setting up startup.cs right now let's add a models folder to hold our three models one will be the user model uh that's gonna hold all the data about a user so this is gonna be some sort of like an asp.net user uh entity in the ef core but obviously we're not going to work within the ef core database with the sql server database uh therefore we're just going to simulate the the presence of it so user model user login that's going to have only username and password and the user constants that's gonna be some sort of like a database holder for us okay so um let's right click on the project add a new folder models and then in here like i said three classes the first one user model user model and this is gonna be a public class and i'm pasting in the the properties right now so we've got a username a password an email address a security role a surname and a given name so pretty simple then the second one will be user login and obviously you can pass in the api the username and the password but it's uh it's better to do it like this it's best practice you'll see what i mean so user login and this is going to have just a couple of strings user name and password that's it and then lastly the user constants so right click add new class and let's call this user constants and this just holds a list of two users that i have already created for us um one is called json admin and it's an administrator it's got a role of an administrator and then one is called the other one is called a list seller and it's got a security role of seller so this is it with this step with setting up our models that we're going to use throughout this application okay following uh here is the meaty part we'll add the api controller so the first api controller that we want to add is the login controller which is the one that will authenticate the user as well as will uh generate the token for forty user based on the user details that are found in the database based on the username and password so let us create a controllers folder so controllers then in here let's create a an api controller so right click add new item and then type in api if you don't already see it and let's call this login controller so this is an api controller that's inheriting from controller base okay the first thing that we want to do obviously is to initialize the uh to inject the i configuration so that we can have access to all the details from appsettings.json so i'm just going to find a private eye configuration property at the top of the field at the top of this class that's going to be called config and then if you type in ctor and double tab um then we can actually inject this so i'm just gonna copy and paste this here without the underscore um so that i can do config dot config equals to uh the config object that's passed in so this is how we inject things um then the very first method is obviously login so this is going to allow anonymous this is an annotation that will um prevent the authorization process the authentication process to happen um at the point of calling this method because this is the very first thing that the user is ever gonna call in this application the login method obviously if they're not already logged in okay so this is a http post and then this is a public returns and i action result and it's called log login okay and this is going to take from body oops so from body um a user login object and let's import that really quick let's call this user login so again this user login only has username and password we could have easily just pass in those two strings in the in this in the parameter section however it's best practice to just wrap it in a dto in a data transfer object um so in here obviously we're not going to have all these methods yet but we're going to create them but the very first thing to do is to grab the all the user details based on the username and password so we do var user and then we call a method called authenticate but wait there is no authenticate method we're going to create that in a bit so let's pass in user login and then if user is not null yeah then let's generate the tokens of our token equal to generate and then we pass in the user uh this user will contain all the user details uh this is going to uh be uh created from um user from from the user model class okay uh and then obviously we found it here so let's just return this uh token in an okay object um in an okay response yeah but then if we uh couldn't uh if we could not find the user then let's return not found not not found with a message user not found so that way we know that the user name or user password are wrong okay then let's generate these two methods and this is the authenticate and generate and to do that you just uh control dot on them and obviously the return types are a bit messed up because uh this generate should just return a string and should take in a user model user model and then this authenticate should return a user model and uh yeah it takes in the user login so we're good to go now so let's first work on the authenticate method so the first thing that we do is obviously we return the current user based on the user login information so that when the username obviously i'm doing to lower because the username is case insensitive it's like the email address in the login form um so if we found the username that's matching the login username um that we have provided as part of this object that we're passing in but then if the password is the same as the password then return the return the entire object from the user constants dot users so this will be this class right here you could just easily call ef core to do this for you um so use ef core with sql server database but this is not the point of this tutorial okay so once we have that user obviously we don't know whether or not it's going to be found or not so we check in uh if the current user is not null then just return the current user with all the details that you found about it uh otherwise just return null so that's the authenticate method worth noting that this is not a proper authentication so you shouldn't do this in your application in your production application this is just for testing purposes to simulate the process of authenticating the user and basically validating username and password okay next thing is to configure the generate method that's gonna this is gonna generate the jwt token based on the user details that we grabbed from our so-called database the first thing to do is to uh grab the security key and define it as a symmetric security key and this is if you remember the same exact thing that we have done inside the startup class we're grabbing a randomly generated string of characters that's going to be um our public string uh then the second thing is to define the credentials object based on the security key so the signing credentials that's going to be um in included inside the jwt token the job token so here we're using sha 256 hmac sha-256 obviously as a as a you know security algorithm as a hashing algorithm and then we define a bunch of claims and claims are just a way to store uh data about the user or about the um the pro the process uh and what we're storing at the moment is a bunch of claim types and these are um already registered claim types that we haven't uh we haven't customized these are set in stone registered claim types and if you don't know what i mean i have already got a video where i'm talking about i'm explaining uh the different types of claims and the components of a jot token so if you haven't already seen that check out the description after this video or check out the end cards and you'll be able to see it um okay so we have a name identifier an email address that we're just grabbing the user's email address and then a given name surname and the security role and the security rule is important uh because we can actually use that to provide some level of access inside our apis okay so after we define our array of claims the next thing to do is to define the token object and what will it look like and in this case we're going to be doing a new jwt security token and the first part is going to be the issuer and it's important to pass the issuer and the audience because this is uh what the api will validate once it reaches once it receives a request with a jwg token so it will check has your issuer changed in the meantime from the one that you have defined in here or has the um has the audience changed from the one that you've defined in the in the startup class the next one is the list of claims obviously we've already talked about them and then when it expires then it's recommended for a secure jwt token to not last more than 15 minutes and then the signing credentials which we have um already created right here and that is it so as soon as we have created this jwt security token then we call jwt security token handler and then we call the write token and we pass in the token object so that's it this should return a string now uh so that is it with setting up our login controller if you save and let's quickly run the app and let's test what we've got so far to try to to attempt to authenticate our users and let's generate a a jot token so that we can get get a hold of it and use it later on in this video okay so the app has started and if we copy the url uh let's uh attempt to log in so uh to log in we do api slash api so localhost localhost colon and then the port that you have in your in your application url um and then slash api slash login and then in here to be able to log in let's um with the username and password let's go to the body tab then let's go to raw and then let's select jason so then in here let's log in with json admin and let's uh see if we can hit this um login breakpoint uh now so let me put a breakpoint right here and let's click send so this is a get method and it's gonna do a method not allowed let's select the post method because that's what we defined inside the api and it looks like we've hit the api so let's step into the authenticate method obviously compare the username and the password and the user is not going to be null so just return the current user with all the details that we have defined in the user constants class define that so yeah so get that user and then if it's not null obviously go in the generate method and generate me a job token so grab the security key this is what the object looks like and then define the credentials that we're going to um chuck into the jaw token define the the claims this is the username the email address given name surname and the security rule so then define the jwt security token and then write it so in essence generated so here we go this is this is the um a string the job token that we're gonna be using to be able to authent to be able to let the api um authenticate and recognize the fact that we are authenticated and validate our um our identity okay so if we continue if you can see in the in the body right here we have got the dwt token generated for us next what we will do we'll set up the user controller okay so back in the application let's stop the app uh close the login controller because we won't need it anymore for this tutorial and then add and then new item and then again new api controller and let's uh call this a user controller and we're gonna we're going to define a bunch of endpoints as part of this user controller um to be able to show uh whether or not we can hit those endpoints if we are authenticated um and if we're not what happens um so the first thing that i would like to do is uh let's add a public endpoint right here uh to say hi you're on public property and let's try to um you know to uh hit that just to make to make sure that we are actually able to hit methods inside this endpoint to alleviate the confusion so let's run the app and let's go back to postman let's try to hit this endpoint okay so the app has not started and if we copy the url go back in postman and then open up a new tab and then let's paste that in there so this is going to be api slash user slash public and this is going to be a get method so let's send it and let's see what we've got hi you're on public property so we are now able to hit endpoints inside that uh controller okay so back in our application let's add a helper function that will allow us to grab the user details based on the jwt token passed in so basically when we were in the login controller if you remember we have defined a bunch of claims basically these claims hold useful information about the user without us having to go back to the database to request details about the user so every time you make a request you send with the request that jwg token that holds all these useful details about the user that we can use inside our example user controller so the first thing uh let's define this as getcurrentuser and uh we're gonna grab the identity from httpcontext.user.identity as claims identity because this is what it is and if that is not null then grab the claims array of claims and this is basically just an innumerable of claims and then let's create a new user model um based on the claims that we have so if we uh we are looking through the um the user claims and we're grabbing based on type so if you remember we have defined in the user controller certain types and these are registered uh claim types and we are doing the same to be able to identify those types so if the type is name identifier then grab that grab that value and put in the username property of this object so as you can see we have stored the username in the name identifier and we're doing exactly the same thing with email address given name surname and the security role and then return null basically if if the identity is not found then return no so this is really useful because we're going to use this quite a bit in the following minutes okay following let's define an endpoint that will actually require us to be authenticated so we're not going to be able to access that endpoint unless we are authenticated and this is going to be again a http method so http get and then uh the route to this will be um say admins yeah because we're gonna use we're gonna actually um after this we are going to um add authorization so only if you are an administrator you can access this endpoint but for now you should only be authenticated so you should only have a valid uh token okay so this is a http guest get and then this is going to be a public eye action result and let's call this admins endpoint it won't make a difference again it won't make a difference your security role at this point so then in here let's grab the current user current user that's going to be get current user so this method right here and we don't need to pass anything in because this grabs the user claim so all the details from the http context so let's uh let's just return uh in an okay message if everything went okay let's say hi and then let's give the current user um [Music] given name and then let's say um u r n and um or um and then let's put in the um security rule right here so current user dot role yeah and then basically in here it will say something along the lines of hi json you are an administrator so let's save this let's run the app and let's see uh what we've got okay so we're back in postman the app has started and uh in here let's um target the admins uh endpoint and let's click send and uh what is going on so basically we are not authenticated and we are able to access that endpoint well that's because we haven't added uh the authorized authorized um notation right here so basically we need to add this authorized in order for the api to validate the stock and that's the whole deal so uh at this point if we have a valid jwt token generated and passed along with the request then we will be able to access this endpoint failing that we won't be able to so let's try that again okay so the app has started and let's try that again so you'll see it returns a 401 unauthorized and uh to be able to access that endpoint we need to be authenticated meaning that the jwt jwt token needs to be passed in along with the request so if we uh go back in here let's uh let's actually generate a brand new one it's not been more than 15 minutes but hey we want to make sure that that actually is a fresh newly generated token with the json administrator um okay so then in here we need to go to um instead of just sending this as it is we need to go to authorization and then from the type of authorization choose bearer token and then paste this new security key so yours is probably going to be empty like that and then paste that um a job token not security key job token uh so then let's try that again and as you can see um the api endpoint the api has authorized this um as we are successfully authenticated because we've passed in a valid fresh new token uh generated uh for us so that the current user is json admin with all the details and we purposely don't didn't grab the password as well and let's see what we've got so hi jason you are an administrator and obviously if we log in with elise which will be inside uh user constants so if we go and grab they've got the same password so elise seller yeah so if we log in and generate a jwt token with elise then replace this replace jason's token with elise's token then uh this breakpoint has already been hit hi elise you are a seller uh and seller well that doesn't really matter at this point um because we haven't made the distinction between the two different security roles uh but how do you make this distinction because this endpoint surely should only allow admins to be to be able to access it well basically what you do is in order to enforce um authorization between different security roles what you do is open and close the parentheses and then you put you define the roles property right here so this would be an administrator so at this point if we run the app at this point we shouldn't be able to access this endpoint with alici's generated token so let's give that a try and let's see how it works okay so the app has started let's go back to postman and uh let's try this again as it is with alicia's token and what you will see is not will not be a 401 um it will be a 403 forbidden so you are authenticated but you are not who you uh who you claim to be or better yet this particular endpoint is not for you you haven't got the right access or the right level of access which we have defined right here to be able to access that and let's stop the application and let's create one for elise uh as well so copy and paste this and this will be sellers yeah and then in here let's define the role as the seller and keep in mind this role we have defined this role right here this is the elise's role this is the seller and this is the administrator the jason's security role so basically we have said that the role should be of administrator right here and then for elise that it should be a seller make sure that the names match right here so let's call this seller seller's endpoint so then here let's change this um okay let's give this another run let's see how it works okay this is right now and uh let's try um so again the admins we're not going to be able to access the admins so um nothing changed in that endpoint however if we say here sellers so go ahead and access the seller's endpoint uh let's take a look at the response of high list you are a seller so 200 okay so it's been we have been able to authenticate successfully and we have been authorized uh so in here if we uh log in with um uh if we log back in with jason's credentials so let's generate a token for json and then let's paste in this token for the for json and let's try to access seller's endpoint with json's that's administrator credentials so as you can see we've got a four or 403 forbidden one last thing that i want to stress is how do you access how do you say define an endpoint that's that's going to allow only a certain types of security roles to um to be able to access it well that's very simple let's create another one and let's say in this one in the roles so let's say um i don't know admins and sellers yeah so in here this is going to be the the route to it and then in here instead of just saying administrator let's put a comma and let's say a seller as well so only this particular role so should you have in your application more security rules such as buyer and whatever any type of other security rule this endpoint will only allow administrators and sellers to access it right so that's it for today's tutorial if you want to get into even more details about what a jwt token is how it works and why it's important check out this video on screen right now until next time stay safe
Info
Channel: Code with Julian
Views: 4,106
Rating: undefined out of 5
Keywords: asp.net core web api authentication and authorization, jwt json web token asp.net core web api authentication, asp.net core web api authentication jwt, asp.net core web api authentication, jwt, json web token, authentication, authorization, web api authentication, token based authentication, jwt (json web token) asp.net core web api authentication, authentication with bearer token
Id: kM1fPt1BcLc
Channel Id: undefined
Length: 32min 46sec (1966 seconds)
Published: Mon Nov 15 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.