ASP.NET Core Authorization (.NET 7 Minimal Apis C#)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome everybody in this video we're going to be covering authorization in an asp.net core application specifically we'll be taking a look at version.net 7. in terms of authorization not much has changed the main difference is that long long time ago there was a concept of roles that we now discard so if you ever had a question what's the difference between roles and claims that role that you knew and loved that's just a claim now okay here i have an example of an application with authentication setup so we've added authentication with cookie authentication we're using the use authentication middleware and we have two endpoints one for logging in where i am creating my claims principle with my claim i'm signing in and then i have another endpoint where i'm just checking the claim i have the application running and if i navigate to insecure because i don't have any cookies in my application i just get an empty because find user returns null so i get the empty value here on the end being able to authenticate with an application means that the application can identify you it's the same as going to the government receiving a passport and now you're authenticated with the government we just know who you are authorization answers a different question whether you're allowed or not if i have a european passport that gives me access to most countries so i'm authorized to visit them and that's just because the claim that i will have is something along the lines of passport type you otherwise if i have a latvian passport that says i'm alien the only passport that does it i can go anywhere i will need a visa with the addition of this passport type and maybe putting a your on the end basically signifying that this is a european passport type i now want to authorize some endpoints let's take over here we will put sweden and we'll check if context user has claim i'll place passport type in there and your will return allowed otherwise if you're not allowed to abide by the http standard we'll take the context we'll go to the response we'll take the status code and we're going to set it to a 403 403 status code means you're not authorized you're not allowed if you set 401 that means you're not authenticated if we want to handle both of these status codes here this is what it will look like if context user navigates to identities and we should have an identity where the authentication type referring to the authentication schema means off schema if we don't have any of that the response type is 401 and we just return an empty string format this and then if we don't have a european passport to access sweden we're doing a 403 and then we're returning a not allowed and finally if we pass both of those checks we are allowed let's come back to the browser and try to visit sweden sweden and we have a 401 that's because we're not authenticated if for now i'll come down here and i'll strip out the setting of the passport type meaning that i'm not going to have this claim i should be unauthorized to visit it let's visit the login endpoint i'm now going to have a cookie and if i now try to visit sweden i'm gonna get a 403 status code which means i'm not authorized if i come back around here and comment the claim come back to the browser i'll clear this cookie i'll re-login there i go and again try to go to sweden now i'm allowed that is all that authorization is it's a combination of first being authenticated because if we don't know who you are how can we even begin to say are you allowed the first step to being authorized to do something is being authenticated with the expected schema this first step might be all you're looking for if you have a user and he logged in he doesn't need any special claims he can just start using your website if then you have manager or admin panels or god knows what then you're adding additional claims onto users and then you're checking those claims on specific endpoints this is an additional optional step for elevated privileges or some kind of customized privileges this is where you're checking claims checking the contents of the claims principle this user record now what may happen is let's say we will take this this end point and we will also put norway here norway and denmark hypothetically speaking just to spice up this scenario so we can again re-arrive at the solution that microsoft is giving us we're going to say we're still looking for the default authentication scheme that you got here however we don't want a european passport we specifically want a norwegian passport i don't know the letters for norway so i'll just say nor and unless you're norwegian we don't allow you here okay norway in my story are pretty selfish guys and then in denmark the rule for having a european passport still applies however we'll go to the top here and we'll say we want a slightly different person to say who you are for this we'll add another cookie authentication schema we'll remove this here and place authentication schema 2 here i'll grab authentication schema 2 here place it where the denmark is and here we can add an additional parameter to switch it on or off so we can authenticate either either as authentication one or as authentication two that doesn't matter in this example what i'm trying to illustrate is that you can have many endpoints and then you can have many different combinations of who do you want to authenticate as to reach this end point and then what are your claims requirements you should be able to mix and match these as you're building up your endpoints and you certainly do not want to repeat this logic over and over again this is where we are going to be smart about it and we're going to do the same thing that we've done before we're going to go to our application we're going to create our own authorization middleware where we're gonna have the context and again we'll have the next delegate we'll call next over here i'll go as far as returning it i'm placing a semicolon here i am not going to build up an example for authentication too because what it requires is a bunch of services and a bunch of reflections so let's just say that i can create a service that will understand if this point requires authentication schema 2. it's going to look something like this off scheme and then i'll just place auth schema 2 and then through reflection at my application startup i will be able to figure out when i'm heading this denmark endpoint does it have this authentication schema on it and if it does and the current user isn't authentication schema 2 i'm going to go ahead and return the 401 i'll place a comment over here because this is not real code this is just pseudo code i will mainly focus on authentication schema the regular one and not put in a layer the abstraction layer that can do multiple authentication schemas microsoft has already done the hard work for us just understand that if i would be rebuilding it it would involve a lot of reflection so we're just gonna focus on authentication schema let's grab this code we'll copy it and place it over here and that's not my middleware that is actually just the unsecure endpoint i wanted to place it over there cool uh once and deleted one too many braces i do not want to return a string here i want a completed task so if we're not authenticated with the default schema again imagine some kind of service that we're extracting here where we can check what kind of schema this requires and then we will do the same thing here and again here i am checking a specific claim imagine if i could place some kind of attribute of claim and then say you need a passport type euro okay again i use a reflection i check what does denmark need and at that point i can surface these values uh in this middleware check and then return the appropriate response okay let's return a task completed here for now we are just going to default to the example of having or not having a european passport i'm going to come down and i will just comment out the rest of this stuff because we now have an idea that all of this stuff can be configured as surf services and surfaced in all in our middleware let's comment out this non-existent attribute well we'll commit this out and to begin with let's get rid of the claim as well we'll come back to the browser wipe the cookie and before we try to relog in let's try to reach sweden because by default we are going to require that you are authenticated as part of the authorization process let's reach it and we get a 401 and this 401 is triggered from over here coming back around let's try it to login and this is where we're now allowed again coming back around if i wanted the login endpoint to circumvent authorization i would do something like allow anonymous again this would be an additional attribute for now what i can do is say if the context request path will say starts with segments and i think i can just say login over here i'll just return next and skip any authorization again reiterating this could be an additional service that checks for a low anonymous coming back to the browser let's reach log in again the path value needs to start with the slash so that's a really good hint let's do that we'll try to relog in we're now logged in and we have removed the passport type euro let's go and try to reach sweden we have a 403 let's come back add back in the claim and please do notice that if you have some kind of database with claims and in your database you make a change of i have this user i want to give him a new claim it's not going to magically change the cookie in his browser the user will have to go through a process where he or she re-logs in and obtains a new cookie with a new claim otherwise you need some kind of logic that is going to go and fetch and always re-enrich the user session with the claims in your database let's come back and check this out let's re-log in with a new cookie let's go to sweden and here we are coming back to our application here we have all of these various moving parts how did microsoft choose to take these parts condense them and give them to you as a comfortable to use tool the middleware same as in the previous example they've just gone ahead and give you use authorization the authorization middleware is going to do the same thing that it does here however it is also going to do the things that i talked about if you're going to mark up your endpoints with some kind of schemas requirements which are policies the services in the authorization middleware are going to check that and we're actually going to look at it the rules which you are checking if the personnel is authorized at specific endpoints look like this you go to builder services and add authentication this is your configuration layer where you can define rules for building up policies a policy describes what a user should look like to reach an endpoint and by the way at authentication in the use authorization middleware if i will open it up we have a verify services registered function this function is going to try to get a service of authorization policy marker service just a class that gets registered to make sure that you have called ad authorization over here and that says add authentication let's make that save and authorization and here when we add authorization policy evaluator we will also see this authorization policy marker service authorization middleware will crash if you have not registered these services in order to configure these rules you have to specify policies and policies go into the authorization builder so let's say that this is a builder and inside this builder we can add a policy you can give a policy a name let's say eu passport and then we will have a policy builder so pb the policy builder implements a fluent api and exposes a bunch of functions to you which allow you to build up the rules which you want for this policy let's check it out what is our rule for this passport type we're looking for this authentication schema so let's say require authenticated user add authentication schemas that will be our authentication schema and then we're also going to require a claim which claim that claim is going to be passport type user place this over here and there we have it a eu passport policy then which we can choose to apply to any endpoint the way that we do it is we say require authorization and then just provide a string over here okay if you're using controllers and mvc this will be the authorized attribute for you where you will be able to specify your policy and set it something like this all right but this is if you're using controllers then finally if i want to make sure that my login endpoint can always be reached by unauthenticated users i can say allow anonymous let's come back around to the top just so we're looking at these two components come back to the browser and try to re-reach sweden and we can if we come back to the policy and we say that we want a passport type with the value of europe not a real thing but refreshing it we're still capable of reaching sweden and that's because i placed it on the unsecure endpoint let's take this require authorization place it over here come back to the browser and refresh this time and we're getting a 404 the reason for that is we are getting redirected so if again we go to the network tab and we refresh we go to sweden we are going to see sweden 302 to redirect and this is the location that it redirects us to so there is redirect logic built in into the authorization middleware let's come back around to the application and look inside the authorization middleware together open up user authorization we will then go to use middleware registration authorization middleware open that up and here is the file that we have i'll close my explorer and first of all we get the next delegate which is injected so we can actually call the next endpoint and we have the policy providers the policies that you're building up can be surfaced through this service when this middleware gets invoked we get the end point and then it attempts to extract some authorized data all this authorization data means and what this is actually doing is the reflection bit that i was talking about it is going to take a look at this endpoint and it's going to check does it have an authorized attribute does it require authorization what kind of policy is assigned to it all that kind of stuff it will pick up the data that is registered on the endpoint it will then take your policy provider all of the policies that you have registered it's going to take the end point it's going to smack them together and by the end you're going to end up with a policy that should be ran against this end point in our case if it's the sweden endpoint we're gonna end up with the logic for this policy over here coming back to the authorization middleware if we haven't found a policy that means we can just run the next delegate and return so we're bypassing any kind of authorization we then go through an authentication check it's not the same as being authenticated imagine you have a cookie for one authentication schema you actually get authenticated with it and then the policy is asking for a different authentication schema so it checks if you're actually authenticated with the correct session that's what's happening here and after we make that check we just verify that if the endpoint that we're trying to reach has an allow anonymous attribute if it does just go ahead and pass through and then circumvent any kind of authorization checking and then finally you have the policy evaluator we will try to authorize the policy against the authenticated user we will get some kind of result and then we are going to get a authorization middleware result handler and that will know how to take this result and map it to a response be it a 401 a 403 the reason this layer exists is let's say you have failed authorization but then you can override this service and instead of returning a 403 do some kind of custom stuff and that's the kind of power that dependency injection will open up for you if you take the steps to actually open up these services and take a look at them that is pretty much all you have for your authorization layer one last thing that you should note is require claim and add authentication schemas these things are written at compile time what if you have more asynchronous operations communication with the database cache whatever you have some kind of custom flow for your authorization process you need to communicate with some kind of components don't worry microsoft has you covered for this you need to implement custom requirements all you do is add requirements this function accepts i authorization requirement which is just a marker service marker services same as if you've seen if you see as you've seen in the use authorization a marker service is just something that marks something so your application can look it up load it etc use it for some kind of setup in this case we are marking a class which is going to parameterize your authentication handler let's come down here we'll create our class which will be my requirement this is an i authorization requirement and this can contain a constructor this can contain properties you can put stuff in here when you create this but i'm going to leave this empty you can then have a handler my requirement handler which implements an authorization handler of my requirement and then here we have to implement a missing member i'll add a couple of spaces so we're actually looking at the middle of the screen and in this context you can reach the user to do whatever you want and if you need to say that it has failed or succeeded on the context you have fail and succeed methods when succeed you pass in your my requirement and whatnot and finally you know you need to return your completed task and in the constructor any services that you register with the dependency injection container you can also put them here so now you can communicate with the database with the cache whatever you want you can inject services any kind of authorization logic that you desire can be placed here and it will be invoked as part of a policy that can then be applied to any endpoint keeping in mind that it will trigger as part of the use authorization middleware so any middleware any endpoints that are passed use authorization aren't going to be triggered if you fail authorization this will be it for this video thank you very much for watching don't forget if you enjoyed it leave a like subscribe if you have any questions leave them in the comments if you want to say thank you leave it in the comments as well or better yet come support me on patreon big thank you to all of my patrons that are already supporting me your help is very much appreciated thank you very much for watching and have a good day
Info
Channel: Raw Coding
Views: 31,085
Rating: undefined out of 5
Keywords: asp.net core, authentication, explained, tutorial, guide, c#, authorization, auth, authn, authz, authentication middleware, authorization middleware, dotnet, minimal api
Id: 5NUCPJTbLWY
Channel Id: undefined
Length: 21min 31sec (1291 seconds)
Published: Wed Sep 07 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.