.NET 6 Web API Authentication | Minimal API & Swagger (CRUD)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
today we'll add jot authentication authorization and swagger support to a.net 6 minimal api so let's get coding okay so the very first thing that we want to do is open up visual studio 2022 create a new project uh that's going to be on asp.net core empty if you can't find it search it in the in this search bar um and then click next give your application a name mine is going to be minimal jwt and a location and click next and then in the framework choose dotnet 6 and leave configure for https as it is and then click create okay as we're here let's close out of this one and double click on the minimal jwt project so the cs proj file and let's quickly remove the nullable attributes so that we can get rid of all the errors uh that all the wordings that are going to appear in this project um and then that's it with this step of following we need to add a data transfer we need to add a few data transfer objects as our application will be a movie management application uh we need to create a few models or data transfer objects in this case uh that are going to hold the data that we're going to basically transfer from the client to the server and to our well virtual database uh and those are going to be the user model that's going to hold all the user details such as first name last name user security role username and password and the email as well and we're going to create a user login which is just going to hold the username and the password or the email and the password and then last but not least the movie model which is going to hold the title the description um and the rating of the movie so let's go ahead and create a new folder right here and call this models and then the first one that we're going to create so create new class and this is going to be the user login so this is simple again a username as a string and then a password as a string as well the next one on our list is the user model so right click add new class and then call this user just user okay so very simple username as a string email address password given name surname and the security role so that's pretty much it it's not too large uh it's a pretty decent dto and then last but not least the movie model so here we are we have an id as a as an integer a title is a string a description as a string as well and then last but not least the rating is double so that's pretty much it with this step next up on our list is to add a few data repositories and because we're not going to work for the purposes of this tutorial with any sort of database we're going to simulate that database in a couple of static classes one is to hold a couple of users with different security roles and one is to hold a simple list of movies so let's go ahead and create those two uh repositories so create a new folder inside your project and call that repositories and then inside that add a new class again this is a simple class and then call this uh user repository obviously if you have a an efcor a sql server database or any sort of database this step is not mandatory it's optional so you can just query your database instead of doing this okay so like i said this is a simple class and here we're just creating a simple list of users and we're newing up with a couple of users so one is look admin and it's got an email address a first name a surname and then a password the password is as you can see is the same for both users and then we've got a standard user so the first one is look is an administrator and then lydia is a standard user so this is really important when we're going to implement authorization inside our minimal api so let's uh control dot on this user and let's import this namespace so we're all good to go okay following is the movie repository so again right click add a new uh class and then this is going to be called movie repository and hit enter so obviously i've already prepped the static list of movies with five titles that we're going to work with so first one being eternals dune the harder they fall red notice and no time to die so basically i just took this off on the imdb page and then they've got a title a description and a rating and an id as well so let's import the movie namespace and yeah that is it with this step okay so following is creating the services so we're going to have two services one is the user service and one is the movie service new user service is just going to hold the simple get method uh that's going to get our current user so passing in the user login as uh as a parameter uh that's going to hold uh the the two properties that we've just uh created the username and the password and uh it's going to return back a user model if the user is found by um username and password so let's close everything down let's collapse everything and right click on your project and add a new folder and call that okay so right click on the services folder and add a new item because this is going to be first an interface so we'll do an interface of the service and an implementation for every single method so i user service okay so this is only going to hold um a get method so let's import the models and that is it so let's do the let's create the implementation class so add a new class and call this user service and let's implement this method okay let's first inherit from our interface and let's define uh the method the implementation method so this is going to return a user so all the user details and it's going to take in the user login so the email and the password and obviously it's going to go ahead and try to find first or default uh by um by username um obviously if it's if it's equal to the login username that's passed in as well as the password so if both of them match then return the user so let's control dot on this um on this red lines and um let's import the specific name spaces okay so very simple again if you've got authentication already implemented in your application it's obviously use the framework exposed methods that you've got at hand obviously don't do this but this is just an example so we can retrieve the information from the user repository from the two from the two users that we've created for us this is just for simplicity of this tutorial it's not best practice to store your users in like in like a static class rather in a database using identity server and whatnot um okay following on our list is the movie service so again this is going to have an interface and an implementation class so let's go ahead and create them really quick if this tutorial is helpful to you hit that like button so that this video can spread to as many people as possible i would really appreciate that right click on the services add new item interface this is going to be called hi movie service really quick uh the create method the get method the list update last but not least the delete so again this is uh to follow the um crude pattern uh that is create read update and delete let's import the namespaces real quick uh and uh yes we're good to go let's create the implementation class right click add new class this is going to be called movie service okay so let's first inherit from our newly created interface and let's uh implement the methods so the first one on our list is the create method that's going to return um a movie object and obviously it's going to take in a movie parameter so let's define the id because obviously on the client side we're not we want to know the id so we go into movie repository get a count and then increment that by one so if we have in our case we have five movies uh the account will be five the next one uh the next movie that we're going to create and the pen to our list is going to have a five plus one id so as an id of six uh and so on so let's uh after we've defined the id let's add that um movie uh to the to our list and uh return the movie then following is the get method so that's just taking in an id and returns a movie object so in this case uh we go in the movie repository and we select first our default pi id nothing new here and if we don't find it return no and if we find it we just return the movie so next one is to return the list of movies and this is probably the simplest one that we're going to create so uh this is uh just returning the entire list of movies from our repository as it is so return movies as i said and then update this is taking in a movie object so the new version of the movie that we want to update and then the first thing that we do is we get a snapshot of the old movie as it is right now by id by the idea of the new movie that we want to um update so if we didn't find that then return no otherwise update the title the description and obviously the rating and then that is pretty much it this is how we uh we update those uh properties and then we return the movie uh object last but not least in our um a movie service is the delete and that takes in an id and finds the old movie by id and then as soon as it's uh if it's not found obviously return uh false because this returns a ball true if the operation has been successful and false uh if otherwise so if the old movie is not found then return false otherwise just remove the old movie from the from the repository and then return true uh one thing that i would like to do is to import this couple of namespaces the repositories and the the models namespace so we are good to go with this movie service implementation class okay so in order to generate and use gwt or jaw authentication in our application we need to install three uh very important dependencies okay so the first package that we're going to install is called microsoft asp.net core authentication gwt bearer so let's install the latest stable version um obviously except um accept all the licenses um and then is microsoft identity model tokens okay install this one too okay and then last but not least is the identity models system identity model token.jwt okay so let's install this one to the latest stable version okay this is it with installing the dependencies necessary to generate and authenticate in our minimal api with the job token okay i just wanted to let you know that i post weekly tutorials just like this one about.net encoding in general so if you are interested subscribe and join our club okay so following let's set up the um endpoints for our minimum api inside program.cs so if you expand the project and then double click on program.cs so here it is very simple what we've got um the builder uh that's defined as webapplication.createbuilder and then we've got builder.build obviously to create the app and then we map the get method um that sits at the root of our application and it should return just a simple string with message 200 that says hello world um and then we do map.app.run so what i would like to do next is to set up the uh crude api methods to expose the functions uh that we have created as part of the movie service so we've got if i do control m control o i collapse to the definitions of these functions so i've got create get list update and delete so um in here we will be creating endpoints like this to expose those methods but before we do that it is really important to register our services so that we can use them inside of our meaningful minimal api through dependency injection this allows us to use the services without having to instantiate them or new them up every time we want to use them in the method we just use them through dependency injection so we um initialize them once per application life cycle and we have the same state throughout the application life cycle so this is how we do it uh we first need to add endpoints api explorer and then we add singleton so this is how we do it builder.services.uh add singleton and this takes in two um engineering types the first one being the interface in our case is the imovie service and the second one is the implementation of that interface so let's import the services namespace so we can get rid of the errors and then we register the iuser service as well so now that we have these two registered we can go ahead and create the actual endpoints because we'll need to reference these ones as the parameters for our endpoints okay so the first method in our list is the create method so this allows us to create a movie inside our static list of movies and this is pretty simple we map post so we do a map post because this will be a post method obviously and we've defined route to slash create this takes in a movie object in the body as uh in the json format so this is how you would do it and um also this uh takes in a movie service because we'll be using the service to obviously to call the create method uh inside the movie service right here um so that is the map create let's actually import so if you do control that you'll be able to add the minimal gwt models namespace so don't worry the create method doesn't exist yet we'll be creating that as soon as we map all the api endpoints the following method is the get method and this is pretty simple it's a map get obviously takes in an idea of type integer and and the movie service again and calls a local function called get and passes in those two arguments the following method is the list method and this is pretty simple slash list this is still a map yet and it only takes in the movie service so you don't need to worry about it we won't pass it through the request uh it will be injected automatically by uh.net core and calls the list function that we haven't yet created and then we've got the update uh which takes the new version of the movie so we're going to update an already existing uh movie record that we've got and we're gonna pass in the new version of the movie be that with a changed title or change description or or an updated rating and then again the movie service that's part of every single uh endpoint that we've created so far and calls in the local function a local function update that passes in those two arguments last but not least is the delete method and this is slash delete and this is a map delete oh one thing that i forgot to mention is that the update is mapped to a put method so this is how we map a put http method um so yeah getting back to the delete method this is a map delete and takes in an id because uh we're just passing in the idea of the movie that we want to delete and we just go ahead and delete it so now let's create the actual functions that we have defined right here but we haven't yet created the first method is the create method and obviously again this takes in a movie in the body and the movie service so this is how we do it we define the result as a service dot create so we call the service dot create method which is right here and obviously here we've already discussed what this method does um and just as soon as we've got the result we just return it in an okay result message one thing to note right here is that previously uh we would just do okay and then we wrap the um the result in an okay message or um or not found or uh what not but whereas in here what we do we do results dot okay because this function returns an i result um object so this is what the minimal api returns an eye result uh then following we've got the get method this takes in an id and the and the service and uh this just simply gets the id and the if the um if the movie that's uh returned by id is no in other words if the movie is not found then return not found and then if it's found then obviously return the movie following the list method by the way all these functions return an eye result uh it doesn't matter the type of object that we are going to be returning it returns on our result because the um the result of the function that we're creating we're wrapping that in my result uh so just keep that in mind okay so the list method again returns an eye result takes in the service this is the simplest one of all just takes a snapshot of all the items in the list and returns them returns them back to the api uh then we've got the update so um we just defined the updated movie as service dot update because we encapsulate all that updating logic inside this um update function right here yeah um so then in here the updated movie if it's no in other words if it's not found so right here we've got the old movie that we're returning by id and if that old movie is not found then return null so here we're checking if it's no then return results dot not found with a message of movies not found otherwise return the updated movie last but not least is the delete takes in an id of course and just calls the service method service dot delete and passes in the id and if the result is false uh then return a bad request otherwise return true in an okay message so this is how we where we are implementing these uh methods as you can see one important thing to uh to note is the fact that we are using um a dependency injection right here so here is how we register the services and then here is how we make use of them uh don't worry i'll show you how to use to call this method to consume these api endpoints and you'll see that the app will just make the difference between the body of the the body of the request and what's supposed to be injected by by the by.net core or the query parameters so it will uh take care of that by itself uh you'll see what i mean in a moment okay so in order to be able to test these we've got a few options available we either test all of these endpoints using postman like we did previously or we installed uh swagger or swashbuckle so this is how we do it let's do the second one we right click on the packages so that's under the project dependencies expand the dependencies and right click on the packages and click manage new get packages and in here let's browse for swashbuckle.asp.net core and install the latest stable version but at the time of recording this tutorial it's uh seeing a 6.2.0.3 uh 6.2.3 okay so as soon as that is installed let's save let's expand and make sure that we've actually got this right here with all all its dependencies okay then after the package is installed we come back to program.cs and we do builder dot so right under builder we do builder.services.addswegergen uh so this is to uh enable uh swagger in our application then uh following right after the app um right after the app is defined oops uh we can where it says builder.build so in our case on line 12 we do app dot use swagger so last but not least right at the end of the uh function right at the end of the file sorry uh we do right before we do app.run we do app.use swagger ui so this is how we set up um a swagger in our application let's run it and let's see what we've got so far okay so here is our application in browser so if we go in the url and we put slash swagger um let's see all our endpoints so there we go we've got all of our endpoints right here and we've got the create the get the list the the update and the delete let's run the um the list method and let's see what what it returns back so as you can see we've got a response body and we've got all of our movies nicely returned let me zoom in a bit so you can um and so so this is a readable from your end and uh let's see these are all the titles um let's actually run the get method with uh with an id of two so there you go we've got um we've got the movie title right here um let's do um a delete uh and that's it um cool this returned true and then let's let's uh run the list again and let's see if um two has been deleted so as you can see we've got id one and then movie with the id of three so obviously uh number two has been skipped so following what we wanna do now is uh add uh jot authentication so jwg bear authentication into our swagger application because um as you can as you could see previously we can uh go ahead we're not authenticated and we could go ahead and and delete every single um every single movie that we've got in the list and um if you can imagine this as being like a real application where you expose like real movies from a real database you don't want to allow anyone to uh there or everyone to come here and and play around with the data so they cannot they can obviously see a list of movies uh so if you go on imdb you can see the list of movies and maybe like get more details about the movie but obviously not everyone can go ahead and update or delete movies because that would be chaos so in order to do that in order to prevent certain users or not authenticated users to access these specific endpoints that expose our data we will be implementing job authentication so that's what we'll do right now okay so the first thing that i would like to do is to actually define a new section in appsettings.json that file can be found in the root of your project uh double click on it and open it up so i'll add a new section right here called jwt with a bunch of properties so this is the key that we'll be using to encrypt our jot token uh and i've generated this with like an online generator tool um it's just a random string of um letters and numbers uh then the next one is the issuer and the audience and what this is is the um the address for um our issuer in the audience which in our case is is just the same um so we'll be using that to validate the request that we'll be sending through our our api so that is pretty much all i'm doing if you're wondering how i got this it's just the url of our application which is which is right here so localhost this will obviously um as soon as you deploy this on a particular server this will uh will change in your pipeline uh uh settings with your release um you will uh you will change this um values right here um or potentially the issuer and the audience only uh but for the purposes of this tutorial this uh this does the trick and locally this is what we need to do so as soon as you've done that we can close out of that okay so getting back to program.cs the first thing that we want to do is do builder.services.ad authentication and we do this below the below where we create the builder obviously um so here is where we define all all of our services um i've put this below at swagger gen so we do builder services add authentication and then we define jwt berrydefaults.authentication scheme um so let's import namespaces and the the namespaces necessary for defining jwt authentication inside our application and they are right here we do authentication dot pair and then identity model.tokens that uh we'll we'll need to um you know work around with the with jwc token last but not least the system.txt to be able to encode the actual key okay so let's define some options to this adjust bearer function right here so uh this is how we do options and then we define the delegate which is option.token validation parameters and we defined that as a new token validation parameters object and inside of that we've got a few properties that we need to define the first one is to validate the actor and the audience then we need to validate lifetime and validate issuer signing key so all of these need to be set to um to true because we need to validate the signing key um so that we know it's not being tampered with so that the message is actually secure is coming from a secured um from a trusted source and then we need to validate each word and here is where the issuer is grabbed from it's it's it's returned from the app settings.json from the issuer value that we have we have defined uh right there and then we validate the audience in our case both of these are the same but this is good because if you ever want to deploy this into production you actually redefine the issuer and the audience based on where your uh issue and audience are deployed yeah and then we define the issuer signing key which is a symmetric security key and we grab the jot token key from the app settings.json so you remember that random string of letters and numbers that were i've generated on a website on the random website on the internet uh and we grab that we encode it and then we create a symmetric security key with it and then we do services dot uh authorization following right after the app is defined i've put this under app.use swagger we do app.use authorization and app.use authentication we use authorization and use authentication we'll be using that to um to add authentication and authorization to our endpoints obviously so let's do that right now okay so now that we have um defined a way for the api to validate uh each and every api request based on the jot token we now need to allow the users to actually log in and have that job token generated because the process is like this you log into a system you've got a token generated for you that token is uh returned back to the client uh and it's stored inside the browser under the form of a cookie and then every time you make a subsequent subsequent request to the api then that joe token is sent along with the request so now we need to create an a login method uh that will generate that token for us so we come down here and we do a map post and um i've put that as the second method under the hello world it really doesn't matter where you put it as long as it's after the app has been defined and after you do um app.run before you do app.run so right along with the rest of the api methods that we've created and that's got a root of login slash login and it's got a map post and it takes in a user login again this user login is just the username and the password and then the user service that's injected and it calls a login method that we've not yet created but we're going to create right now so let's go down here this method returns an i result and it takes in again the user as um username and password and the service that's injected so if the um if the username if both the username and the passwords um are not new then we're free to go ahead and authenticate the user so we grab the login user from the service doing the service.get and passing in the user credentials uh so again this all this method does is just it goes in our list of users and grabs the first or default by username and the password where they match where the username and password match um so if the logged in user is not null um well if the if the user is not found then return not found so if the locked in user is null return not found otherwise go ahead and do this so let's create some claims right here so claims are just pieces of information about the user such as the username the email the first name last name and also the security rules so these are bits of information about a user that we can encode we can append to the jot token so that they can be easily accessed inside the api so the first one is the name identifier so these are predefined registered claims if you haven't seen my uh jot jwt authentication basics then make sure to take a look at that after this video so basically we are defining the username the email address as the claim types dot email uh the given name uh the surname and the and the security role so um basically you need to add these two usings right here the identi model tokens.jwt and security claims um with these two ones you'll be able to do everything that we've done so far then the next thing is to actually generate the token so we're defining the token as new jwt security token the first part is the issuer so you'll see that this is pretty similar to the part where we've actually uh we've actually done this um and um the first part is the issuer and we're grabbing the address of the issuer from the configuration from appsettings.json then we've got the audience then we're defining the claims that were all we've already declared right here at the top so we're just passing that away through then we say when it expires i've put here 60 days because help we don't want this to expire yet but in an application you want this to be like 15 minutes so you want this to expire in in no more than like 50 minutes um then not before of course utc now and then we define the signing credentials and again this signing credentials will take in the a new object a new instance of the secure symmetric security key that's just grabbing the um the configuration key from appsettings.json and everything inside here and again the um the uh signing credentials one thing that i've got to mention is actually finding the hashing algorithm in this case is sha256 and then we define the token string by doing jwt security token handler dot write token and we're passing in the token with all the properties that we've defined right here so as soon as we've we've got the token string then we can return that in an okay result message so that's how we expose the login method um and we allow users to actually um to actually log in and have a token generated for them one thing that i would like to mention that's really important is the fact that this is not actually proper authentication so obviously um this is just uh as an example uh to be able to leave this tutorial as condensed as possible this is not focused on authenticated um the user that exists in the actual database so this simulates the presence of an of a proper authentication process this is just to allow us to uh generate this particular this particular token you would obviously want to replace this with like 20 identity model or something similar um where you've got a proper authentication process in place but for the purposes of this tutorial uh this would do it okay so let's take a step back for a second we've got two types of users we've got an administrator and we've got the standard user so what we'll do we'll restrict some of the api methods so that only administrators can access it and some of them which in this case will be the get will restrict it so that only the standard user can access it in our application the login method will allow anonymous so in this case we'll we won't put any sort of authentication and authorization on it because um any user will need to access this method without being authenticated so the first thing we do is inside the map post inside the create method uh we um add this authorize attribute so inside this create method we do authorize um we add this attribute inside of here so you could have went away with just doing authorized but in our case we want to um actually define the authentication scheme as being jwt by default authentication scheme and this method will only allow administrators uh to uh to access it so in essence if you are not authenticated it should return a 401 saying you're not authenticated however if you are authenticated but you are not an administrator or you are a standard user yeah then you will say for a three it's forbidden so you are authenticated okay fine but you are not um you're not able to access this specific endpoint so following let's add a similar thing to the um to the get method and we've we've defined again the authentication scheme as job barrier defaults and the roles we've defined at the administrator and the standard role so um again you could have went away with just defining the uh authorized like this because um we've only got two security rules so we're seeing um allow only these security roles uh to access this endpoint following the list method will remain unchanged so let's say we can allow everyone regardless of whether they're authenticated or not um so we won't put anything in there but for the update let's actually allow all the administrators to update uh same for the delete so that's the same sort of logic as um for the update and for the create so this is how this is how we implement authentication and authorization in the minimal api let's actually run the application let's see uh let's see what we've got so far okay if we uh head over to swagger uh then we if we scroll down we have the login method so let's try this out the request body should be let's actually just copy paste so we can make sure that we uh we don't make any typos and uh the password should be this and um let's execute this and let's see what we've got okay so this is the response body with the token that's been generated for us um and let's look at some other method that's simple to um to test and let's try to do let's try to execute this and let's see what we've got and there we go we've got a response status of a forum one that basically means you are not authorized to access this but uh here comes a question how do you actually test um api endpoints with swagger because we actually have a token that's been generated for us based on our username and password so we're successfully authenticated we've got a token generated for us but how do we actually test these endpoints if we're not able to um to get through the authentication wall um well that's what we'll be doing now back in our application where you see builder.services.adswagergen inside these parentheses what we'll do we'll define some options so here is how we'll configure a job bearer for swagger so we'll do options.add security definition and inside that method we'll define um a few a few properties so this is a bit a bit convoluted but bear with me because this is how we actually uh configure uh jwt bear for swagger this is how to do it in um in dot net in dot net six so we do open api security scheme and inside here we define the scheme as bear the bare format as jwt because this is jaw token and we need to define that inside the header and the name should be authorization with a description of saying uh bear authentication uh with jwt talking it's up to you how you put the name and the description though then we need to define the type as security scheme type dot http and um following that we need to define um the options.add security requirements so inside those parentheses we do new open api security requirement and obviously feel free at any point to pause and copy and paste this but also i'll have this entire project uh linked up on github for completely for free so make sure that uh you go ahead and you clone the repo and you can contrast and compare with your progress and with what you've got so don't worry if i'm going too fast go ahead and copy the code from from github so we do new open security scheme and then inside here we define the references the reference as new open api reference with an idf pair a type of security scheme then last but not least here as the second part of this we define the a new list of strings so let's actually um add all the needed references uh and i'm assuming that is pretty much it so yes like i said this is a bit convoluted but this is how you actually enable uh better authentication in in swagger so let's run this app again if you haven't already done if you haven't already typed everything out just make sure that you pause the video and you uh you copy everything that's uh that's right here okay so inside our application let's do slash swagger and uh here you can see an authorized button right here um with a title of bearer and the bearer authentication description of their authentication with john togan we haven't got a token yet defined but what we can do we can go ahead and have one defined for us so again let's go to the user repository let's grab luke's admin uh let's actually try this out so the username being look admin and the password being this one so we have a token generated for us and let's copy that without the double quotes and let's go up to authorize and let's paste that in there and click authorize and close out of this one so uh let's try the delete again let's see what we've got so far we've put an id of 2 and there you go we've got a response body of true so let's grab a list because this is not doesn't require authentication and as you can see id number two doesn't exist so we are authenticated okay one other thing that i would like to try is actually access the same delete endpoint with um with lydia that's just the standard user so let's um let's log out yeah go into the authorize button and clicking log out and let's log in again with lydia and with the same password for simplicity purposes and let's execute so let's grab this uh token that's been generated with lidia's details and let's paste that in there and uh going back to the delete method let's choose a different one and execute and as you can see we've got a response status of 403 that is because if we go back in our application the delete method right here it's it's only allowing the administrators to access to access it whereas lydia is a standard user so if we try to access the get method i believe is for both of them the get method uh will um allow lydia to uh to get the details one last thing that i would like to add to this tutorial is the fact that you can actually add more description to your endpoints uh or to actually exclude them so in this case we have this pretty useless uh hello world uh map yet so what we can do we is we can actually leave this so it can still be accessed um by the application but we can exclude it from description so this is how we would uh we would do it and also the login method we can actually specify the fact that it accepts uh type of user login and the um the request that's passed in the body that's passed in is of type application slash json and also it produces a string because we are returning back a string that's actually uh that represents the jot token and in the case of create it accepts a movie that's an object so that's the object that with the movie that we want to create and it produces a movie of with the set with the status code of 200 with the content type of application.json though these are optional if um this will if this should always return a status of 200 then these are optional but i've just put there just for demonstration purposes then in the case of get it just produces um a movie uh and then afford list again it produces a list of movies so this is pretty similar for the rest of the for the rest of the methods so in the case of update it accepts a movie type and then it returns back it produces in other words uh a movie object so movie type minimal api is generally for small applications or prototyping but if you're interested in building an enterprise crude api controller in.net 5 check out this video until next time stay safe
Info
Channel: Code with Julian
Views: 1,997
Rating: undefined out of 5
Keywords: .NET 6 Web API, .net 6 minimal api docs, .net 6 minimal api configuration, .net 6 minimal api swagger, swagger support, swagger documentation, swagger bearer token, jwt authentication, swagger bearer configuration, minimal api, .net 6, jwt, .net 6 authentication, .net 6 authorization, .net 6 minimal api
Id: f2IdQqpjR0c
Channel Id: undefined
Length: 45min 34sec (2734 seconds)
Published: Mon Nov 29 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.