Transcripts
1. Introduction: Hi there and welcome to my new course is for you dotnet Core identity, authentication and authorization Essentials. I'm your instructor for var Williams. I have been a software engineer and lecture for over 10 years. And with this course, I hope to teach you all of the fundamentals and essentials about securing your ESP dotnet core application using the flagship library, identity core. So on the things you learn, you learn how to build a strong foundation in ASP.net Core Security, you learn how to implement cookie authentication Manuel is and hold to manage claims enrolls in your application, you learn how to set up secure login and redistribution work for your users while maintaining ease of use. And we will set up various third-party features like email, and we'll look at how to implement two-factor authentication. We looked at how to integrate with social logins like Google and Facebook on Twitter, all of these things, all in this course. And all the things that we won't do in this course are getting destructed learning is b.net development. And we won't get lost looking at various features and trying to build up a big project. Instead, we'll focus on a small project and I send targeted what we will use the opportunity to explore the ins and outs of the identity library. We learned how to secure any dotnet Core application no matter how big or small it is because of the fundamentals of authentication and authorization that we will be exploring. You'll also need some experience programming in dotnet Core with C-Sharp as well as working understanding of how Entity Framework works. Once again, we're not going to be exploring all of these things. I have other courses for those specific things. So in this course we're looking at is the dotnet Core identity. So with all that said and done, let's go and look at how we can implement the best security of possible for our dotnet Core application. See you soon.
2. Setup Classified Advertisement Project: Hey guys, welcome back. In this lesson, we'll be taking some time to understand the projects that we're starting off with. They'll not going to start from scratch because this course assumes that you already have some foundational knowledge in is speed on a core and Entity Framework Core. And if you don't, I recommend that you check out one of my previous courses like complete is speed on a core and Entity Framework Development. Or my courses on Entity Framework, if that's where you need to sharpen up your skills. But for this course we're focusing on security. So those foundational topics are already assumed and the project is already created. So you can get to that project by following the link that is already shared with you. Or you can just go to my GitHub profile and look for a classifier. And it does that been identity security and it should pop up as one of the projects if you want to take that route. Now all you really have to do to get this project on your machine, if you're not necessarily familiar with the process, is to just hit code and then you'll be able to open with Visual Studio. At that point. Visual Studio will allow you to clone this tool any folder on your machine. And then you'll be able to open that solution. So I'm just going to demonstrate that quickly. If I choose that option open with Visual Studio, then it says, where would I like to clone it to? And then I can just select the path. I'll leave it as the default rational. Instead, I'll just put on something so it doesn't clash with my existing code. And then hit Clone. And once that is done, then you would be able to double-click this solution file and open the solution on your machine. Now, when that solution is opened in the Solution Explorer and Mark you minus to the left, yours might be to the right. However, your Visual Studio setup, it doesn't really matter that you should be seeing something. We can let this. So you'll see that we have two projects. We have a data project, and we have a web project. No, the data project is hosing basic things like the configuration for the entities, the migration so far for the database and the actual database contexts. Once again, if anything that I just said is unfamiliar to you, at least 80 percent of what I just said should be familiar to you. If it is not, I recommend that you check out one of the previous courses that I have on ASP.net core developments. All right, so for this portion of the project, everything's already wired up with all the references and so on. By the time you're doing this course, you may get prompted to update a few NuGet packages. That's fine. Right now everything is built with dotnet five, so it's backwards compatible and a generally speaking forwards compatible. But everything we're doing here will be compatible with even the next version of dotnet. So you don't have to worry too much about being all of the scope of the latest technology. So in our database context, we make reference to two tables and it's a very simple application. Like I said, we're really just want an application where we're going to be applying security concerns and setting it up and looking at how identity works in general and helps us to secure or website. So here we have two tables, one for the categories on 14, the advertisements, right? I'm applying the configurations which are phoned in the configuration folder, respectively for advertisement and four categories. So basically these are just seeding some data into the database. All right, so that's all that's really happening there. And then the migration is already created. So already created that initial migration where it creates the categories table and the advertisement stay with sets of that foreign key relationship between the two. And then it goes ahead and inserts that seeded data. So that is our data project. Really know the web project is pretty much where the user interface will sit as we know already. In this situation, I'm using Razor pages. So with dotnet core, you have the option of Razor pages of MVC. And you also have the option of using blazer. Know the fundamentals of what we'll be discussing in terms of adding identity to a project and securing your project. All of those security fundamentals can be used across the board with any of those project templates. So while we may be using Razor pages, if you have an MVC app or a blazer up the IRR using, he can still play most, if not all, of these security concerns accordingly. All right, so in the web application, simple setup things are here. We have the connection string which is going to generate a database, or it's pointing to a database that should be on local DB server, which comes with Resolve Studio. We have the database being called classifieds dB, and we gave it some little security. You can make changes there if you want. So if you don't want it on that particular server already, don't want it to be called that no problem. You go ahead and adjust that. I've already scaffolded the advertisements on and categories pages. Alright, so we have the full current pages here. And once again, this is a security that the focal point of this course is security. So I'm not going to go off and start abstracting and have repositories and so on. We have all the courses that go in depth in all of that, right? So I'm keeping it very simplest possible for the things that don't really matter within the context of this course. So you'll see that I am actually directly injecting the context. I just scuffled at everything here from scratch. I'm not using any any obstructions or any advanced dependency injection or anything like that. I just want something that works. All right. So simply put, I'm all out of the box code here, barring a few modifications. Like for the advertisements, the default code would have had ID, an ID here for the drop-down list, I have ID and name, so that a name displays on a drug columnists, right? Similarly in the details, we would have had category dot ID here. I've changed that to need for display purposes. And similar to the create for the edit. Once again, we have ID and name for the drop-down list. Now besides all of that, I've already set up the layout page to have the additional navigation links to the advertisement and the categories pages. So once again, all of that is done for you. So we have a good launching platform because I'm already assuming that you know how to build an ASP.net Core application, or we're focusing on security. So to get this fully installed or settle for mediocrity of the source code. The next step here would just be to let it create that database. So whether or not you change the connection string, you need to go to the Package Manager Console, which if it is not on this at the section on your screen, you can always go to Tools NuGet package manager and get that monitor console. And then all you need to do is update the database. Once you do that, it will generate that database for you with the default data. And then you can always just, you know, whether you click, press F5, you click Execute or use Control F5 to go into non demoed mode, you will get the web, the web app, sorry, launch. Alright, so once again, I've done nothing too special with the project except scuffled the new pages. So here if you hit advertisements, you see the default seeded data in their categories. You'll see the same thing, right? I added a little formatting to the details page for the price, but he didn't remember to do that here for the index page. So I mean, if you want, you can customize it as you wish. But for node that is what I have so few J and just could be that you, you modify the formatting here, and you also change the category, display it to not be the ID name like what we have in the details, right? Which by this time for you should be easy fixes, right? So when we come back, we're going to look at the first set of configurations that we need to add to get identity added or authentication rather added to our project. So we're going to be setting up cookie authentication when we come back.
3. Add Cookie Authentication to Web Project: All right, welcome back guys. So in this lesson we're going to be adding cookie authentication to our application. The last time, a Candida misstep. And I said, we'll be adding identity. And then I corrected myself to say cookies. So identity is the library that Microsoft uses to handled authentication authorization on all of those security things. But they do allow us to kind of do our own things. So before I go into the Microsoft provided libraries, I want you to appreciate what the options are because you just might be necessary funnel where you don't want to rely on the Microsoft library. You might want to do your own thing and cookie authentication is available, or you actually have the ability to add your own type of authentication with their own type of authentication on scheme independent of identity, a library or no, in case you're not so clear on what a cookie is, I'm sure you've seen something about a cookie and all of your traversing the Internet you mostly see in old, do you want to accept all cookies and all sorts of cookie policies and so on all over the Internet. So essentially a cookie is basically a data file that is exceeded between your computer and a server. And it uniquely identifies you as a user and your computer as a client. And whenever you attempt to do something on our website, that cookie information about you and your computer will be shared with the server. And then the server can make a decision as to whether or not to eat should show you something. Yes, there are security concerns with using cookie authentication in general. But then, I mean, you can do as much as you can to help to secure your application. And all. The point is that you will have to always find a balance between usability and security. Because the more security you put in is, the less usability is for some users. And sometimes a more user, the user for an elite is, is a less secure. So it's a healthy balance that you definitely have to gauge enough of that. Let's get into how we would add authentication and by extension, cookie authentication to our web application as it stands. So inside of our startup.js CSS file, I'm going to add this option. Right underneath the services dot, add Razor pages. I wanted to see Services thought AD Authentication. So I can just say add authentication. And that would mean that I want users to have to identify themselves. So there's little look at authentication versus authorization. Authentication means identify yourself so I know who you are right now we did see a specific allele would want cookie authentication. So inside of this method, there is, there are a few overloads. So one overlord R1 version has NT parameters. Another one allows me to insert the default scheme. And there are low on, allows me to put in options. So I'm going to use the one where I can just put in the default scheme. So the default scheme for cookies would basically be the string cookies, alright, with tools. But then, you know, sometimes you don't want to type it in watercolor magic string, so they actually give us constant or a static constant, I go something like cookie off and she saw on the fault. And if I just control dots you see with the using statement for that. So cookie authentication defaults dot and then I endlessly authentication scheme. And that will bring back that string cookies. Alright? So I can use that to the compile safe at all times, as well as get rid of that magic string. In addition to that, I would want to add, literally add cookies. So if you look at what this method is doing, it seeing it adds cookie authentication to an ASP.net Core Authentication builder using the specified theme scheme, sorry, right, So cookie authentication uses issue to be assisted in the client to perform authentication. So that's a lot of information right there. That's a whole tutorial right there in just the IntelliSense snippet. So I can just add cookie. And between these two lines, we know, know, know that our application is capable of cookie authentication. Now what we need to do is let the middleware know that it needs to front load the libraries and the capabilities to have our authentication and stuff done. So if we scroll down a bit to the configure, which is where all the middlewares are really added. You will see that we already have authorizations. Authorization, use authorization comes standard with basically any dotnet Core application template. But what we want to do is add authentication right above it, right? So you can just say. Dot add authentication or sorry, use authentication and my butt. Use authentication right above the US authorization. And I'll between those two lines, our application, we'll see, well, if something is protected, then I need to see our cookie. If I don't see a cookie, then use any logins. So that's what authentication on SES, identify who you are. Authorization says, Can you do this or not? So after you've identified who you are using, the imposter or whatever it is, you have identified who you are, right? Can you actually perform this action or not? So that's what authorization sees. So to invoke authorization and what I'm going to do to speed through this is on our index for advertisements, right? Or no or limited on the categories. That makes it a little bit more sense that you would want to predict the list of categories and the ability to augment the list of categories, then it would be to predict advertisements. Of course, different business rules have different requirements. So I'm not saying this is the way it should be based on your contexts, you make your decision, right? But if we wanted to restrict access to the categories list, alright, so if you run that application right now you can pause run the application. You'll see that there is no restriction on between the category of speech and advertisement speech. That's fine. However, all we have to do is open square brackets right above the class. All right, so I've namespace and we have public class. And then we can say author I write, and we just include or missing using statements. All right, and then this line alone, basically, we'll restrict access to anything else in this page. If it's an MVC application, it would probably be over the controller or it would be over the actions. So you can actually put this authorized in the context of an MVC application over the controller to restrict access to every action in that controller, or over the specific options to restrict access to that specific action. In the case of arrays of Ph-like what we have, you could put it over the entire class that represents the pH. And this in turn will trickle down to all of the handlers that might be in the pH. Of course, unlike MVC where you have one file with multiple auction stock into multiple views in Razor pages, you have multiple pages, each one kind of autonomous. So if you wanted to restrict access to the functionality on a particular page, then you just put that authorized flood over that particular page. All right. So with all of that said, let us take a look at what adding those few lines of code would bring to our application. All right, so our application is open. If I go to advertisements, I will navigate there with no problem. And then if I choose categories, then you see it's giving me this while it's giving me 40 forearm cannot be phone, right. Reason for that is it is trying to find by default a login page. See that I didn't know that. I didn't do much. Right. It is automatically seeing well, I see on authorized flag here for this beach, saw that means I need to ask the person to identify themselves before. Alright, so if you've done any formal security with is b.net Core, you know that it's that symbol. Add the authorized and the login stuff. You've grown risk of folded ED entity pages before. But like I said, we're doing building boxes. I want us to company. They appreciate all the bits and pieces and how they fit into the bigger picture. Now, one more thing before we close out this session. Sometimes you would want that kind of authorization across every single page. So whether you're in MVC app or is a pages up, sometimes it is that you just want ever be is that a person goes on. Our IDE user would go on. They have to identify themselves that have to be a logged in user to access anything. So in that situation, if you're using Razor pages, you can go to the startup, go to the line that says add Razor pages. And then you could say add MVC options are unequally, right? And then inside of that you just have a lambda expression on where you can see q-dot filters, dot add. So filter in case you're wondering, filter presents this, this is a filter. Anything that's in square brackets that goes over a controller or an auction or in this case a page. And sometimes even component code. Those are called filters, right? So here I'm seeing add a filter. And this filter would be a new authorize. The sole author as filter. Alright, and then Control dots to include the missing reference. So that's how you would see everything in my and I'm missing the open and close there. Alright, so this is my way of seeing every single page that says there is a page in this application. Most have that author as filter by default. So that means I could even just remove that authorize. I don't need it there explicitly because no, I've locked down my entire application. If you're using MVC, it could be accomplished in a similar fashion. Instead of arteries of pages, you would probably have controllers are let me see. Controller. So you would have controllers would views, controllers with views. And then you wouldn't have to say add MVC options. You'd actually just see put in that lambda expression directly in, right? And there you go. So that's how you would add those, that filter by default to all of your controllers. Controllers with you, right? So that is how you would own your entire application. Now in light of me locking down the entire application, there might be pages I want to get to without needing to author heads, right? So let us see, for example, the list of advertisement should be free for viewing. Maybe the details page should be free for viewing. Both editing and creating is restricted to and deleting would be restricted to authenticate that person's right. So in that case, I could easily just go to index and then use another filter that says allow anonymous and not Nemo's spilling, right? Go ahead and include the missing or references. Go. So allow anonymous on that page and allow anonymous on the details page, right, Just for argument's sake. So if I go back into running without debug, well, then you'll see that I'm going to the login page. Why? Because I don't end up and I did not allow anonymous on the actual index page of the website. All right. So you're going way out to privacy and index by default. So anywhere you want to get to without needing to authenticate, you have to tell it to allow anonymous. So just for demo purposes, let's allow anonymous. And I'm just going to rebuild and try again and see nowhere gets into the index page, right? If I go to privacy, I load anonymous. If I go to categories, I didn't allow anonymous. I after login. If I tried to go to advertisements, then there we go. Hey, it works right over create, edit, delete, all of those require logins, right? However, details will work because I load anonymous. So that's a basic way of hole out of the box. They are lower. They being Microsoft, the whole dotnet framework and dotnet core development suite allows us to just choose, pick and choose. It's quite easily, in my opinion, which page should be secured, on which page should not be secure. And of course, it gets far more complicated with more business rules. But I'm sure you're starting to see if you're not really familiar with what we've done so far, How easy to do really is to start adding restrictions on security to our application. Now when we come back, we're going to wire up a very simple login logout workflow. Just show what it looks like when we get to the page login, we provide what we need to provide and what it looks like when we're logged in.
4. Add Login and Logout Functionality: All right guys, welcome back. The last time we were sure we were setting up our cookie authentication and we looked at all of the things that we need to put in place to make sure that our application will request a user to identify him or herself before we allow them access. And we saw how easy that is. Oh, no. The line I have highlighted is slightly modified from what we had the last time and I'm going to explain. So when we added the cookie off and we added the global authentication on our authorization Filter Other, we noticed that it would always default to a page that said the website slash slash login with query string, which is called a return URL, right? So what if you didn't want it to go to that path, right? So this is completely optional, but by default is going to slash our colon slash login is looking for a login page at that path. If you're using MVC, you would create a colon controller and have an option that is called login. So it wouldn't all go to that controller called a cones. And there's a login action returned. The view in Razor pages would be as simple as creating a new folder, calling a TOC cones and creating our pH in there called login. Right? Now, what if you didn't want the defaults? So that's what I have done here. If you don't want the default for the login pass, you can actually add cookie and then just put a lambda expression and set the login path to be whatever path you want it to be. So in our example, I'm going to be using this custom palette. All right, Once again, with all the custom path, it will be looking for a cone slash login. So it's entirely up to you if you wanted to use the custom path just for practice purposes or you want to stick to the default. It doesn't really matter as long as you will appreciate the concept. So with the custom path, I'm going to create a new folder called off. It could easily be authentication or whatever it is you want to call it right off. And inside of all, I'm going to create a new Razor page. I'll just use an empty result page. And I went off to call it login because it's looking in the auth folder for our pH called login. So once I do that, I get my HTML or CSS, some of our other and my code behind. And we'll be putting this together rather quickly as I already kinda have the form here. So I'm just going to paste it there and then I'll walk you through what is being done, right? So I have roll, right, so I have a first div, say can open and close that div. And then you open and close another div. And then I mean the section is optional. It's your user interface, you can put in what you want. But this is kind of modeled off the standard login page from identities. So if you already have a project or an identity page, that's fine. You can always go and get it. By the time you're doing this lesson, this page would already be in the project anyway. So we can actually go and just fetch the code and put in if you don't want to type dot from scratch. But pretty much in a nutshell, I just have a form here that is taking an input dot email, input dot password and then a checkbox for remember me. Alright, that's all that really has. And then to top it all off, we have a submit button that says login. All right, below, I've included the PowerShell for the validation scripts that's optional at these, at this point. What? We can put all of those things so you can go ahead and replicate that form or that you want to pause and replicate it, or you want to go and fetch it from the project, that's fine. What's I'll be moving on at this point. And we'll be coding up the code behind. No, we're not doing anything too fancy. Joseon, once again, we're just trying to drive home certain concepts. The first thing that I would encourage you to do is to allow anonymous. Because if we don't allow anonymous, it will become a circuitous call, meaning when the cookie settings are trying to call the login path as defined in the startup. It is going to hit this this page. And then if it can't alone on MOZ would keep on trend to the page with a return URL for the page and then it would just, I would just break so you can actually try it and see what kind of error you would get. So elusive able to see that error in the future, you know, right? And probably later on we can experiment and see what they look like, but just put on a low anonymous suspicious of that heartache. Now instead of this page, I'm going to create a quick model. And this model. Is going to be called input. So once again, this is kinda model of the existing code are some Kodak would be generated for you by an entity, but when we get there, you'll see it. But right now all I have is buying property for input model. We have a proper default return URL and Tim vetoed error message to. We probably don't even need that, but hey, and then we have a class called input model, which takes these three fields. All right, so pause, replicate, and move along. All right, So for our get's, I'm just going to retrofit it quite quickly with turned it into a public task, async on Getty's sink, That's takes the return you are as a parameter about defaults to null. And then actually I can do a component of bone assignment here we'll just say for turning your head is null, then make it be equal to that. So that's pretty much what you see. And then we set the return, you are a property to be the return URL. Now on that note, I just realized that I do not have the hidden for the return URL on the form. So what I'll do is adequate hidden field somewhere. I'm going to just put it right on the here. And this is going to be for the return, return euro, and its type is going to be hidden. So the point of the return your list that you know when you're, when you're trying to access apart to give a page and it's it's a login and you login usually navigates to the pH of that. It would have gone to if you were authenticated already. That's what their return you are already represents, right? So whatever you click Done. And then he said, Hey, please login first. It's storing that original clique, that original destination. Alright, so that's what return you are doing, which is why we're seeing when you get here, what is the page that was trying to be accessed? These keep track of it. Now, the next thing that we would do is where we process the actual user creation and validation. All right, so over here what we're seeing is we have an on-policy async method. All right? And then inside of this on post AC method, I'm going to sit there return URL again. So same kind of components M and can work here again. All right, if it's not, if it's null, then defaulted to the homepage. No problem. All right. And probably a little more refactoring can happen, but that's fine. We can leave that alone for null, null in a real scenario, what you would want to do at this point, so pause does when they submit username, password. And if you want, they want to be remembered. At this point, you would really go to the database and see does this user exists? Yes. Okay. These actions, if not buoyancy bucket and say please, sorry, but he's validators who you are. That's fine. But right. No worse than in kind of demo fees. So what's I wanted to do is just hard code. This is not good practice. Generally not good practice. But once again, this is demo purposes. Go just wanted to see how it fools. So I'm just going to hard code and email address of floods. See Admin, test.com. Say if the person enters admin at test.com with a password of p at sign word one, right? So that's my special strong quote unquote strong posture that I usually use. But this is just what I'm putting here once again, for demo purposes, there are a few things wrong here. Won your password should never be in plain text. I use this bus or it should never be in plain text. So I'm just putting that out there for demo purposes. Later on you look at how you can hash the password on the passwords will actually look like when stored for a, so a plain text file. Now, when we do find that users, so let's see, this is the user that we're looking for. That's what was entered. Then what we need to do is build a list of claims. No, I'll claim is pretty much point of data about the user, right? Literally the word says a cream. This is why Klimt to be. So these are bits of information that the user has. The sea, the seas, who I am, this is my claim to fame. This is who I claim to be whoever you want to freeze it. That's basically what's I clean represents some building our list of claims here. I'm seeing Barclay and z equal to a new list of claims. And then here I'm going to set up some claims. So nucleon where adding to the list a nucleus. And we have some constants here that kind of reduce our needs are ID and magic strings. So there are certain claims that the system will always recognize and automatically look for and they're kinda stored, are given to us through this library system dot security, clean.com types, right? So you would actually probably have to include that using statement when you put in that line of code. All right, So claim types dot name identifier. So if you look at the static string, this is what it looks like. Now imagine having to type that string every time you wanted to name identifier, know. So just like with the cookie off, they gave us this with constants that are a fan of globally acceptable, or they work with JWT before our JSON Web Tokens before. Or, you know, any kind of API, you would always see claims kind of like being a common theme when it comes to security. And then this formatted string here, which you see is an open XML standard, is acceptable by many different systems. You will need to.net Core, but dotnet Core is taken advantage of the fact that we provide things that anybody else can use, right? So our facilitate things, anybody who's skinnier. So moving on, claimed test.html into fire. What value do you want to be stored as that one, right? You have claimed types dot name, okay? You would put your username here. So I'm just hard coding some things they can kind of get an idea of what would go. We're new, clean, clean types rule. What role is this person is? It's an admin, is the user's distilleries buyer, et cetera, new, clean. And then you can add more claims as he wants of random data points, random value. You can add as many claims as this user will need to operate in the system. You can add them, right? Otherwise they will, kind of will be added by default. What's I'm just showing you once again all the nuts and bolts that go together to make up what we call a claims principle. So after we have the list of claims, then we want to create an identity user. So you say var identity users equal to a new claims identity, which takes that list of claims that was just created, right? And then we tell it that we're using the cookie authentication defaults, that authentication schema, right? So here we're seeing, please add this list of key claims to this particular schema, which is cookies. No, you can't have multiple identities. Are multiple schemas that are using the same identity, right? Or one principle. So here we see VAR principle is really just taken the identity user, right? So you can have multiple principals, multiple identities users with multiple schemes. Later on we'll see how we settled login using third party libraries. Our systems, we will see that we can add other claims, are creating other identities using the claims from those, right? So identity user far principle is equal to new principal. And then the final thing that we need to do is actually log this user and send all we need to tell the application that this person is signed in order that it needs to sign them into the application. So we'll call the HTTP context. Great. And that basically represents the flat line, the baseline for where every single request and response passes through. So if we tell the contexts to sign in using cookie authentication, right, the principal, so create Our, let this application know that this principle with these claims, that user is basically a signed in user. Do we have identified them? And you can sit if it is persistent or not. So e-sport assistant would be like when you say Remember me on any cools off your computer and turn it back on and you're still logged in. That's pretty much all that they're doing there they're seeing, yes, remember this cookie for the next time so that the user ticked it to are not without fake TO persistent dot cookie is for their authentication. After all of that, we're going to return local redirect on with that return URL. So we're using local redirect as one of those security features and all because there are times when people might hijack, I use a session on tried to give them their own version of the website that they wanted them to cool tool or something else. So loci redirect to make sure that it will only read directly to something that is internal. Cause remember that return URL query string, which is prone to change. So if somebody put in Google.com, it would actually navigate away to google.com once I've authenticated. So think about what's on our Tucker could do with that. So logo, the redirect is a very simple, very effective way of trying to mitigate against that redirect attack. Now, moving on from this if statement, I'm just going to say else, return on authorized or unauthorized here, if you're abused the API developments that will give you a 40 on response that the in-order, you're not authorized to carry out tests or an auction. So here, if you attempt to login and it fails, we just need to know that you're not authorized. This is a very simple bare bones example once again, All right, so let us take this for a quick spin. All right, so we have our application, I clicked categories and it navigated me here. So our test is admin test.com and our password is P, That's an SSD or RDD1, right? Just to make sure, then we click Login and then we are redirected to the categories page, right? So that was that return URL, Click to categories, logged in and just navigated us to categories. All right, So if you're not off the query string, you don't see in that it had that kind of question mark return URL equals, and in some URLs, some takes there that was returned. You are know, it's asking me if I wanted to see if that's fine. But you notice that there's really no indication that we have been logged in red. So that's where accessing the user information comes in. And what we want to do in next lesson is to understand how we can access that claims principle, as well as facilitate logout functionality.
5. Exploring Identity Claims and Principal: Hey guys, welcome back. So the last time we were here, we were sitting up our login functionality, which we got to working as far as we could see because we were able to pass authentication on screen and actually see us navigate to where we need it to go. So the real proof in any application though that somebody is logged in is when you display to them, hello and username or some there, there's always some visual cue to accompany a successful authentication or an authenticated session while the person is in the application. So we want to do know is set up our application to display the logged in user, their username actually, and probably change up what is displayed in the menu relative to the fact that they are no authenticated. We will also in this activity take a look at how the claims help us with doing all of that. So what I would like you to do would be to one, go ahead and create a new partial hour. We're going to call it login partial. So you can just directly call unshared, hit Add and then create the new Razor page or actually just create new item. And then you can hit razor view. So if you create a recipe and you're going to get the pH and the code behind. We don't need both. We just want the file itself. So you can those heat razor view, call it underscore login partial. All right, I already have one, so I'm just going to show you I'm just showing you what to do and then hit add and then you'll get that new file by itself, right? So when you get that file, we're going to set it up no. So that it can act as the cue that we're going to use the display, the login uses information. So when you have that file, you can go ahead and start retro fitting it like this. One creates a new unordered list, give it the class navbar nav. Reason for this is that we wanted to fit into the navigation bar and alleles, which I'll show you in a few seconds. So the thing is that if you ever scaffolded an MVC or a dotnet Core project in general, with the identity included. Good, I've actually gotten this kind of out of the box, but since we're doing it from scratch so we can see the nuts and bolts and how everything is connected. I'm just showing you how to set this file up quickly. So we'll have the login partial, give it that unordered list with class navbar. And then we're going to have an if statement. So we're seeing if the user dot identity is authenticated. So user here represents the claims principle that no exists in the HTTP contexts are actually always exists. But until we kind of call the function that says sign in, it is not authenticated and it wouldn't have any claims. So that's why when we sign in, we see sign-in using this authentication scheme. So that means you are not authenticated. You have your principal and the principal has identity and identity as a claim. So that's how everything comes together no, to be put into the HTTP contexts user object, right? So even though I can see user by itself here, in reality, user is just like a global objects I can call here, but it's really a part of the HTTP contexts because I can't see it that dot user, it's the same objects really, right? So just showing you how everything is connected. So user.name, identity, dot is authenticated, will say yes or no. If it is authenticated, then we want our nav item here. And I'm just putting it inside of the navbutton link. So everything kinda looks uniform, but it's not really going anywhere. And we give it the value of san user data identity dot name. So name here represents a claim. And remember that we're nor sitting of the claims we said to name ones that are deliberately gave them two different values so that we can see which one of them is really being used and we see an entity name. So we'll see that in a few. So we have identity dot name, and then we have this logo button, which is going to navigate to a page that we're about to create also in the auth folder called logos. And its only purpose is to log the person salts. So if they're authenticated, they should see their username and logo born. And if you want, you can probably qualify that and say hello, dot username or welcome. You know, something friendly if they are not authenticates at which would've been in the else section, then we want to display the ability to register. I don't have are just the page at least not yet. But the ability to register as well as the ability to login. And as I'm here, I see that I need to kind of modify this is B page path and let it noise off slash login. All right, so before we do all of that or before we jump into what happens with the logo, I want us to take a look at watts. This will yield. So at the moment, I am not logged in. If you are logged in, you're probably going to be seeing something else displayed, but that's fine. I'll just go ahead and login. And when I do that, you'll see my welcome message here and username here. So, so that means the claim that we give that value is what is being accessed by an entity name. So clearly that's not really what we want. We don't want to see welcome username here. Instead, we would want to display the actual username. So we just give them the appropriate variable that would be storing whatever we asked them for as their display name. Sometimes you want to display a FirstName, LastName. It's that simple. You assign that role are not inflammation rather to that claim. And then it is going to be displayed just like that. So with me switching that around, if I go back and take a look at the page, you'll notice that I'm still going to have username here. Why do I still have username here? Even though I just clearly said change and clean. That's because the claim was created or all of these claims are created. These objects are created and these were signed in and stored in the cookie. So the cookie is still existing while I can make changes, but until I log out and log bikinis went to reconstruct data identity. So it is actually kind of difficult to change an identity after it's already constructed and already authenticated can be done. But it is not usually something that people practice to do. So the point is that you want to build up all of your claims and your identity before you authenticate the user. Now, I'm going to just log boats, so that should kill that logged in session. I see I just logged out. So let's take a look at what the logo pages doing. So create a new recipes. So the result page, you can use either an empty one, it's fine, but we want both the view and the code behind. So the view is empty. But the code behind on Git is going to do something like this. So you might get that does avoid on gets method, you can always just change it's our own to be an AsyncTask of action results on get, on, get async. And then we're going to always use the HTTP contexts call to the sign-up async method, litigate nowhere signing all of the cookie authentication, right? That out, we want to just return to the index page of our entire application. At this point, you could probably think about return URLs and all of these things, but we won't get into that fanciness. All we just want to know that we are logging out at this point, right? So that is pretty much all the logo does. So let's try to say I need one more time. So if I log in, I'm on my login page, put in my credentials, and then there I go. No, it is building the claim with the value of the email address being Boston as the name, clean. If I logout is going to kill that cookie authentication and put me back on the, on the index screen, right? If I go to advertisements after login or, oh sorry, that one wasn't protected after login for categories. There we go. If I say Remember me, that is going to persist. So even if I close the browser, the cookie will still exist. Click Login. And then if we just go to Inspect Element or F2 on your keyboard and we jump over to application. You'll actually see the cookies that exist as we go along doing the CSE here, identity application, right? Cookies, all of those things. So if I clear, let me just clear all these cookies on logos login. You'll see here that the cookie gets created. So that at the very basic level is how you can enable cookie authentication, how we can display who is logged in, and how we can control the flow of our application and logos. Having written code from scratch.
6. Exploring Identity Claims and Principal: Hey guys, welcome back. So in the previous lesson, we looked at how we can access the claim so we can set up the login, Hold the cookie authentication works and everything, the whole workflow. In this lesson, we want to kind of build on that knowledge and look at what it would take to facilitate third-party login engine. So open to know we have built our own login engine as anemic as the login code is, right? No, because we have hard coded what we're looking for. We would have probably been using a database on later on we're going to be using a database. Well, just to get through the basics, we see that we verify the input versus expected values. And then we go ahead and do the authentication. Know what if you wanted to rely on third party platforms? Because a lot of the times when you go to websites, you would see something like a login using Facebook login using tutor login, using Google, et cetera. And that kinda of spirits of the user. The, the, what should I say no, the tedious task of putting in the filling order form when they already have these scans of a cone. So here I just wanted to show the basics of how you'd go about facilitating that hole. We would add it to what we currently have. We won't be able to do it to completion though, because you will need to register your app and gets a client ID and client secret, which I will be showing you that if you had all of these things, what would be required OFF you to get it working in your application. So it starts off in the startup file, right, right here we're would've said AD Authentication. We said we wanted a cookie schema from here. We can actually, I'm going to say daisy chain, but we can actually, using the Fluent API, add additional libraries here, right, so that's odd cookie, but then what if that semicolon didn't end it there I could say something like add Google. And this would take its own options. And the lambda expression with options that it would need, right? So here, there's obviously a red line, but if I do Control dots and all that does not give me the prompt for the library. That's fine. If we go to New get sales trends, that a shortcut way. And clearly that wouldn't work. So let's just jump over to a new Git. And in NuGet weekend boroughs and find the different libraries for our OpenID providers. So if we just type in, let me try open ID. All right, not OpenID, I apologize, Let's type authentication. So that is more global library to what we want. So under authentication you see a lot, but then you'll see that we also have space for Google, Facebook, Microsoft are co-owned, and Twitter, right? So for any one of these that you wish to use as an OpenID provider for authentication on your application. You can go right ahead. So let's try with a Google. I'm actually let's just install all of them because at the end of the day, I just wanted to show you what the sittings would look like for anyone. All right. So I've installed all of them. And if I jump back over to my startup file, now you'll see that at Google no longer has an error. So like I said, I can nose, chin all of them. So what I'm going to do is just duplicate at Google. And from here I'll just say add Twitter. Facebook. There we go. And add Microsoft. So all of these libraries being present a lowest to use these as potential authentication engines for our application. So going beyond just having the additional lines, no, I'm showing you what fired at the basic level for connection to these services, right? So the libraries, we'll know the API locations hold to talk to the relevant API for authentication against a services. However, on your part as the third party consumer, you need to make sure that you have registered your websites or your application on Google or on Twitter, Facebook, whatever. And they would provide it with an ID and secret. So you would have to provide these two values, null. At this point. It would be as easy as putting in claimed key here and the secret here, right? But you probably wouldn't want to hard code them or put them in light that in the source code. Because then when you turn this in on GitHub or any source control form, it is going to be globally accessible to everybody and anybody can hijack its right. You'd want to put these in some form of settings that is secured. So that would eliminate by default also the AP settings.js ON file because this would be as publicly accessible as putting it in the startup file. So here's where we talk about secrets. So in your application, if you're the web projects, you can actually say manage user secrets. And then from here, you can put in your values, your key value pairs. So for instance, if we were to put in the key value pair are the ID and secret for say, Google. You would create a section called it Google maybe. And you're going to notice that it's the same kinda JSON file that we're used to with the app settings.js IN read. So you would say Google and then you put in the key which would be claimed id. And then you put in the key here, whatever it is, her own here, and help me get my spelling right, then you would have your client secret. So let me just jump over and make sure I don't spell it incorrectly. So you'd say client secret and then you would see secret here. All right, so that's basically what you would do. And then as many of them as you have, you have Google and Facebook, right? Will be the same thing, et cetera, et cetera, et cetera. So all of these would be stored in that secretes file. And if in case you're curious as to where that secretes is, it is actually being stored in like a secret directory that is phoned via this, whatever this value represents, that's where it is. So the thought that this makes little sense to you, and I can't explain it much better than this is why it is called a secret, right? So that is where those secrets would be stored and anything like that, any API keys or anything that's kinda secure, you'd want to put, make sure you put it inside of that JSON dot secrets file. An alternative way to manage in the secrets could be to use the console. So using the Package Manager console, you could actually see something like.net user dash secrets. That doesn't complete init and that would get it started. And then under that you would see dotnet uses secrets set. And then you would put in like our key value pairs, I would say something like Google colon, client ID, meaning the section on Google and the key client ID. And then the value of the key here. Alright, so whichever one is easier for you, you can do it though. Those waves, maybe you're not using Visual Studio. If you're using Visual Studio Code, then you'd probably want to use the command line approach anyway. So that is where you would store the secret and all to access these secrets, pretty much you would have to go to configuration. So instead of writing and the value that you would say configuration and using square brackets, you would look at the key value appearing so the, the section rather colon the key, right? So just the same way you would have created it in the command line. Here are areas that just know apologists, but Google, that's a section and then client ID let me fix the spelling so I'm consistent. So Google and then client ID. And then it would know to just go and look in the secrets for that same thing for a client secret and for every other one. Alright? So that is pretty much how you would go about securing your secret keys that you would want for your third party API. So I'm showing you within the context of authentication providers What's in general, whether it's an email provider, are anything else that given API key that you need to keep secure, That's his whole, you would basically do it and that's how you would access it when it is needed. Now, outside of this, what if I wanted to change maybe the default scheme From the challenge scheme rather from cookies. So right, no, What we have is the cookie as the one that was the first one we setup. But before we say I'd cookie within this AD Authentication, we could actually change this into a whole options configuration. So I'll just use all lambda expression and then the object. And then inside of here we can specify all the options like or dot, default authentication scheme, Default Challenge scheme, default sign-in ski, right? So if you want to by default use Facebook, you can add all of these things here. So if I said the default scheme must be the authentication cookie, that's fine. But then what if my challenge, before I create a cookie, My be followed Chaldeans, he and I wanted it to be, I could say Google defaults, which is a constant that I get. There we go from that Google Library. Defaults dot authentication scheme. And I'm pretty sure I have those defaults for any other one. So Facebook defaults. Let's see if one exists. Defaults, thought, authentication scheme, right? So whichever one of them you would have wanted to be the default authentication scheme, you can go ahead and specify. So that would mean that when we navigate to a page that is protected through our authorization filter, it would say what is the default way that I want my users to authenticate. So with auto setting up all of this, that was the default cookie authentication was a default. It went straight our login page, however, no, I'm seeing if if the person doesn't go straight to the login page, like they navigate slash login and go there. If they go to IP address is protected, then I want them to go straight to the Facebook challenge pH, at which point your application would navigate away to Facebook, allow them to authenticate with their Facebook account and then comeback with all of the claims and information from Facebook. And then the thing is that these claims that we would have set up in our login as money well as the seams, these claims are what you're going to get to basically from any OpenID provider, from any authentication on third-party authentication platform. These are common claims that are shared. So it's kind of like a standard. That's why when LC and that then even though it says name here, you'll see this very long looking URL. So that URL means that every application, no matter if it's dotnet, Facebook, Python, whichever one it is, all of them can come to the same level. And I agree that this is what I named claim is, and this is how I am going to use it in my application. All right, so that's, that's what I'm going to stop. Like I said, you would have to go and sign open, make sure you register your application and so on. But at the very basic level, that's how you would solve that. One thing I recommend before moving on though, is to comment out the additional one. So o demonstrate that hold to add the client ID and the secret using the configuration. But then if you don't provide anything sensibly here, then you're going to get runtime errors. I recommend that you just go ahead and comment them or delete them, or only have the ones that you know you're going to be using. You, I'm going to leave them here commented out so that when you view the source code, you can have I reference point. But recommending to you once again, comment them out so that when you run, you don't get any runtime errors, right?
7. Section Review: All right guys, so that's it for this section. Let us do a quick recap of what we have accomplished. So we came here, whether we knew about identity or not. We probably knew what the identity could do out of the box for us. But in this situation, we started off from scratch up basic obligation, basic database. Whether it's basic or complicated, the principles remain the same. We know that we can go to the start of week and one set of the database we can set up authentication in our application. We can let it know that it's supposed to use cookie authentication. We can rotate it to whichever login path we want to, whoever custom page. All of these wonderful things. We can set up our global authorization policy for the application. So every page by default would need to be accessed by an authenticated user. We also know that in the startup we have to add the middleware to use authentication, which it is recommended that we do that before use authorization, which usually comes out of the box anyway. Well, IT side of that door we looked at setting up a simple login form. I had added some additional links us to display what it would look like when we display login with the third party platforms. And before I move on from the startup, we also looked at adding are some of the steps towards adding third-party authentication on how to hide the claim key gland secretes in the secrets portion of our dotnet Core application. So all of those wonderful things we have been able to accomplish. We also looked at the fact that we can hello anonymous. So if we didn't do They'll global authorization. If want to authorize who would use square brackets and say authorize over whichever page or action that we want to restrict. Otherwise, we would have to say allow anonymous if everything is restricted, what we want to allow certain pages to be accessed by on authenticated person. So like our homepage at definitely allow anonymous so that it could be our landing page. We also looked at setting up the accessing claims. So after login, we know how to build up that claims identity and then the claims principle and then ultimately signing the person, creating the cookie along the way. And then how to access these screens to display information from the authenticates that person. So with all of the sudden done, I'm just going to check this because GitHub is where we store all of our changes truck, everything that we're doing as we go along. So puts in my quick message there and go ahead and commit all and sink and let that upload. And that's it for this section. So I'll see you soon.
8. What Is Identity Core: Hey guys, welcome back. In this module, we're going to start looking at the identity library and all of the functions that it affords us know just for context. Identity or identity core is the library that comes with any speed on a core application. And it allows us to manage user related operations and data with Alltop interact much complex code. Although the box, it's verbal full solely. If you need complex code, you can extend it fairly easily. But out of the box it has been pretty reliable and powerful for you. And my needs, of course, like always say, everybody's business rules will differ. Know, as it relates to what we have done versus what identity will allow us to do with identity. We wouldn't have to write all the claims manually and build up all of that. The thing is that what we have done where we built our own user claims and principal identity and then created the cookie money valley. That would probably come in handy more when you're dealing with an application that has to rely on third party authentication. And then it just passes over the information, then we can build our User Claims money while they sold. Like if we're dealing with JWT or the third party off, that's when we would end up needing to do all of that. We'll be looking at scenarios similar to that later in the course. So, you know, we're just cranking up into gear to see whole ASP.net Core deals with authentication and authorization. So baby steps, nuts and bolts. But at this level we see how we can do it manually. So what we're going to do here is create a new projects. Now this is more like a show-and-tell. You can follow what I'm doing. But it is optional because we will continue to use our initial classifieds websites. But here I am going to show you how you would be able to build authentication, authorization, all of those things into the project from the get-go. So if you were to create a new project and you choose your SBA.net Core web project, a new one works once again, what is the web up or the MVC? Both of them will have an VCs and listed here somewhere in the list, but they're using the razor pages or the MVC there it is. It would be the same principle. Know when you go over, you give it and I'm going to just give it the name simple auth up. And click Next on this green, you'll get the option to change the authentication type. So classifieds upon to know has non-selective and by default it will be not, non sorry. But then if you were to say individualist cones, then it would automatically scaffolded out certain things for you that facilitate identity out of the box are authentication, authorization, all of those things out of the box. You would also notice that you have all the options, you have the identity platform. So early on worth talking about adding third party authorization using Microsoft or Facebook or Google, et cetera, with this autoboxing, supporting the Microsoft one. And then we have windows which would be more like if you're using Active Directory. And your users needed to authenticate just by being on the network. So that would be a topic for another course or later on. So we can see individualist cones. And then we just go ahead and hit Create. So once that project is created, we can take note of a few additional things in this template who are not in our classifier templates, right? So I'm going to kind of have them side-by-side so you can see what I mean. So in terms of data, we have a data folder. When you don't include identity, you don't get that data folder straight-up. Knowing that data folder you automatically have migrations and application DVI contexts. So I have a data project where I would have kind of build those things in, right? So we have migrations, we have the application DB contexts. Sure. But if you look in this application DVI contexts, you're going to notice a certain few things that are different. A bolted one. It's inheriting from identity DVI contexts as opposed to the one that we have, which is just DVI contexts. So DVI contexts gives it a connection to Entity Framework Core. That's fine. Alright, lets it know that this is database Entity Framework. Core is what we're using. Blablabla, whoever identity DVI contexts extends DVI contexts and it adds the identity related tables, alt off the box. So identity related tables, which we'll see in a few, include tables to store roles, information on rows, sorry, information on users, claims, all of those things. All of those tables will get generated alongside the database once we use this application, VB contexts. All right, no identity DB contexts can be extended because you have different overloads are different things you can put in sake and put in like a custom class for the user, custom royal class, and a custom key. Out of the box we have identity user. So that, that class identity user represents this red head entity. User presents the default user class that comes with identities. So using control lots and adding statement, right? You have identity role, which is also out of the box when it comes to identity, really self. And then the key here means what data type should I be using to generate the key value? So in some cases, or by default rather comes with string, right? So it would have good values as the keys for these two tables by default. But what if you wanted to use integers, then you can decide to int. So you would be telling the DVI contexts and there are a few other configurations they have to put in along the way. But once you want to change that datatype, you can do these. Showing your flexibility is, but once I get out of the box, it will be string. I didn't notice that it'll stop completing. So I'm trying to reduce them all to customizations at this point. So when we leave that default, it won't complain. And even if we didn't qualify it with all of that, those are the defaults anyway, in the startup dot CSS file, you'll also see that we actually have all of this coming out of the box. So without adding identity, that would have been all that we saw in the address in the startup file, right? So I actually had to add that manually with our startup. This was added manually. But then you see over here out of the box we got the DB context at it with a default connection string. And it also adds on the default identity with some options and tells its use Entity Framework as the stores. All right, so I'm definitely alter the box. All of these things kind of come wired up. Another thing that we can take note of is in the migrations folder, in the data folder, we'll see that we come out of the box with a migration. And this migration creates all of the tables that are required for identity. So ISBN integrals, That's where the rules will be stored. Sbi net users. See that it comes out of the box with all of these columns. No, the class that I had shown just know which is identity user. This class gives automatic access to everything in this is been AT users table. So by default, any identity user object is going to have properties. I'm just control clicking to see if I can get into, see the definition of this class. And there we go. I just control click. Let me just go back and show you, just control-click the startle or so Control click Add entity user and then Control click identity user relative to string. And then that will allow us to see all of the fields that are there. So these are all fields IDE and normalize e-mail, username, password, password, hash. All of these fields correspond with the table for the ASP NET users. So you don't have to write any excessive code to be able to access these fields. Other tables include role claims. So we have an idea of what claims are. We don't necessarily know what rules are, at least not within the grand scheme of things. But basically you can assign claims through rules, also, user claims, we know what those are. So you can actually store those in the database as opposed to building them manually. When a person logs in, there'll be stored in the database and automatically loaded into a cookie after the user has authenticated. Red, we have ISBN at user login. So this one can track the third party providers that users might using or the cones associated with them that they might be using to access your website. We have is peanuts user roles. So this is saying, Who are the users, what are the rules, and then what rules do these ISAF? So it's like a many-to-many linker table between the user table and the role table. Tolkien's, this one is, if we're using reference Tolkien's, which we'll look at later on. So I'm just showing you that out of the box and get all of these tables. You don't have to build it snow. Once again, if you already have your user store or you're already kinda doing your own authentication, but you want to extend over to use identity to handle that identities very flexible and extensible and can be used. At that, but that is out of the scope of this course as we're trying to understand the basics that are needed to get authentication into our application here. Alright, so when we come back, what we will be doing is adding authentication on our proper authentication, our identity, to our existing application. So Alltop the box, we would've been able to just say, well, let me sorry, let me jump over to the app settings.js IN file. So this database would have been called that, right? So all of the box, let me just do this and we can go to the next lesson. If I say update hyphen database, what this will do is actually let it generate the migration associated with the database or the migration that came out of the box rather. And then when we get that database, and as soon as that's done, I can now access all of the tables that we just saw in the migration file, right? So if I was to execute this application, then you see we get the same boilerplate and out of the box, we get a register and login links. So I didn't create those this time. We did it manually with a classifies, but here they are. And if I click on Register, you see that we don't, but what do I register page right. Creating our cones, put in email, put in password, confirm password. If I go to login, you see that we have login. And then it lets us know how we can probably go a boat sitting up, external external sign-in monitors or authentication services, like what we looked at. So I'm just showing you that. Yes, we did all of that money wildly. We just wanted to see how everything is wired up. Null. We know how to do it out of the box if I register right, no. And I'll just choose a strong password us suggested, if I do the register, that will actually go to the database. Right. And all so prior to this suit are classified as we do on top of a database storing users, which is why we don't have a registered just yet. But I can put in a conformation so we look at how to actually send an e-mail, but they're simulating that confirm e-mail workflow right there. And then if I go back to login outside of the browser remembering the stuff, because that's really not any feature of identity. But if I jump over to the users table and view data, then you will see that there is no stored, right, that user. And this is what that role looks like. And look at that password. So remember that we use a plain text password when we were setting up our own, of course, that is taboo in the database. It would be hashed automatically courtesy of our identity service. So this is a very powerful out of the box tool and we're going to have a lot of fun looking at the notes, the bowl, so everything is setup and how we can maximize our security using Microsoft's out of the box features. So just one more test login works. There we go. So exactly what we did, all of that. I haven't written any code opened in though, and I already have a fully working login system that's already secure because my password is being hushed and I can easily start adding authorize anywhere. And it will work. So no come back, we will look at how if we already created our projects, holy, get this feature set into that project.
9. Add Identity To Existing Project: All right guys, so now that we know out of the box what we get with that entity and we have a better understanding of how it works. Let us start to retrofit our application to make use of libraries that available to us. So some of these things I'm just squint and literally borrow from what was generated with the oath of the box score if we had enable that entity from the get-go bullet, of course, I'll explain what's happening as we go along so we understand what each line is, four, right? So we already have our DB context and we know we're using our database connection, that's fine. However, what we need to add is the Identity tool, this whole scope. So I'm going to jump over to the DB context and I'm going to let it know that I no longer want you to just use DB context and I wanted to use identity DB contexts. So remember that identity DVI contexts is what affords us the ability to use all of the box, the different tables that we can get. So I'm just going to go ahead and include the package is being a core identity dot EF Core. And I let it find that install the latest bucket. And once that sin all the red lenses appear and everything looks as it did before. Nice and easy, right? So no, we automatically will have access to those tables. Right now in the startup class, we need to let it know that we want to use the default identity. So we're going to see services dot default identity and all you have different classes that you can use. The Azure AD Identity, Identity core, and you also have a default identity. So the difference between them is that when you say add default identity means all the default settings, please put them there. You can get very granular and say add identity, and then you add what you want and you will leave awhile you don't want. And frankly, I think that is a lot more work that needs to happen. I understand why it was included, but for simplicity sake, and frankly a lot of the box, it's variable full. I'm just going to keep the defaults. So I'm going to say add default identity and we're using identity user. So remember we looked at that entity uses as the default user class that represents the user table. Well after that we want to how some options. So you can add options to see how we want to deal with password. So we want to deal with sign-in requirements, right? So I can just put in that lambda expression on. And actually let me put this in an object because we can have multiple options on an object block. And then I can start fishing adoptions. But before that I want to solve this issue so I need a library and I thank gets it through control dot. So that's fine. What I'll do is jump over to our NuGet package manager and I'm going to search for Microsoft.net dot Microsoft ASP NET Core identity wi. Alright, so that is what gives us the defaults are Razor pages built-in UI for the chloride Entity Framework. So like I was saying, when we add default identity, there are certain things that just come out of the box for us. So the UI is one of those. So I'm just going to go ahead and get that version. And I'm just going to go over to the CSS file just to make sure that it is no added. Now one thing to 0 to l m here, and this has been the being of many frustrations in previous courses and even in my work. If the versions here do not much, then you might end up getting errors on inexplicable errors. With scaffolding. Scaffolding is generating files or generating views. Views in the automatic mechanisms of visual Studio and the framework. If these versions though between the authentication libraries and the Entity Framework libraries, then you will encounter issues, right? So sometimes you might have 0.09 or at least at the time of this recording, point 0100 is elitist, Right? But then if you have one that's not 0.10.9, that might cause a niches. So when we get there, if we have an AC, then we'll fix it. But generally speaking, it relates to anything that is authentication or Entity Framework related. All of them must be the same versions. All right, so this point of information right here. So now we can confirm that our new library is added if we jump back over to our startup filed and we see that our error. Appears and that's good. Alright, remove this earlier. I apologize. So that's what your line should look like, right? So that's a spontaneous so what options do we have? So we have PaaS or adoptions of sign-in options, of user options for the password. We can specify that we want to require a digit. So yes, we want to require digit, true, right? So we can set the bar password string right here, and that will be global. How many characters do we want? Minimum wants maybe 7 or 7, I think is a standard. Once again, business rules differ. We require lowercase. Do we require non alphanumeric? Do we require uppercase? All of those things? Even if we don't specify these options though all of the box you will need up capital letter. You will need a special character, and you will need that digit. And the password must be minimum. I think eight characters, that's all it off the box. So even without getting granular, like what we're doing here, it would be their boats out of the box, right? So I'm just going to show you all of these require uppercase. And I think it's required non alphanumeric, true. All right. So I'll tell the box that's what kinda of what you get. And although option that might come in handy would be the option to require confirmation upon sign-in. So options that sign-in required I've gone confirmation. If you hover, it tells you it has this flag that says is confirmed or not. So you know, like when you sign up for our websites and they say please confirm miracle before it can move in and further until you do that, you can't access the website or that's what this brings to the table. So we will be putting in that e-mail mechanism to go out and send off the email once a person has registered with the application. So doing all of these, we're going to look at one more thing before we do a migration and then scuffled or rather generate the tables. And that is extending Identity users. So we saw the columns and once again, if you want to know what columns there are, you can just hit F 12 or control-click and then F2 over again, and then you'll see what the columns are. Well, you'll notice that these are defaults. There's nothing terrible at FirstName, LastName, know, nothing personal, nothing personal information. Pebble the user. So generally speaking, whatever it is you wanted to storable do users, you would want to store them. Which means that we would have to extend this identity user table to store more things. So what you would end up doing is maybe creating a new entity. And I'm just going to say new class in the entity stable. You could store, you could create a class called anything. Somebody will generally would say application user, you can see use it against a company user. Sometimes you have different kinds of users with different fields, right? So maybe a manager has different information points than our regular user, et cetera. So it depends, right? School of Management System teachers, student as cetera, those are all users but with different data points, but ultimately you want them all in the same table. So what's wearable to go through here with this one class could apply it to many other classes. So if I had just said user, and this is obviously my custom user class. And then to say public user, I can know let it inherit from identity user. So one by a little bit, inherit from identity user. It is automatically going to assume all of the fields that the identity user had available. Then I can add even more. So what if I wanted to say add a new property of bit time to get my spelling right. And this would be date of birth. All right. So I want my my employee or my users to tell me their date of birth. What if I wanted first name and last name? So that will be a string, firstName and string thus name. All right, whatever it is I want, I'm like I was saying, you can have multiple users, so that's C, the stake adult off, just use a lot if we had a school management system teacher and student, Right? So a student would probably have like a date enrolled, teach, I would've day tired, et cetera. So the different data points would relate to the different users. That's a topic for another course though that's once again is a kind of an extension thing that would take a bit more finesse in the setup. So random, just going to keep it simple and just have my custom user class, which has the custom fields. Now once I want to use this custom user after the DB context, know that you're not using the default identity user. So remember when we're looking at the previous project, we could come here and tell it to identity user. But by default it knows about that entity user right now I wanted to use user. So by attending identity DVI contexts relative to user, it will know, look to the user file as a point of reference, which in glues that entity user stuff. And then some, right? So if I didn't have that inheritance, I would get an error here. Because identity DB context is expecting something of type identity user, right? So that's why you're seeing that error at there. So you have to make sure that you have that inheritance happening. So that's it. We'll see it as something off the type it is looking for. So this is basically how you would add a custom, our custom fields to the user table. But you don't necessarily want to remove fields if you don't use the fields aid or use the fields. But every field that is put in there is for a specific purpose, right? So at the end of the day we, I think this is enough configuration for now, let us jump over and add a new migration. So when we're doing our migrations stuff, we have to see migration. Added identities. Tables, give us spelling right? Then to t Tables. And then of course after change the default projects that go ahead and generate. All right, so I'm getting a very nasty error here. And if you've done any of my courses in order to, I don't shy away from Aras. I show you the errors, so I think we're missing out configuration. And I am absolutely correct. So let me correct that. So we can see here we have to use the data store, So I missed that step. So after adding default identity and setting up all the options, we need to say add. Defaults are odd Entity Framework store, so it knows that it should be used in the application DB context to store these tables. So I think that arrow was it seeing I'm very confused. Rant nulla. I know I should be identity. I know I should be somewhere, but I don't know where to put my still, Fred. And while we're here, another major change that we need to account for is that we need to know change everything to the contexts of our costs user class, right? So we can't be using identity user here, but intended to BB contexts, these identities are so everything has to be kind of uniform. So user and just go ahead and add the using statement for that. Because nowhere doing everything within the context of our cost on user class. Now after making those Suchi and does this tread the ad migration again? And this time I'm getting a brand new errors. So it's telling me that the non-model creating has some issue. So once again, I'm bringing it through all the motions because sometimes you miss one step and it has a ripple effect on the error isn't necessarily telling you what the issue is, right? So this is usually seen that one of the tables requires a primary key, something, something, something though that has to do with the DB context. And what we didn't do was run the base on molal creating for the ModelBuilder. Alright, so this is basically just seeing force. What is going to hop in on the beach even before you start doing what it's supposed to happen on the implementation, right? So that one line is absolutely required to ancestral what's identity, right? So it wasn't before, it is null. So I'm just showing you all the little nuances that go into adding identity to an existing project. So if we try this one more time, then we have success. All right, took a few tries, but we saw what can go wrong along the way. And every time we do this, it should be a learning experience so we can understand what's happening. So no, we see that we have a migration that is bringing about the same sets of tables that we just saw in the Box migration file. But we know see that we have custom columns in our ASP NET users. We have dates of birth, FirstName, LastName, as well as everything else that would've been off the box with that entity user. All right, So that is how we can add new fields to our tables. All we have to do is create a new class. Go ahead and extend whichever class is. So in this case it was ASP NET users. Sometimes you may want something extra for the roles table trying to find the rows all heritage who was at the top right. So all we have is the name, the normalized name on this concurrent system. Sometimes you want to extend this for whatever reason it will be the same principle. You just go ahead and extend it. And then in the startup, you could specify a default identity with the different types. Actually, it would be here if we were to add the custom rules. So it wouldn't be. So based on the type of library use here or the service extension method use here. You could add it. You might not be able to, in this case, this is not where it's at. If we're using ide identity core, then we could have extended it to see user comma, customer or with AD default identity. You'd have to see a laterals and then give it the new role type that you wanted to use in that setting. All right, so those are the little nuances as we go along and how everything gets settled. But ultimately we have done our scaffolding, sorry, our migration, no, let us update the database. And that is done. So our one's simple database that was merely storing classified information is null, going to be extended as soon as FA, There we go. And we will see that we have all of those tables as we saw from our previous project. So know what we need to do is finish wiring to get the registration page on the login page on all of those things working.
10. Implement Secure Registration - Part 1: All right guys. So the last time we were here, we were in the process of setting up our identity tables where the scuffled them, generated them in a database. Now we need to actually set up application to null hole to interact with the database for a distribution on login purposes. So what we're going to do is look at how weekends it's secure distribution process. And all of the things are nuances that we need to consider. So in the startup file, just to start off, I'm going to remove this add authentication because I don't need it anymore. I don't need to manually specify that I'm adding a cookie and Crito kooky because identity will actually create the cookie automatically. Alright? So I can actually just remove all of this. And we can start from right here. Right? Secondly, I won't be needing the special offer or the custom offer that we created, but I'm not linear with them does yet. Before that, I want us to see how we can generate register. The ages are registered period rather. That's his already wired up to look in the database and interacts with all the data that is being shared. So this process is called scaffolding. I've been seeing scaffolding a lot. So when we go to pages and we go to add, we can look for new scuffled item. In new scuffled item, you'll see a category that says identity and any can double-click that. And it will scan your libraries, make sure everything is okay. Then we're presented with this dialogue box that says, what do we want to do? So once again, altough the box. We get the register page, we get the login page. We get them to access via the web interface. However, the physical files are not there. So whether you're adding identity manually or you chose the option to edit from the get-go. This step is required if you're going to need to customize your login or your register page, or just add any one of these here and any one of these pages. You'll see that we can actually just see over at all files because they are actually there, but they're not physically accessible. However, Randall, I'm not went to override all. I'm just going to stick to my guns and I'm here for the register page. So that's all that I really want to deal with, right? Null. And they throw, we can do the login and logout and confirm ensemble it right, I'm only here for the cone to register. Then I can select that I'm using my data context. And it's already knows the music us, nothing getting prompted here, still whatever. And then I can just click Add. And once that scaffolding process is done, you'll see that we have a new folder called areas and areas you see identity and identity pages and pages. You see these files. And in a cone is the whatever really want which is register. So as many files as you would've scaffolded, they would've gotten generated unbidden placed along that full structure will also go to and it's a Read Me which don't really need right? No. So just a quick tour fuel start. It's just going to say which load Fei Li Yuan's you can actually have multiple load fast because anytime you have an IRA or a new area, you can have it. Use a different layout from the risks of the project, right? Well, we're telling it to use the general layouts that is found at the shared project level, the shared pages level of the project. We have view imports. We also have that kind of standards. So anything that would have been the standard pages there are true. It's available here. So that's all of those are. But if we look at the register dot CSE demo page, and generally speaking, even if you're using an MVC project template already blazed a project in, but these pages that would be scuffled at for identity purposes will generally be Razor pages, as in CSS HTML pages, Razor pages with the code behind. So even if you're using an MVC application at this point where definitely on poverty, everything that I will be doing is what you will be experiencing. Full stop. So the register page goes with the form, right, Create New York cones. And we have all the fields and the section on boats, the external logins, all of that is there. If you want to keep it. If not, you can modify this file as you wish, of course, within the limits of remaining functional. Alright, so let me test all the redistribution. I'm not going to get too much into the heavy explanation on how everything is wired ope right now, I just wanted to I just want to make sure that it works. So in our login partial know that we have the register page. I'm going to tell it where to point. So that URL is going to end up or not anchor tag rather is going to end up looking something like this. So anchor tag class nav link, that is B arrow is identity, right? So that's the ero identities. Name of the area is B dash area and an SDS-PAGE is slash slash register. So that's where I want it to go whenever somebody comes to the application. So register. So let us take this for a spin. So on this page we hit register, and there we go. Where at the registration page. Now remember that we had authorized every single thing in our app. So that simply means that register oath of the bulk skin with that a low anonymous flood right above it. Right? Once again, we'll get into the details of what's happening behind the scenes right now. I just wanted to test distinct. So admin test. Let me see if I can. Okay, so my usual password is P at San ss WW already want. However, I wanted to put in a weak password and let's see what happens. So I'm just going to put in the word test. You see here it seeing it must be between six and at max1, 100 characters long. So it has automatic validation happening. Not necessarily because of the policy that we put in, but because of hole the page itself, although the boxes designed. So that's fine. I'll just use my special long buzzword. And then the second buzzword most much. All right, so I'm just showing you what to get out of the box just by generating the register page. All of these rules are being enforced for us already. Then when I hit register is going to bring us all as adopt confirm register 0 page that I mentioned. Simulating the dispatching of the email to help us to register. So just go ahead and confirmed cones. But like all of that hasn't been done, let us jump over to the database and see if it worked. So in the database, I just registered, I should know be in the ASP NET users table. And if I view data for the table, you'll see here admin test e-mail. My password has been hushed. So that does not look that the password that I typed in P at San SS, they'll be OID one. And look at what we got. Oh, it's off the box, right? I'm also a confirmed user. Thanks to the simulation. But what does the Northeast you'll notice that we have the custom fields, date of birth, full name, last name. All of those are blank. Her. And it seems as though I may have used the wrong data type on last name and I did. And you guys can correct me. Oh, I'm sorry about that. But my point is that the register is working. All of that is wired up. We did very little upon to know to get it working, right. So what I'm going to do is remove this solely because I used the wrong data type for last name. So I'm just going to remove that field. I'm going to do new migration and I went to see fixed last name field. You probably don't have to do this because you probably saw my mistake before I made it. If not, then that's fine. I'm just doing this so that I can make sure everything is okay. So you see here, I made a change to the user class, adding migration. It will do the updates. And then I can just do an update database. So it will update that datatype for me accordingly. Good. So now we know that our registration page working and that's fine. So that's step one done. When we come back, we'll look at more a boat or a distribution process and see what other consideration on. So we look at won, what the code is actually doing in the, in the code behind off the file. How we can extend it to actually support the additional fields that we added. And we'll get to a full understanding of what exactly is happening in general.
11. Implement Secure Registration - Part 2: Hey guys, welcome back. Before we move on with on the sunning, everything about a register page, I just wanted to point out that if you're using an MVC application and there might be one additional theme you need to do to get your URL to actually see the pH inside of the areas, right? So in the startle viewed of by default it's had on endpoints and then that's it, end points about MAC controller. And then you have the roads and everything. You need to make sure that you have endpoints, a mop, raise the pH is all soul. So if you're using an MVC up a nice the line that says endpoints dot controller root. And then it's specified as a template, does, creates a new line and put endpoints up mop result pages. And other thing that you're going to want to do is to make sure that you have services, the arteries of pages. So you'll probably already have services. The controller will fuse, right? Yes. That's probably what you have, right? Null. Say you wanted to make sure that you have had Razor pages. So that's the other challenge that you definitely need to cone for to get everything up and running. So after you do that, if you were encountering difficulty before, then you should be fine. So that's this appoints of inflammation for MVC persons all there. No. Let us take a look at what is happening with our registers. And so I'm just going to close everything that doesn't have to do with the immediate activity in our register. We had established that it works. We also established that it's only asking for the email, the password, and the confirmation. Know there are a number of things that we can consider. One, you'd notice that the identity user by default has the username field. It also has an email address field, but we're only asking for email. If you look at the user that was created after we registered, then you would see that we only two. Oh, sorry, I removed it. What do you would've noticed that username and email, but the same values, right? Or to see him value, that might not necessarily be what you want. Sometimes on our website you'll see username different from e-mail address. And everything is kind of Lando different and that's fine. But at this stage what we would want to make sure is that we're capturing all the fields on the registration page that we need. So maybe date of birth is needed. Firstname, LastName. Maybe the username is different from the email address ofcourse the password. And then you see here Yeah, For number, right. Whatever it is you need from the user, you can add to the registration on beach. So let us say that I wanted email. I also wanted username. So you should be familiar with whole forms are laid out or hole forms work in Razor pages. So if you have that are registered model and then what happens is that we've got this object called artists other class called input, which is going to be storing those different fields that we're asking for. So we'll have to make sure that this input class has all of the fields that we're asking the user for on the form. That's why you see using the EM lighting up because it's not asking for to use anymore. It doesn't have our representation on, off the username, but that's fine for now. So we will be using and we also the password. And I'm just going to add that additional fields for first name, last name, and date of birth. All right, and for date of birth, I'm going to specify that it's type is time, our data rather, so that we get that color window control by default. So basically that's it. The whole you want to extend the fields that are on the form. This is step one. You will make representation of the fields that you want right. Now. The next step would be to actually have the inputs class retrofitted to accidently so I can just control click on it, jumps over to the inputs. So we see here buying property in both models. So that means it's seeing o-chem tracking whatever data is put in to the corresponding fields for the input model as seen by the object inputs. Here's a definition for input model. So you see all it does is that e-mail the password and confirm password. The validations are there, which is why we've gotten those validation messages about the minimum length of the buzzword, right? And the foot that they needed to match all of those things are there out of the box. Soul, if I wanted to extend this, what I would do is let me just copy one of them that are there. All right, so first name, first name, that's our new fields. Display name, firstname. I don't have any length requirements and it's not a boss or a datatype, so I don't need all of that. So that's it for firstName. I can duplicate that and do that for her last name because those two are pretty much the same thing, right? Both are required. However, for date of birth, maybe dates of birth is not required, so I'll put in date of birth, Putin, the display name. But it is not required and it's definitely not a big deal if it's not provided. But I'm just showing you how you would extend that glass. Know when I go back over to the form or the red lines are gone because no, they see the fields. That's fine. Now when we hit Register case, so Username, okay, We lift all Username. Let me make sure that I put in user name. And username would also be required. And this is where it could get creative. You could say if you want a different use an improvised on, otherwise we use the email and it will still flat that you can get creative and experiments. And I think the spinning that I use for username is different. There we go. So when we hit the register button on the page, what happens is that's going to hit the post. So on get it loads the page. That's fine. Oh, that works. And then you'll see they have different third party library are not third party have different libraries being injected in, like sign-in Manager, User Manager and email sender. The sender will have to wire that's money wildly. So later on we'll do that. You'll also have multiple books on logger, that's fine. But between sand and monitoring user manager, you have a lot of powerful foam shuns and just general functionality to help you to manipulate all the US, ALL related operations. So let us continental what happens on posts. So on post, We knowable the return you are a lawyer. We get the external logins of which there are none, right? And also don't have to worry about that. But then we do the validation. Validation is relative to any validation rules here, that's fine. So if it is valid, then we build our user. So notice that we're seeing var users equal to new user. If we didn't specify that we're using a special class, then it would have been new identity user, right? Which would still work. But the fact is that we would be limited to which fields we can and cannot use. So note that we have the user class using, I can say what is the username? Here is why username and email got the same value because by default you have to provide a username, you have to provide an email. And what the default code does is set the e-mail as both. So now that we've extended our form to actually ask for username, I can know say that username is in username, email is input dot email. And then I can do that for all the other fields. So date of birth, date of birth is no inputs. Thought of birth, etc. So I just did that for last name and first name and date of birth is giving an error because I said it, string 1, it should be it. So after making that adjustment, we can just review our entire user object. So that is what we intend to store. No, you will use one of our libraries called the User Manager. Lets us go Baco, this is used for mantissa and it's being injected in. So courtesy IL-4 identity library, we get this user manager object or library that has a simple function that allows us to create, what are we creating where creating a user and we're giving them that password. So remember that we would've typed in that password in plain text. But by the time this method is finished with, it would've hushed it to the point where it would be completely unrecognizable as on what alpha, the same boss or it will always look different in the table because I followed this method hashes the posture. So hashing is a very important procedure where we obscure the presentation of the password for storage. And it is always a one-way operation so you don't want to on hashed passwords, you hashed passwords, and then you hash another string to compare with the original hush, right? So you obscured a password. And then when the person comes to the login, you obscure what they have typed and shaky both obscure versions off that takes look alike. If they don't, then it fails. Well, you don't want on harsh what is stored in the database to then compare. All right, so hashing is a very important security protocol that hides or passwords. All right, So then after those, this, this may or may not have succeeded and then if it was say a result dots succeeded, then it will log, okay? Yes, nice. And login is very important for security based applications or tools. Security off application by the way. So you'll be seeing this thing a bit more logging later on. What did those is generate a token code. No, we can change the Tolkien manager, meaning we can use our own body because we use the default identity. We're using the default token engine. And that Tolkien is basically just that fact, hush, hush string. You would see at the end of a URL up, they get that confirmation email. Click here to confirm or click the URL. I is it is URL www_website.com slash this long alphanumeric combination. That's what this does is it generates the code for us relative to the inflammation the user provided. And then it encodes it and then it sends art creates a URL. So it says callback URL is this page, right? And it is adding those values to the e-mail that will get sent eventually. So like I said, we're going to be wiring tops with actually dispatches that e-mail. But I want you to appreciate all of what is happening right here. So all of this generates that Tolkien for you. And then it sends that email. And then if use a manager dot options signing require confirmed our cones, then it redirects to that beat. So notice this is a Piazza we didn't create, but just by adding default identity, it actually went to that big, right? We didn't create it, we haven't created its own. We've only scuffle at one, but once again, because you've added default identity, that UI is implied in our project. Only if we need to modify something, then we need to actually generate that physical page like we have done for register. So right, no, it will always read Erich to that beat. So when we set up our emailing mechanism, we can actually just remove this part of it. And then we can just redirect to the way we can sign in the person or other, and then redirect to the return URL. So that means if the person was on the categories page and then they clicked register, we know that the return URL, we know how that works by null. All right? But the sign-in manager is another variable for library that's closest to the sign in this user, I'm deciding manager actually creates that cookie, gives them the claims as stored in the database and authenticates that user altogether. So we're seeing a bit more of that when we get into the login portion of our activities. So that's basically what is happening when we click Register. All of that code may seem simple. Art is simple and it's made very simple because of these helper libraries that are afforded to us by the identity suite of tools. But it is a very, very complex process in the bucket. Alright, so if all those fails and the user, it, if it wasn't successful, are the Federals and valid. It will just go ahead and compile all the errors and return the page. So what I'm going to do is test on mother or distribution just to make sure that everything still works. So null on our registry. So don't be AGC though we have all the fields that we had specific. All right, So instead of username here, I'm willing to say admin, admin test.com. First name is admin, last name is test, and then date of birth. Just choose the day. And then my special password, which is p at San assist allele or D1. And just repeat that. And then we can hit register. And we get redirected to that register confirmation. Know what's all this thing about that token. If you look at this URL, if you just hover over it and look at the URL that comes up, you'll see that everything that comes after user ID equals, that is, well, that's the user ID in the database rather. And then you'll see that you have an ampersand, then the word code, and then all of that after code is that Tolkien, that LC and gets generated, right? So we didn't do any of that, all of that out of the box. So I just confirmed a cone and that's fine. So you see here is that quote that I mentioned all of that Tolkien code that was generated. So let me try another a distribution on, actually I'm going to use the seam user. And I, I'm just, I'm just forcing an error to show what happens when certain constraints are violated. All right, so using the same stuff, you'll see here, it says username admin is already taken. So when it generated that list of errors here, that means result was not successful because it tried to create. But then based on the constraints econs off to uses with the same username out of the box. There are certain constraints, certain things that it will tell us how we get haptic feedback. We can tweet them as we go along. We can create our custom user manages custom authentication rules, everything that we need. We can do an extend identity as we need to. So when we come back, we're going to take a look at what it takes to set up that e-mail confirmation so that when we register, we can actually see that email, as it were.
12. Implement Email Verification for Registration: All right guys. So we're back on. We want to set up our email sender and all sending that email after the user registers, those who are far away in producing the success rates of small methoxy 1 and 2. It does increase the level of security and kinda brings in a two-factor authentication on Kindle for regimen. Even though it is not the most secure option, it's still does bring that level of security. So we're definitely going to look at how it is implemented. And by extension on ones who have the email sender up and running for register, you'd notice that there are other procedures like password reset. Although the two things that our emails to be dispatched and we'll be setting up email sender relative to our current task, which is registering our user well, this email sender I email sender interface can be accessed anywhere. You can always just go and register it in the way I'm going to register it rather into startups so that it can be used anywhere else. Alright, so let us look at what it takes to get this open earning. First, then went to create a new folder. And I'm going to call this services. And in services we're going to add a new class. And I'm going to call this class just email sender. All right, so we have our class email sender and he's going to inherit from the email sender. So this email sender is going to implement the method send email async. So that's definitely what we need. Before we go any further, I want to register this in the startup. So I wanted to make sure that application knows that we have this service running. So I'm going to say services dot add, transient. And I'm seeing that I email sender is going to be implemented by email sender. And then we add any missing or for instance, worse. No, I'm leaving this here for now, but I'm definitely going to revisit that because I think by the time we're done here will have to write that line up differently. So no problem. So what I'm going to do in the I-beam in the email sender class is setup a few fields for our server or port on our address. Someone to be using SMTP like sittings. So for this activity though, like Oh, we're in a div environment and not everybody might have access to an SMTP server and so on. What we'll be using is local host SMTP server. And we'll be looking at enough use. So for null we have the fields. So we have the fields for SMTP server, SMTP ports on from e-mail address. And then I have a constructor that is initially initializing them so you can pause and replicate that. Now in the Send Email is seeing caught, I'm going to do is construct a message. So say var message z equal to a new message. So our new mail message. And that is going to require the system dotnet dot male library. And inside that mail message, we can set up the from the subjects of the body and the body is right. So we can set up all of those. Because Send me lay a sink is a expecting those from whatever scalding. So we have all of that information available tools. We're going to hard code or from e-mail address because generally speaking, you'd send from like I do not reply at are no replay, something like that. It doesn't really matter. Business rules differ. We're just going through a basic setup. Now after all of that, we're going to set the message dot add and we're adding a new meal address for the email address that is expected to be sent to. And then we're going to invoke an SMTP client using the SMTP server and port values that would've been passed in through the constructor and will be a dispatching that message outdoors. We'll just return that the task has been completed. So that's the basics of mobile phone, email sender using SMTP. And all I did say that we are going to be doing everything locally using our own SMTP. So what I'm going to do is modify this startup file and r, sorry this line in the startup. And what I'm going to do is add transient and let it know that the service provider, So as what S here represents the service provider. So I can let you know it's going to be new email sender. And then email sender takes that SMTP server as the first parameter. All right, so we'll say local host or whatever the SMTP server is that you're using. Some persons would actually put that inside the app settings file and then call the configuration. There are so many ways to do it. We'll be using the default portrait is 25. And then the email address, I'm just going to say no reply. Classified.com. That is where the e-mail is expected to be sent from. So that's basically what this is going to look like in the startup. Now let's get to our SMTP server. So we're going to be using this Luca SMTP server called paper, which you can get to a paper cut dot dash smtp.com. And it doubles as an SMTP server and e-mail viewer. So it's a really handy tool for development, stylish ones where you're just wanted to see, does this emailing mechanism work? I'm I seeing what I need to see in tests, right? So you can go ahead and read up on it if you want. But for anomalous interested in downloading the latest release. So they're hosting it on GitHub, we can just download. And once the setup is underway, you may be prompted to go through those. So you can just go right ahead and install. And once that has been completed successfully, you can go ahead and open it on your machine so you can just hit Start, Search for paper cuts and a window similar to this should pop up. You may also need to free up in the firewall so does allow access so that it knows my machine knows to trust this application. All right, so that is what the email manager looks like. But once again, it's doubling as SMTP. So let us take this for a spin. So I'm just filling out my redistribution page with some test data and then I'll just hit register. So as usual, we are navigating to the register confirmation page. Right. So it says, please check your e-mail to confirm Europe cones. So notice it's not going to that simulation anymore. If I look in the coordinate system over to the register page quickly, what was it? It said that it's going to dispatch that email sender and then it seeing if the options requires confirmed our cones, then go to register confirmation. That's fine. All that, That's just fine. But if I jump into pay-per-click, you see here that we've got the email. Alright, please confirm your article and by clicking here, well that's exactly what they said. Please confirm your columns by clicking. And then we have the anchor tag with the HTML encoding of our callback URL and the Tolkien code. And all of that to seeing clicking here, right? So that is basic what that brings to the table. So yes, we can test the email and all we see that it works, how exactly it works, as much information as you want to present the user with, right? That is where you would do that. So I'm just going to see click here. He navigates and then he says, You're no confirmed. Alright, how do I know if I'm really confirmed or not? We can just jump back over to our database as levodopa in here. If I refresh and look at all the users. So here's this recent user. You'll see here that e-mail is confirmed. So that's the one that's I just confirmed via e-mail. And notice once again with the passwords all three boss or is it different? Well, they're the same. Be at saying This is the blue or ID1. Alright. So I think that's it for no. So like I said, this e-mail senders going to be used in multiple places for multiple tests and situation. Sorry, let me just grab my bearings. So this email sender will send e-mails for distribution, confirmation for Forgot Password, and for anything else that you need. So once you have this paper cut SMTP server running, feel free to test those e-mails on what they're going to look like in different settings and situations all over the place.
13. Additional Password Considerations: Welcome back guys. So we're going through setting up our distribution and implementing security. And we've briefly looked at some of the security options that are kind of built into identity that we can just put right into pipeline. Know the thing is that the order recurring theme with identity is extensibility because not all the time, you'll get the default options that meet your specific needs, your business needs or whatever it is you want to accomplish. These are finals of the bulks up to a certain point. Well 20 just want to go just that little edge over. You may need to write some extensions. So in this lesson we're going to be looking at adding additional password security. And this additional password security could be driven by what your vision is for what secure passwords need to be in your particular organization or your particular setting. So globally we know that we want to require digit so on. Nothing less than eight characters long, yes, uppercase and all of these things. Sure. But then what if you wanted to make sure that specific keywords weren't in their life maybe or company name, or even the user. Sometimes users use their own name as the password, stuff like that. You could actually help to mitigate against the certain things that, that by writing your own custom methods are functions. So the thing is that at this point services dot default identity we had added on Add Entity Framework stores how we told it to use the DVI contexts. But we could actually add more to this pipeline. So I'm just going to remove that semicolon and went to the line so we can see where each one starts and stops. And then underneath that one I could say dot. And if you look at what you get, you see that you have some Part two kilo, let me just say funded data, let me start typing validates and so you can add a password validity can add a rule validator, Canada user validator. If you want to write extension methods, which is what we're going to do for the password pipeline or validation pipeline. It's as easy as just tucking them on to the identity service that you're adding. You can just add them on. So any custom quota you need to write, or if you want to use your own Tolkien provider, heroin user store, whatever it is, because you may not necessarily be using the database fresh like we are. He may have a database and you want to use your own store. All of those things are possible. So I'm going to do the password validator. And here I'm going to have class that someone to call password validator service. So you just give it the class that you intend to use or create. In our case, we're going to create this. I already have it created, so that's fine. You can go ahead, make the class button there. And then I added a new folder on the Add entity and put that class there. So you can just go ahead and do that. And pretty much that's a pattern for any other customization or extension that you want to add on to that identity pipeline. So when I jump over to this class, the trademark characteristics of this CSS standard class, but it's inheriting from i password validator with the contexts of our custom user class. So I fostered validator comes from our Microsoft dot ASP NET Core identity folder, or sorry, library. And the user comes from our entities namespace. So you can go ahead and type that unused control dot include the missing references. Once you do that, you'll be required to implement the user face, which gives you this method called validate a sink. Funded async takes the manager as well as the user object and the password as they are being created during the registration process. So I went ahead and put in some sample code as to what could happen around here. I'm just seeing if password meets this condition and if you don't want are you have all of your conditions, whatever it is, you pass password through your checks and balances. If it doesn't meet the mark. He your business rules because it will only get this far if the password RD MIT these requirements. So if it meets these requirements, then is going to go down here and say, okay, let me further scrutinize this password based on what the business wants. So business wants, if it doesn't meet those additional requirements, then we're going to return task dot from results and identity results. So this method takes an identity results, right? Because that's what this is returning. So we are to return that identity result and fail that takes an array of identity errors. So you could just compile that area, compile the area, compiled areas as many violations as you have your compile that area, add a new identity error per violation, and then finally end with that result. Returning identity result field with maybe the whole array of errors. Those are the areas that get displayed on the Register page as the errors, seeing why you can't register. So remember that when we tried to register if we didn't put in a strong enough password or username was taken, it bounced back and said, hey, this is wrong. So pretty much identity errors. That's what is going to be displayed on the page. Once this bonuses. If everything is okay though, then we would just return the identity result dot success. Which if we go back to the register page, you'll see a lot of that asks if a result dot success. So the result of me trying to create this user if it is successful, then proceed. Otherwise, display the errors that came back from the result. So that's all that is happening right here. So I've retrofitted this method to drive home my scenario that I just painted. So let us say we have a bunch of things that we're looking for. I'm going to start off by initializing a new list of identity errors. Then I have the different shapes. So one check could be that if the password contains the name of the company, then you add an identity, ERCP and that the code is company name, what the description, which is what would actually print out on the page to the user, is that you should not contain the name of the company, right? And although one, if it contains a first name or the last name that the user is entering, then we buzzword, cannot or should not contain your name. This one use anymore e-mail. You don't want them to put that in either. You put an appropriate message. So after all of these checks, it will just be adding new errors, adding new Eris to the list. And then if at the end of it we actually have errors instead list, then we want to return that it failed and we want to convert that list an array. Why I would do that? Because remember it's taking on IRI of identity error. So we had a list compiling. We just converts it to an area last minute to send buck with the failure. Otherwise, it was a successful fostered creation attempt. So at this point to meal, so on to consider integrating with third-party services. Once again, it depends on your business rules, so I'm just giving you the ideas. But you do have third-party services there that help you to determine the strength of passwords relative to how many times these passwords might have been breached in the past. So typical example of such a service would be PEW 100.com, PWN ED.com. And they actually tell you like, okay, this password has been breached. Maybe I fellows on times in the past. So you don't want your users to be using breach symbol. Passwords are possible. Results are known to be vulnerable like password RP at sign as systole or ID1 like I'm using, right. So you could integrate with other parts or third party services At that point to make your whole validation workflow more airtight, fun, although that is basically it. We just extended it so that give it a quick run. All right, so here are just during a brand new user. And what I'm going to do is put in the password, make sure it meets the minimum length. What I'm going to put in the word test. Alright? And I'm going to do the same thing, don't hear. And not sure if this will work properly because I'm not doing case sensitivity, so I'm going to definitely need a modification. So the code to make sure that it does a case-sensitive check for the strings. But I just wanted to see what will happen. So nots running in debug mode, when I click Register, you see here password should not continue your name. So it's bouncing buck with that very era that we just sit. All right, so pause everything else but failed on the more stringent measures that we have put in place so that it's simpler really, to extend the functionality of the Identity Services.
14. Registration Essentials - Section Review: All right guys, So we're ready to close out this section or module. And I think we've done some particular work here. So we've added identity to our project minute we extended the user class by creating our own class, meeting it inherited from identity user. We can put in our own custom fields. After doing all of that, we had to the DB context know that each should be using the identity DB context as opposed to irregular DB contexts within the scope of what our new user class offers. We also had to make sure that we put on this base on modeling creating because we saw the era that we've got with older kids. Further to that, we did our migration, which gave us an additional migration file that created all of those identity related tables for us in the database. Now at this point, are probably should've mentioned this before, but there are times when you may want to keep a different user store from the actual transactional database. And that point, it would be as easy as creating a different database context and giving it its own connection string in the startup dot cs area, right? So you would have two of these, one for the advocates on DVI contexts, on 14 to identity DVI contexts, you might be using a custom name. So that's fine. Well then of course the different connection string is where you will be telling you to use this database for that purpose. And then you could probably do BK that then how something like identity, DB connection, and then you give it its own connection string. So I'm just, I'm just sharing different things with you because you might be looking at all the projects and UCI, different DVI contexts for user related stuff. And then even then, even when they use the same data store, sometimes personas may separates the application DVI contexts, That's the irregular data, data differently from an identity based DVI contexts. I'm just demonstrating it here. So user DVI contexts. So this one would still be DB context. All right, well then the other one would know inherit from the identity DB context, and it wouldn't need any DB sets because all of the box, it doesn't do anything but handle identity-based stuff. So you may see things that That's I'm just sharing different nuances are different things that you might run across as you grow and develop more projects so that you have an understanding of and appreciation for one when you might end up doing certain things. All right. So outside of that though, we looked at all we scaffold or areas and we scaffolded or register page. We extended the form to have additional fields relative to our custom user class. We looked at the register file and the only modifications we had to make really or just to make sure that we're capturing that additional information into our user object before the user gets created. We got to implement our EMEA sender. So like, oh, we have that email sender going on. No, we can actually just well, we can we can leave all of that code does is that that's fine. So we just redirect to the greatest of confirmation. We don't have to trouble any of that. But we implemented our email sender right here. In email sender puts it in a services folder. We said that our SMTP settings and in the startup weekend of hardcoded those values. So instead we're using local host, which could easily be swapped out for your actual SMTP server. We're using the port and this is the e-mail that everything is getting sent from. And for testing, we would have set up our paper called SMTP. Outside of that, we added our default identity. We looked at the photo we can put in our custom rules for how user information is validated at the time of registration. And different constraints, again put in at that level, we have to make sure that we add the Entity Framework stores. And we also looked at that we need to add Razor pages. If you're using an MVC application as well as at the endpoints for Razor pages. Alright, so with all of that said and done, we're just going to do a quick check-in and always make sure that your message is clear enough. And then we can do and sink. Now when we come back, we'll start looking at some more authentication and authorization, but within the context of identity. So we'll be looking at how we support login functionality. Forgot password, all of those wonderful features.
15. Login Essentials - Section Overview: All right guys, So we're coming off the heels or setting up our distribution functionality. And in this section we're going to kind of focus on authentication. So that's setting up the login, looking at password security, looking at Session Management or cookie management using identity. All of those wonderful things we will be looking at. I will be taking a deeper look at the third party libraries that user manager under sign-in Monitor and how we can implement the multi-factor authentication. So stick around, we're going to have a lot of fun in this section.
16. Implement Login Functionality: All right guys, so in this lesson we're going to be looking at the login functionality. So we already setup or a distribution on stuff and we're able to get a user created in our deeds of store, no, we actually need to do the login. So before, no, we had actually implemented login using our custom login page and our custom code, which I'm sure we can both agree, was not very secure. What it did was to accept the input from the form and we manually test it against something that we figure would be correct. Are we want to be correct? Obviously, in a real-world situation, uses are stored in the database on when they come to login, they come to authenticate in the up. And we need to verify their existence and the accuracy of their password in the database. So what we're going to do to get a real login mechanism is to rely on the login code provided to us by the identity. So we can right-click on a Cones similar to what we did with our register page and we can go to new scuffled item. Then we jumped down to the identity, sexual identity. And after it has finished its processing and we get this dialogue box, we are going to select the login page. So we have login and well, logo, so I'm just going to select both at this point. All right, so once I do that, we know we select our data contexts and then hit Add. All right, so I'm encountering this error. You might not encounter it. But if you are encountering it, then we're going to work through it together. No, I think this error is coming up because of the potential versioning gap that I would've mentioned earlier. So I'm just going to cancel off this. And we can jump over to the NuGet package manager for that web project. And if we take a good look, I'm pretty sure that they are going to be some updates here. That's our pending. All right. So the thing is that when the versioning is misaligned between a few of the packages, then everything else will be out of alignment. If I'm not mistaken, at least one of these is There we go. So this one was upgraded. I didn't do it personally. Sometimes it happens. I don't know. So does he gets installed after the fact, but nonetheless, this is how we're going to solve it. So I'm just going to select all packages and let them all upgrade. And what I actually could have done was just good for the entire solution to make sure that all of the projects are on the same page. So a little off-topic null, but we can actually right-click the solution managed and get packages for the solution. And that allows us to look at the individual projects and the versions that they're using. So when we get the list of packages and we click on any one of these packages will see the two projects or as many projects as you have. And if it is in one and not the other, you'll see that it's not installed. However, for light into different, we're a core, it's in both, but one is seeing five-point 10. One is saying 5.11 is generally speaking, it's good to just have everything at the same levels. So I'll just go ahead and click them one-by-one and make sure that they're all at the same version. Now, kind of easily to do this too is to just go to the CS Bridge file. And I can just change these to 11. So I know that we live in is what these need to be. Just go through them all or you could have just done the NuGet package manager. And albeit that there are so many ways, but once you do a build and it has been reported successful than you know, you're on the right track. So after all of that, let us try this again. So a Koen News scuffled item identity. Go ahead and select our new pages and our DV context and add. And when all of that is done, we now have our new pages for login and logout purposes. So let us take a look at the login page and all the money or login page that we created actually looks very similar to the scaffolded login page. Except you'll notice that a few more services are being injected in, in terms of the user manager, on the sign-in manager, we've seen those two libraries in the register page. And you'll notice that there are few other things here that we didn't include. Ultimately, we have the same input model which takes the email address and password. And then this could be modified if you want to have like a username and password login, then you'd obviously asks for the username is that of the email, so you can modify that if you wish. Otherwise, we have the En-Gedi, which basically wants to know is there an error message I should display? No. Okay, fine. The return URL is, and then it makes provisions for the external sign in libraries or sign-in services that might have been included. That's the Facebook and Google, et cetera. So we're not going through those just yet, but up to worry about that. However, on post, Here's where more stuff the magic really happens. So on post we're doing something like okay, we know about a return URL and the external logins, That's fine. If the model state is valid and validity once again, is based on these attributes are annotations rather that the model would have. If everything is valid, then we use the sign in Manager. No notice I am not making a database called it isn't even making a database called art, not explicitly because the sign-in manager is chock full of methods on one of them is the password sign-in async. So this method by itself is going to go to the email address and the password that has been provided. It's going to go and check in the database in the ASP NET users table. Can I find a matching record? Yes, I can. Okay. No. Armed with the flower to remember me or not, we're going to create the cookie, right? And actually signed the person in. So this one line is basically going to do all of that and defend the original one. All of this building the claim, setting up that entity user, the principal and then signing in. All of this is captured and executed pretty much in this one line. All right? Of course this can be extended if you have more claims or more things that you want to add to the user. But ultimately speaking, you generally out of the box, Candace, use the code as it is, right? No. So after it attempts to create the cookie and attempts to meet the whole principle and sign in the HTTP contexts, It's going to return if it was successful or not. So if it was successful, yes, we log to the logger which will be setting up later on that this user has been logged in. And then we redirect. If it requires two-factor authentication, there's a page that comes with identity that allows us to facilitate, to FA if they are locked out, right? So octo means that we can actually track to see somebody has too many login attempts or somebody has violated some business rule and they're not able to access the system at this time. We can set that flag so if they are locked out, then we redirect them to the beach that's seen them know they are locked, told. Otherwise we just show an error which you can customize to some extent. We don't want to give too much information because if the password was incorrect for argument's sake, you don't want to give them something specific enough to know all your posture. It was wrong, all your username was wrong because then you'd be giving an attacker at least 50 percent of the equation here, they would know exactly what's wrong. So this is a very generic message to see invalid login attempt. Once again though, you can kind of treat that bullets within good taste and security. And then ultimately we return the page. So if you get this far, that means something failed up here because if it was valid, it would have redirected. And notice low-calorie direct because you don't want to redirect our risk redirection to an external website. So we were local redirect to the return URL. That is another feels safe against potential redirect attacks. Now we can test this old was I wanted to do is jump down to the shared and go to the login partial. And we're going to modify the URL for the login so that your URL is not going to look something more like the Register 1. Instead, I'll see in a register it's going to see a login. And instead of register once again, it's going to say login. All right, so now we're going to account login. And in the same way for the logos, we can just read them to the logo page. So let us take this one for a spin. And when I get to the login page and try to login with my existing are co-owned, I'm getting an invalid login attempts. No, this is not a very obvious error and we need to walk, walk through this one. Let me explain exactly why this one is happening. So the way that the sign in Manager, let me jump over to the login. The way the sign in Manager or this method works is that it takes a username and a password. So a lot of the times when we get to this point, we might get mixed up on wonder, why isn't it working? I'm an outputting into right thing. Because by default remember that the register page was taking email address and the password and the confirmation. Then using that email address value as both the email address and the username values. So that is the result of the box behavior. As a result, when it got stored in the database, you don't see in Email and username being the same value because it was the same e-mail address that was taken and be used for both. Since we came on though, we put in a username field. So we're taking username different from e-mail. So that means when the sign in with password ac method is being called, as we see here, it is passing in the email address that we put in what is checking that against the username field. All right, so that is why we are getting our feet and that's completely not obvious. So I'm just pointing that toe because it has caught me a few times. So I hope this helps somebody out there. So what we're going to have to do, once again, we have to settle on how we want our users to be able to sign in. And this is where customization on business rules will determine what extensions you probably put in versus how you write up your logic altogether. So if you want that e-mail authentication model, then you might as well just leave email as username and password. Otherwise, you may have to use the email to find if there is a user record on. If there is, then you find the username on that record. They would provide the email, but then you find the username to then make use of this method. Or in our case, all we can do is just change the input model from wanting an email to just asking for the username so I can see username. And I don't want it to be an e-mail address field, right? So, um, this refactoring this email address field and the editing anywhere else. So we're asking the user for their username and their password, their e-mail address, and their password. So on the form itself, of course, after update the references. Alright, there we go. So now that we've done that, we can try this login again. So now I'm asking for username and password. And when I click Login, we see here that we are logged in and we get our welcome screen. All right, so it works just the same way that sign-in manager does everything for us. It puts up the claims and everything. So you see here, we're seeing that username. All right? No, the logo button is going to navigate to the logo page, which then asks us to click here to login. So I'm just going to inspect this element and art well, sorry, instead of inspect in the element as jump over to the page. So on the logo page, what it's going to have is a farm. That's basically says goal here. And do a post to this area with the return URL of the page. Of course it's a post and what it says click here to login. So in other words, I'm sure you wouldn't want to necessarily say to our user, go to the logo page, then click here to login. If they click logo, do you want to lock them out? So what we can do is instead of taking that whole approach of navigating to the logo page, I can borrow this form, go back to my login partial, and then use this form in stead of the navigation element to the logo page. So this button, now we'll just see logos. So when they click that button will be actually submitting the requests to the logo. So I'll just remove that anchor tag that I had initially. And generally speaking, you will see this kind of form setup. So on the logo page itself, you have the En-Gedi which lowers the pitch. Sure, but then this is what happens when we click Logout. So the sign-in manager, ironically does assign alt, right? So sign-in manager is the library and cenotes async is the method that will know, okay, this is the logged in user killed local key, kill everything, and kill their session on the website. So it's similar or it does basically what we did manually here. All right. So that's what the Legos action come companies for us. I'm going to go back into our application. And this time when I click logout, it will actually just logos and let us know we have logged out successfully. So we actually don't even need that logo pH, because remember that these identity files are actually there, is just that when we want to override them, we can scaffold them and interact with them like we would have done for the login and for the register. Now after removing the logo file, if we jump back over to our login partial, we can retrofit this to look a bit more like what we could expect, how we scaffolded all of the identity stuff from the project creation. So generally speaking, you would have seen the injection of the sign-in manager relative to the governing user class, right? And yes, you just injected so in the controllers or in the page we've seen wholly do dependency injection. This is solely injected into a view. And then this if statement, instead of saying user.name identity that is authenticated and in Manager is user sanding. And then it would just take that whole claims object or user principal object, right? The red line is there because we need to do some view imports. And this view imports file is a nice global way to get using statements into your views and partials. So by putting using Microsoft dot ASP NET Core dots identity in the view inputs file. Anywhere that you need to have that sand in Manager, User Manager injected. It can be done without a mother, right? So if will go about to login partial, we see, okay, now we have the user out. So we can repeat that process for user where we go back to View inputs and this time we're adding the using statement for the namespace where our user file is located, and that is an entities and it's in the classifies data project. So once you do that, we'll see that user is no longer giving an error and I can build successfully. Now that's it for hold, the basic login functionality works. When we come back, we'll look at additional security and checks and balances that we can put in our own this whole process.
17. Handle Logout Flow: All right guys, this is a very simple video and it's just about handling what happens afterward logo. So we saw that logging India would just did that. We click Logout is going to actually go to our logo page. We don't necessarily want to just sit down on the page. The user probably has no interest in seeing a beard, seeing I love note. You'd probably want to navigate them back to the homepage. At that point, you would probably want to go ahead and scuffled the logo page. So let me just do that quickly. Ages. You scuffled item, identity, find logos and choose or contexts, and then add know when that pH pop surplus, just scroll down to what is happening in the on post. So on posts, we send all the user and then we check for turn your land. If one is there, then we redirect to that return URL. Otherwise, we read Erich to the page. So we keep on seeing the page instead of going to some other page cred. So obviously, this is coming back as no-no. If I jump over to login partial, we actually see in the form that we had put together, remember that we had converted that logo bought into a farm. And it is just submitting to that onPause method. It sending over return URL, which should be the homepage. So peculiarly enough, that is not coming back, but that's fine. What I'm going to do is just work our own. So remember we're controlling the flow anyway. So it's not behaving Hall we want what I'm going to do is just change all at what happens after logos. So instead of relying on a return URL that we know is supposed to be the homepage. Anyway. I'm just going to say return local redirect and then pointed to what I know is my home URL, which from this point would be tilde and then slash. Right. Now that I've done that, let us test it out and see what happens. So I'm here and I'm logged in. Let me see what happens when I click logos. When I logos, you see I'm on the homepage and I'm no longer allowed the right. So let's try that again. I'm going to login and then I went to go to the advertisements page and then I'm going to log out. So that means after a logo should know, see what's on the homepage. And there we go. So that's how you control that lava flow.
18. Implement Password Reset Functionality: All right guys, So we're back and we're going to be looking at the forgot password functionality at this point. So remember that when typically when somebody tries to login and maybe after they fail a few times, they're going to get frustrated and then they're going to want so far got fostered or reset their password, right? Of course, the verbiage here, you can change it. You can modify the login page however you want. But if I do click forgot password, notice that it will navigate to a page called Forgot Password. We haven't scuffled at such a page at all. But remember that all of the identity pages actually lingering in the button grown if we want to modify weekend, always scuffled it and overhead as we wish. But let's take a look at what happens out of the box. So forgot your password. Please enter your email. I'm just going to use the same email address admin at tes.com and then reset password. And all. The typical procedure for a password reset will be that it will send an email to the email address that you've provided. So if you bring up your paper caught SMTP server, or at least the SMTP client, then you'll see that we have received that reset password email from our system. So if we click here, it will navigate to another page that says Reset Password with that Tolkien code. This code, it looks very similar to when we had to confirm oracle bones. And then we would be able to put in the email, put in our password, and then hit reset. And then it will say, okay, it was reset. Please click here to login. Which point I should be able to login using the same password as I have been using or the same posture that's I just used. And forgive me, I forgot our using username and not e-mail. So let's try that again. We should be good to go. And there we are. Alright, so that is basically what we get out of the box with, forgot your password. Nothing too fancy, but what we're going to do is go ahead and scuffled it so we can at least see what is happening behind the scenes. So we know the procedure, new scuffled item identity. And after it's finished building, we go ahead and select what you want. So I want forgot password confirmation. I also want Forgot Password and reset password. All right, So those are the three pages that were involved in that workflow. Just know. So and I do all of that. She was a context. Then I can see my new pages appear. So let's look at what the forgot password does firstly. So it does take in the email sender by default. So because we have that implementation, we didn't have to even come around here and do anything else. It just knows what to do with the system is configured. So anywhere you need that email sender, you'd need only injected accordingly. So what it does on post, and this is me seeing that ESI wanted to reset my password and clicking these Reset, it will then see, check if this user exists in the system. So we're finding by e-mail if the user is null or if the user has not yet confirmed their email, then we're going to read directs to forgot password confirmation. All right. So this is basically doing that because it doesn't want to give you a clue that, you know, we know that you are probably trend the system because it could be that you erroneously put in their own email. But that means we didn't find it in the system or you are trying to forgot your password, but you haven't confirmed. We're still going to give you an impression that there is hope for you. So if the scenario is correct, There's really no hope, but this redirection suggests hope. So at this point you could make a decision. You could probably actually give them haptic feedback to see if you are attempting to forgot your password and you are not yet confirmed. Please go and confirm DCG e-mail and confirm. So these the user knows that Oh, I'm sorry, I missed a step and that's why I can't get into the system. So that's up to you. But that's just the default behavior. Further on though, it goes on to go ahead and generate the code. So this happens when we phoned the user and the system. We're generating the code. So you'll see that it looks very similar to what happens in that register. Confirmation bits, right? So it did generate the code on alterable. Look at the key difference here. Won the URL for this is Confirm Email, whereas the URL is for reset password. And another thing is that the Tolkien that it generates is password reset Tolkien. Whereas in the register it is generate e-mail confirmation token. Really pointing that one or two because I absentmindedly in the past are all tough ignorance. Copied the code from one and putting the other and could not. I spent an hour trying to figure out why this token code would not. Let me proceed in the system. That's because they're two different mechanisms through different hashing mechanism is used. So I just wanted to point that toe it in case, you know, you didn't really notice that before. So this one is e-mail confirmation and this one is password reset. All right. I'm sure there are others. If you just go to the use of manage or control space and probably stereotyping Tolkien, then you'll see all of the different options that might appear in the password security chain, GMail, changeful, number, et cetera, et cetera, et cetera. So based on the situation that you may need to generate a Tolkien code for confirmation, the more than likely will have one out of the box for you. Alright? So after it generates that password reset, Tolkien, it then goes ahead and generates that URL once again to the reset password. And then it dispatches that email tool, whatever email address is on that user's file, then it goes over to the password confirmation screen. So the password confirmation or forgot password confirmation rather, all that does is that you know, that check your email so you can modify that, make it fun, make it a bit more user-friendly. That's up to you. Once again, we're not focusing on the aesthetics, were just really focusing on the work floor off all our authentication bits and pieces. Then on the Reset Password, we have a form that asks for your email address, for your password to confirm your password, then the reset password after it has been submitted is going to see find by email. If the user is null, meaning we didn't find them. We direct them to the reset password confirmation screen. So once again, we're giving them hope so you can always figure out how you want to handle that, right? Otherwise, we want to find their record in the database and then reset their passwords. Is it that's so easy to use a manager dot reset, boss or the sink. We get the user, we know the token code based on the URL, and then we give the new password. And then once that is successful, we show the confirmation page. Confirmation page, of course, just navigate to our suggests that you go ahead and login. All right? Once again, you don't even need to scuffle these unless you intend to modify how they are laid out. And if you want to modify the workflow like we discussed for the forgot password. So that's really it for implementing forgot password functionality. And for me, the crux of the matter is getting that email service up and running ones that is there. You wouldn't even notice that things are just working harder. Suppose store.
19. Implement Account Locking: All right guys, So we're continuing our journey through the identity library and all that it offers us. And in this lesson we're going to be implementing that locking feature. Now this is a good way to improve the security by locking out a user that they enter is encouraged credentials too many times. And it's actually is a big hill by gains brute force attacks. When maybe an attacker has a username or password and repeatedly tries to get into the system with various potentially wrong passwords. So what we're going to do is modify the options here so we know that we have the options to enable password security. If we look a little further, we can add options dot Lakota. And then we can see is it's allowed for new users. What's is the default timespan on what is the maximum failed access attempts. So I have said yes, it does allowed for new users. I have the default time span to timespan dot five minutes. Of course, business rules will determine what you do and the max number of failed attempts is three. So after three failed attempts, we locked them up 45 minutes. And we don't care if you're a new user are not. So the option is there. But when I go to the login, you'll see that the code, our own hair is not complimenting the options. So in the sand in Manager dot password sign-in async method, you see here local on failure is by default, by the NO, this is what was generated, it set to false. So we need to change that to true to let it know that we want you to act in a strict manner. No, we can kind of beef this part of to maybe do a bit more. All right, so what do we want to do when the user is locked told? So at this point, if they do this three times, they are going to, the result is going to say lacO, this person, if they are locked totes is going to redirect to a local pH, which is probably just going to see high, you're locked out. Wait a few moments. We can always scuffle that patients see what is, what exactly is displayed on it. But without scaffolding it, what we're going to do is inject our e-mail senders. So the thing about it is that you do want to let your user know that they have been locked out. So we'll just inject I email sender. And the quick way to do this is just to put it in the constructor, then use Control dots, and then let it creates an assigned the fields and then follow naming convention. We will just use the underscore for the email sender. There we go. So then inside off, the result is locked, told we're going to have some CSV log that the account has been locked out. Then I'm going to go and find the user. So up until now we've always found user base on the email address. Now I can find by name, which takes the username that was entered, right? So if you hover over fan by name, you see that they want the username. So when we find that that user, we're not able to get the e-mail address. So that step is optional if you chose to routine that e-mail as the username and email address, if you chose a routine that they wouldn't have to do this extra step. But because we're logging in using username, at this point, I need to find what is that? I need to find the user records. I can get the email address to send the email tool. So I'm just getting my email sender, sending that e-mail e-mail subject and then HML message so that the subject is locked out, a cone information, whatever you want that's subject to B. And then my email says you have been locked out of your account for a two-minute invalid attempts. If this was not, you please reset your password as this might've been a breach. Of course, your message can be as clear as you need it to be to let the user know that this is what is happening to their cones. And then you can know redirect that user to the forgot password or bucks to the homepage or to another page just to see locked out, whatever it is, you can determine that full. So this is my flow. Just to give you an idea of the possibilities at that point. Now what I'm going to do is test this out. So on the login screen, I'm just going to butcher the password that I know. And while I'm doing that, I'm going to jump over to the database and I am going to look for the peanut users table. And then I'm going to scroll to the right where you will see local Lakota enabled and access field cones. All right, so that cone is supposed to increment with each failed attempts. So this is attempt number one. All right? And then when I refresh this table and then take a look, those you'll see here that the field current has gone up by one. So I'm just going to feel two more times deliberately. And let's see what happens. So this is me getting redirected to the forgot password. If I go back in the database and look, no, you're going to see that Maya Cone says that I have been lactose. So Lakota enable this, true? Yes. And I've been locked out because no lockout end has a value. So this value is basically the time from no, based on the time span that I said, which was what, five minutes. And then if we check our SMTP server or client or other, we'll see that we've got the email saying that there hasn't been a breach. Of course, for this now we could actually just do the whole Forgot Password, Generate the link and send that link over in the password so that the attacker may get redirected here. And even if they tried to put in the email address again and submit, at which point we're asking for the email address, but they have to login with a username. So whatever it is, however, the dynamic that attacker is stopped right there. They can't proceed with anything. But then the user would actually get the emails to say reset password or as I said, this original one seeing follow this link to reset your password. How do we put that in? So at this point, they can always do all of that and be able to manage their own destiny. So those are little ideas. Once again, I'm just showing you what the system is capable of. The actual implementation is relative to what your business needs are.
20. Implement Two-Factor Authentication: All right, so in this lesson we're going to be looking at enabling two-factor authentication. So two-factor authentication in most systems, at least that this time is really optional. Some cases make it mandatory at this rate, or at least out of the box, we can make it optional for the user. And they can go in and money their user account and enabling or disabling that will. So the first step in our stake in this movement or making this movement is to set up the link to go to the Manage page for the user. So the original euro that was just a URL seeing welcome. The username will have no retrofitted it to C is B area identity go to SBP, a co-owned manage index, and the title is mileage. That's fine. And then the texture means the same. So let's see what we get when we do that. So after logging in, we can always just click on the admin, know that it's a URL and we would be navigated to the management, let's say a management panel for the user. Of course, he can scaffold the speeches and to know what to scuffled, you need only look in the URL to see what the page names are. All right, but when, when he scuffled these, you can modify them so they can allow the user to be in charge of their own profile. At this point, they can update their email, they can change their password at will, and they can enable two-factor authentication. And this tab actually allows them to delete their own are columns. All right, so you can allow them to be able to do all of that or you can restrict them as you need. Now let's go back to the two-factor authentication page and click on sit up authenticator app. And now we're going to be presented with the instruction. So this is what the user is seeing out of the box. The identity we'll work with that two-factor authentication given to us by Microsoft Authenticator or Google authenticates are both available for Android and iOS devices. Now I already have the apps on my phone. So if you wish to venture down this road and much further than I suggest, you go ahead and get either one for your phone. The next instruction would say scan the QR code or enter this key into your two-factor off. And then they will navigate to do some documentation on how to get the QR code working. So we're actually going to do that together. So the documentation for me is quite straightforward one we have to get this library into our project. So if I click that link, will see that we get to download that library. So go ahead and download that. And then in our project, we can jump up towards the root. And in our folder, I'm just going to create a new directory and call it a liability. Of course it can be more specific. And we're going to drag the two JavaScript files into the library folder. So we need QR code dot js. And if you drag the other one is just the full version of the minified, right? So we have QR code dot js. Then we're going to take this JavaScript file or this code here or there, and create a new file called QR ab.js in the root JS folder. So I'm just following the instructions as Microsoft is telling me, I'm not doing anything, all of the art in area here, but we're doing this together. So new item, I want JavaScript file, which will be found on the web, a little, or a JavaScript file. And I'm naming it as they suggested, QR ab.js. And then we paste that in that file. Now, after we've done all of that, we're going to find the page that is displaying this torus, which is the enable authenticator, which clearly means that we have to scuffle that page. So no, I went off to jump over to our cones, go to add or you know, the routine already go to identity. And we're going to look for the page, a colon slash, slash enable authenticator. And like I said, many pages as you may want to interact with, like 12, maybe I load them to disable it. If they can enable it, you probably want to allow them to disable it. And then you'd probably want to manage our change the index with the navigation properties, you know, stuff like that, whatever it is you want to do. So I'm just going to go ahead and include those three. I might not interact with all of them, but let them scuffled. Then we will get a new folder with all the new files. So I'll jump over to the file in question. And underneath this scripts section, we're going to add the new paths. So I just copied this from Microsoft bulks. Let me just make sure that my paths. So that is slash lib slash QR code and I'll just use min. And then this one is slash js slash QR. So you can always use Control Space to get this additional under it. So now that we have all of that setup, let me try and load that page again. And would you look at that? And all we have a QR code being displayed. So of course he can modify the page and remove that hitting because we no longer need that and we would want to tell the user that. So I'm actually just going to scan the QR code right now with my phone. I wish I could show you that on in both. It is happening. No. And then I can put in the verification code as it is on my phone and verify. And there I go. So now I have enabled two-factor authentication for this particular user. Our cones know these recover quotes you would probably suggest to the user or as you see the notice, please keep them safe because if the opposite working, you need to get onto the system, you can always use these recover codes to get to access. Now I'm, it's all of that. If I look in the database and look at that user's record, I will see that the two-factor enabled flag is no set to true. So that means that when we go back to the code for the login process, there is something that is going to happen when we successfully login. So this means we have successfully logged in. And then this is going to see if it requires two factor authentication, then redirect. See that? So no, the result won't come back. I succeeded, at least not the first time he'd steady will come back as requires two factor authentication, which will then send those to this new login page. Login with two FA, which we didn't scuffled. We can scaffold, but let us see what we get out of the box first. So I went to load, load and try to login again with the same user. Click login, and then you see it is no navigating need to the new page login with two FA asking me for my Authenticator quotes at this point, I or the user, as, as you know, the context will determine, would now put in what is being displayed to me in my Authenticator up. So I'm putting in my code and I click Login and there I am logged in. And just like that, we have two-factor authentication enabled. Now, this process is relatively simple for somebody who is tech savvy. So you may want to think about the best way to enable something that is in your organization. But the whole point of two-factor authentication is something you know, and something that you have, right? So something you know, would be a username and password that's standard, but then somebody else could know what you know. However, the likelihood of somebody having what you have is even more greatly reduced because now this device is more in your position. Of course, it would take a lot more effort for somebody to be able to access Sarah Colin's because of the disparity between the two points of contact. It's not foolproof, but it's another level of security and complexity to the login process that you may want to consider or reconsider based on your audience. Always remember that more security that goes in means reduced usability for some people. All right, so sometimes you have to find that balance between usability and security. With all of that said, what are your business rules? Make sure that you're making the best decisions for yourself and your users and for the longevity and security of your application. That being said, if the user goes back to their manage bids and clicks on two-factor authentication, then they have the option to disable to FA. And that would reset everything. And there would be back to needing to set up everything from scratch. So, you know, you give them some amount of power and they allow them to moneyed certain affair as well. Once again, find that balance between usability and security.
21. Section Review: All right guys. So you've hit another milestone. We looked at quite a few things. One hold to get their own that scaffolding error. All right. I hope you don't want to encounter, but at least we've gone through it so you know what to do. We also looked at scaffolding more pages and replacing our own custom code, especially the login code that was only designed to look forward to seeing with the scaffolded or the Alt of the box boilerplate code that those far more complex things, but using the third-party libraries that are very powerful. So you see that the login page is using the sign-in manager and it has all of these other options and we beefed up some of them like with the lock tote, I went back and added more CO2. It's a can hit pause and replicate if you want. But I put in the link to the password resets in one go so there'll be navigate, they'll be prompted to reset their password via their email. All of these wonderful things. We also looked at scaffolding more pages, customizing them, looking at what each bit of code is doing and once again, understanding how we can modify them based on our actual needs. So what I'm going to do is remove our original auth pages. We don't need those anymore. Those are things of the past. And now we have more robust code and far more secure code handling our operations. We also looked at whole weekend extend the identity functionality pipeline. So we looked at the built-in options, yes, we added more for the local mechanism, but then we added custom password validation and we looked at the file. We can add more custom functionality as we need to. And basically whatever it is that you add as something costume. So if you added, maybe let me just see validator. So if we added role of validator, then he would actually tell you that you need. And I rolled validator C will always let you know what interface the custom class that you're going to create needs to inherit from. So you can properly in, lamented, right? So in this case we put in password validator, or I call it the password valid data service. And it's just inheriting from i password via the data. Yeah, if I roll validator, right, you have I, this validator I, that. So you have quite a few options. And based on your scenario, you can just use that interface, implement the method, and put in all the logic that you need to accomplish your business rules. So with all of that said and done, what we're going to do now is check in our code. As usual, we make our message as clear as possible and then we're just going to go ahead and commit and synchronize. And I'll stick around. We're just going to get into more meat and more concepts are on whole weekend secure or application.
22. Section Overview: All right guys, welcome back. I'm really happy you're here. It means that you're committed to understanding WHO authorization and authentication work in dotnet Core applications. Now up until this point, we've already kind of looked at some amount of authorization where we looked at the photo. You can actually just put that HTTP filter right above your page or your action, or your controller, or even your components based on which flavor of dotnet Core application it is you're using. And by just saying authorize, you will be foreseeing any body who is trying to access the content at this end point or at this location to first authenticates before they can proceed. So if we wanted that's on every single page. We already know that we have that configuration that we can put in the startup. It looks slightly different if you're using an MVC application. But it pretty much is the same thing where we just force that author as filter on every single location in our application. We also looked at the fact that if there are particular locations that we want to leave the open not requiring authentication, and then we need only floodgates with the allow anonymous. And these would probably be fewer than the number of locations that you want to own. So for me, it's always easier to just do it globally and then put in the exceptions. So we've already looked at those basic things, so we're going to kind of review it in the next lesson. But for this entire section, we're going to look at all of the capabilities because you have the basic authorization, which is what we have looked at and would review. You also have roles, you have claims, you have policies. We're going to look at all of those things and how they can combine to make a very secure application based on your business needs. So stick around. We have a lot to explore in this section.
23. Implement Basic Authorization: All right, so we're back and we just want a quick recap of authorization part. So in the review, just know we looked at the different flavors that we can do in a Razor pages application, what extension or dotnet Core application where one, we can set it globally. And if we don't want to sit that globally, we can always go to the specific page or the code behind off that specific beads. So this is the index page of the categories. And I can say author I. So in this case I didn't authorize explicitly. It's already set globally ports. This is a category, so you would want to authorize this because you probably want this to be dedicated to what administrators in the system can do as opposed to regular users. However. So right, no, it does alter as because of the global filter. And if I wanted to explicitly do it, we just say author, authors, that's fine. But then if I want to globally authorize and then exempts like we did for the index page of the advertisements. That's because I regularly users should be able to come to my classifieds websites and look at the list of advertisements without needing to authenticate. Maybe if they want to create one, then I would want them to authenticate at that point, I don't allow anonymous. So you have to authenticate, sign interior cone, then you can create so I know who you are, right? So those are the kinds of decisions that you need to make. But then in addition to all of that, because we kinda looked at all of this at the basic level already. I want to show you some examples from MVC apps and blazer ups that I have built in the past. So I mentioned that it might look slightly different because MVC, they use views, controllers and models. So the placements of these authorization tiles would be in the controller. And it's kind of a bit different from the page because the page yes, it has on Git and it has on post and you have what you call a handlers. But all of these are relative to the page. So it's not like I can authorize the En-Gedi. Tried to author as on gets here. And then not authorize another handler. It's either authorizing the entire page or I'm not. So if I try to offer as just the handler you see here is going to flag it and say, Well, this cannot be applied to the handler. It has to be applied globally. So it's either you have access to the page and the hundreds on the page or your bones. So that's all MVC sorry. That's all Razor pages with a handle, that's all authorizations scenario. However, here's an example of an MVC app that I had done and actually do this one in my course, complete ASP.net Core and development into different word developments, right? So in that one we do well through authorization just not as in depth as we are doing it in this course. But you will see here that this is a controller and a controller has different actions, right? So each oxygen would have a view. I'm just going through this in case you're not very familiar with MVC. So each controller would have an action and the action has a corresponding view. So if you look in the views folder, you're always going to find, or you should always find a folder with the same name as a controller. So this is home controller. Here's a home folder in the views folder. Then the index action, there's that index view that goes with that axon. So that means that a controller has access to multiple pages at a time. I can choose to authorize all the pages that might be associated with this controller. Which means that just by me saying author as you have to log in to access the index page, the privacy page, and probably even the arrow page, right? Any page that is any action that is here that has a page or a view associated with it is automatically authorized by my doing this. Now, if I wanted to not authorized entire control about authorize maybe just a particular view, then I can just put that flood directly above that action. So that means that no index requires authentication. What privacy and error do not. That's basically how it works in an MVC application. So even if I said allow anonymous, this entire controller, then this author as with override their low anonymous for this particular action, right? So anytime we go to index, you have to authenticate. But because of the low anonymous evenly, there was a global author as filter. Then. This would allow the home controller to allow anonymous users to be able to access it. So that's basically what it looks like in an MVC application. I don't know if, you know whichever one you prefer, whichever model you prefer, they're both pretty much the same thing. You just have to appreciate the nuances so you can operate properly? No, the next example. Comes in the form of my blazer up. So I do this one. This is a bookstore API where I do this one in my speed on a core API and blazer course. So in that course we do go through API development. Sure. And but then you realize our API development is 12, just like MVC where you have your controllers and you can flag authorized directly above that API endpoints, right, or above that entire controller, or above that behavior or action, just like I depicted in the regular MVC applications so that you can run a parallel between an API and an MVC application as to how you handle authorization. But then in terms of the blazer, when you are in the components are at no, I'm in that component that loads the authors. Inside this component, I can put you in an attributes at the top of the component that says author. And so this, and that's what I was saying. It looks basically the same in all of the dotnet Core application. So let's look a few nuances. So here I would actually be seeing it inside of the component itself. And the component is pretty much hybrid of yeah, HTML markup or RAs, Marco, brother and C-sharp. That's pretty much what our component looks like. So in case you, you're not necessarily familiar with it. This is what it brings to the table. So right here I can see that I want to authorize this components, meaning if you try to navigate to it, you have to log in. Another cool thing, a boats blazer and something like this is available in the dotnet Core applications as I raise on NBC. That is we can Who's the authorized view? So here I'm just seeing authorized view and I'm specifying that if the person is of the role administrator, then they can view this. That's pretty much all that. Does. We do something similar to that in the login page, not the login page in the login partial component. In our Razor pages upward, we say only display certain things if the person is logged in or if we know we can extend that. We can always say if the person is in our role or something like that, we can do those fancy things here. So I'm just showing you the whole authorization is kind of, it differs to very minute extends between the different dotnet application templates. Ultimately though, once you appreciate the thought that once you put authorize or you put that global filter, then everything needs to be authorized. Then you are already on your wheat on the standing authorization. Now what we want to do is take it a step further. So you would see here that this is specifying what we'll call a roll, right? It's saying roles equal administrator. I can bring up my leave management and I can show you to the in the, which one is it in the leave allocation. It is automatically authorizing only rules for administrator. All right, so there are times though when you can't actually specify that I want to authorize only this role for the control or these actions, or in our case, these pages. So in our case, we want to make sure that only administrators can create categories are interrupters categories. But then anybody a regular users should be able to interact with advertisements. So that is our next mission. So when we come back, we'll get to understand how rules were coal. We add roles to users and how we use that to enforce what they can and cannot do.
24. Add Roles To Users: All right guys, so no on to discuss roles on how we can implement rows in our application on unholy goes up, it does help us. So our role is basically like a permission. Like what is your road in your company? Are you a boss, Are you a worker, et cetera, on based on your role, you can do certain things, you do how certain privileges, et cetera. So just like that in real life, we want to replicate that kind of strictness in our application. When we talk about ascending rules to users and making sure that they cannot do certain things. So the easiest way to get directly into the system really is to seed. It's because generally speaking, when you start creating an application on, you have the foresight to know that these are the rules that might be used? Yes, Later on he can look into managing them through our user interface. Bullets, right? No fraud to get cool, we're just going to try seeding them into the database using Entity Framework and how it those seeding or ED. So inside of configuration already have two configuration gases where we did seeding. So I'm just going to replicate this kind of construct with the rules are, and so I'm just going to add a new class. I'm going to call roles seed configuration. I'm just going to seed configuration because that's all I'm really going to use it to do. And I'm going to let it inherit from I entity type configuration of identity role. Alright, so you may need to add some using statements after that, but then we need to implement that interface. So notice that we're using identity rule already looked at the photo about entity user identity, Rhode, et cetera. If you chose to override this as in, you are using your own type of role type just like overall the user type, then you can always replace identity roll with whatever role-type you created after the fact. So null inside of the builder, I'm going to have two roles, customer and administrator and all. You're looking at the code that's on my screen and probably wondering what topic. That's fine. Let me explain all lattice happening here. So we already have the template for how we do the CD or as we say, a builder dot has data and new object and then we fill in the pieces. So here we have built their data's data new identity rule. All right? And then we fill out all the fields are at least the fields that we deem absolutely necessary. So you have concurrent system has another field, but I don't really need that one in this situation. So identity rule, ID is equal to, I just went on phoned up good because they use void as the primary key in the identity tables, right? So you can just go and find a good and use that. And I literally just changed a few characters in that same good so you can replicate it. That's how you can use your own good, that's fine. It's a blank table, so you have the luxury of putting in what you want. Also, this table doesn't necessarily change much, so the likelihood of crashing later on is greatly reduced. So I have that. And then in name, typically it I mean the name is a string. You would have had string. Maybe you say customer. Once I don't want to do though is to write all this static string light, that's our magic string. So to reduce that, what I did was create another folder called constants. In that constants full of added a file called a rule and then roll. This guy just has constants, strings. So as many rules as you may want to just have matching names and the actual value say of that magic stream once. All right, then later on you just for reference, it's so name is equal to rho dot costumer, which is going to return the static string customer normalized name. Basically it's the capitalized version on, off whatever name is like we saw with the username and the normalized username or e-mail and normalize e-mail in the ASP NET users table. So normalized name here, we just see, Give me about the customer, but put it to uppercase. That's much cleaner, I think, right? And then later on, we do the same thing for the administrators. As many rules as you need, you can replicate these steps. Now the next step is to do RMI grayish on. So you have to remember that we need to update our application DVI contexts to let it know that it should know how this seed my configuration on null. You may have multiple seed configurations going forward because you may want to see the user. You may want to seed the font that this user is associated with this rule and you may end up with many configuration files. So what I'm going to do is reduce the individual lines and replace it with this one. Modelbuilder dot apply configurations from assembly type of application, DVI contexts or whatever your DB context and aim is, not to assembly. So this is really Spanish, quote unquote four. Look in the current assembly that the DB context is in and get all configuration files that are associated with. That's pretty much all it's doing. All right, so automatically just scan through and find that all here's a configuration file that's associated with an entity that I know off, et cetera, et cetera. And with that one line, you just automatically apply all of those configuration files. So let us know, run our Migrations. I'm going to add rural seed migration, which then as expected, gives us this migration file stating that wearable to insert values into our SBI net roles table. All right, so this is our ID that will put in and then it automatically did the concurrent system and the name Ministry Peter and customer. All right. So with that done, we can do an update. And no, we have successfully updated the system. Now at this point, you want to probably have an administrator in the system separate from the users or anybody who registers normally should be a arugula user, our customer other, and then we controlled administrators. So based on your business rules and your strategy, you may have to employ different ways of doing this. So generally speaking, you'd want to have a system admin. So we already have some users that we already named admin. And I'm going to show you exactly how you can associate them with our role in the database directly. So this is kind of Manuel and then we'll look at how weekend seed customer. And then further by extension, we look at how we can set the rule once the person has registered. So let us start off with the ISBN that users table. And we're going to be looking at the ID for the rows. So ASP NET rules and SBI net users. So we'll look at the data for both tables. We will see what we expect, right? Administrator versus the users. So there's another table here and all which is a many-to-many relationship table or a linker till between the users and roles called ASP NET user roles. So this one actually takes the user ID and the role idea and says these two I associated thing is that a user can have multiple roles. So it's not that one user has to be only one or the other. It can support multiple. But that's once again, is up to the discretion of your business needs. So I wanted to take admin test this user. I don't want to go into user roles and I'm going to say that this user ID, then I'm going to go over to roles and I'm going to take that Administrator ID and I'm going to say this rule ID. I, once I do that, off the butt null. The admin user is seen as an administrator to our scene to have this role in our system. Well, it's up to us to say what this role can and cannot do. But as far as the system is concerned, that user has that role. It's that simple. But symbol doesn't always mean practical because there is no user that's going to come around here and do this. So lets us jump over to watch really expected to happen in the system. So when somebody registers that, I'll just close all tabs. When somebody registers is when we need to associate them with the roll part. So back to the register page. What we're going to do on post is if the creation of the user was successful, then we're going to have to add them to the rule. So we can say login information created new user, a call with basilar, that's fine. Underneath that log, we're going to see a weight user manager. So we are to have the user manager, We know the, the existence of your polarity. And then we're going to see a dot. And if I just type in rule, you're going to see all of the potential things you can do with the user monitor relative to the rule. So you can add to roll. You can, sorry about that. You can get roll, get the users in a particular rule. You can check if our users in a rodeo, so many things. All right, so in this case we want to add to roll, so on to alterable a sink. And then this takes two parameters, the user which we just created and the role. And I'll yes, what I can always type administrator, if I spelled that incorrectly. At that point, I would be debugging for awhile wondering why this thing won't work because I probably missed old and I, and I'm oblivious to it. Maybe somebody else will come and see you misspelled it. So I went to say roll, which is our constant cross and I'm not seeing it. So let me jump back over here. All right, so fewer and flaws and I'm just going to carve it myself. If you saw the IRS before, then that's fine. One, I need to make this public. I did not make it public. And two, that the filename is rules. The class names should also be rows. All right, so let's try this again. So roles, and if I Control dots null, we can get its right. So roles, dot administrator or customer. So I can say add two rows and the rows, customer and I think that's more readable, That's compile safe. Of course. So there's no mistake regarding the spelling or any ambiguity regarding which rule is being used here. Alright, so let's make a quick test and register a new customer. And I have a few errors. I need to start just with the spelling here. So I'm registering this new costumer. And once we hit this speech and know that it is working. So if I jump back over to the databases C1, we have our new customer here, customer. And you see the ID starts with 22 a something-something. Whether that good is, if we look in the user roles table, I remove the earlier one that we did. No, you'll see that we have that customer, so we have that customer ID, as well as the role ID that corresponds with the costumer role. And that's pretty much it. So no, everybody who passes through this particular authentication, sorry, this particular registration process will always get added to the customer. Now at this point, you may want to consider, you know, if you want different or you want to allow people to register as different roles. Because you do have that at times in systems that could serve on boarding. Maybe your role could represent that department, right. Or something like that. So you want to use it to identify which department they are, which role they wish to have in the system so that when there are just the use that particular role. At that point, you start wanting to look at the role of manager, which allows you to interact a bit more with the rule is stable. So you can always just like, well, you have the user and descending managers, you have rural and manage or relative to identity role or whatever your custom class is. And then he can just go ahead and inject that into your registration page. And I'm just assuming at this point that you already know how to set up like a drop-down list and all of those things. So I'm not focusing on the UI apart. So what I'm trying to 0 is that you can actually setup your role list here as a new selects list. That TX role of manager dots. And then he can just get the roles as a list of rules right there. And you can put it to list if you want, you can filter by. It's at least offer was coming from the database. So if you're in, if you're in tune with how to manipulate lists using linked and extends on methods, then it will be the same principle here. So you could do that. And then you have the name as the field that is to be selected and the name as what is being displayed. And right there, you would be able to list all the rules to your page for your users to be able to select which one they want. So to put more practicality on that suggestion, what I've done is to modify the input model. And I've added a selected property, four rolls and one for the required role. So they have that identify which row they want in order to submit successfully. We know about that's already right. So in the fgets, I'm going to say input, which is the object of input model that the pH will use. I'm initializing it to a new instance where rules will be equal to a new instance of the role, manage adult roles. The dot getting the name as the selector, the selector value, and the display. In C-Sharp in the latest versions of CSRP can actually just say new, just say what I did here. Instead of saying new input model, again, the sin you, but sometimes for readability I still keep it. And although times adult necessarily use it's because the constructor might be implied. That's besides the point though. So we want to make sure that we have that there and then don't where we add them to the role instead of hard-coding the rule, we're going to take the role that was coming from the input. All right? Of course we have to repeat that assignment of the rules list if something feels so that the pH can reload the list successfully. So let's see what that looks like. So on the Register page itself, all I did was add select tag. All right. Form control gave the items coming in from the input dot roles list and it is for the role. And then it has a desire that default select desired roll and it's not listing the rules coming from the system. All right, that's simple. So if I'm registering as a customer and a customer one or let me register as an administrator. And I'll see Admin one and fill this out. And then I hit register. All right, So we hit the confirmation page and if I jump back over to the project and look in the users table, we see that we have admin 1 and id 0, 0, 1, b. Say if I go over to the roles table, now I'm going to see that I have 000 001 BE. And this is the admin ID can cross-reference it if you wish. But my point is that, that is how you would get the user to select their own rule and onboard themselves with a particular rule. Of course, once again, you can always manipulate that lists. So if it is, I have the administrator role and other user-based the rules, but you don't want people to select administrator then you just excluded from that list when it is being loaded. So with all that said and done, that is how you get add rules to the users. Know, when we come back, we'll look at how we can restrict what certain rules can and cannot do.
25. Implement Role Based Authorization: All right guys, so in this lesson we want to look at how we can know start implementing the rules and restrictions based on the rules in our application. So right now I have a pore sites and you can see I did her little face lift to the front page. Just a little informational stuff. But if we look at advertisements and our categories, we see that categories is requiring authorization or authentication rather, whereas advertisements is not. However, on advertisements, I can easily common edits, look at the details or delete an ad, right? So those are little things that of course, would be red flags in any system. And you want to be able to restrict what certain people can do. And we're certain people can go because at this point, I can get in here as the customer and still be able to manipulate all the categories. So we wanted to make sure that the access to the categories is restricted to administrator users only. And we would probably want to hide the ability to manipulate the advertisement or at least edit or delete an advertisement or only administrator users. So one modification will help us modifying the code behind file for there is a page is page, which once again could easily be the action or even the razor component. And the other one would have us modifying the actual rays of page, which would be like for like with the MVC application on a resume page. And pretty much the same thing for a blazer component. So I wanted to start off with what I think is the lower hanging fruits, which is modifying the code behind. So all I want to do is make sure that when the person who tries to login, when they come and try to login, they have to be an administrator. All right, so let me logos and I'm going to jump back over to our application code. And all I have to do really for the categories is specify author as so we still have to go back to our author as filter. But then I'm going to let it know that the role, so you'll see here that you can specify the author has attributes with Wanda authentication scheme. So you can restrict it if it's cookie or if it's not cookie, allow or disallow, et cetera. I can specify a policy. We'll be looking at policies later on. And I can also specify the roles. So notice its roles, right? So I can actually see that more than one roles can access a particular area. So when I say rules here and say equal, I would actually give it a string. Now this string would be like it would take a comma separated list, says here it gets us. It's a comma delimited list of rules that are allowed to access the resource. So if I wanted administrator comma, customer, coma, grow one comma rule to as many rules as I want to give authorization to a particular resource, I can just comma, separate them all over the discourse. The danger of the magic strings and writing them in like this. The, of the matzah those most times you will actually just see it written. Now in this situation, I want only the administrator to be able to access the categories. So I know it's only one. I can now just say rules, which is my static class. And then say administrator. And then for as many other roles are Xudong, we just have to concatenate the strings as we go along and piece them together. More advanced methods would include creating a customized authorization filter, which we can look at later on. But right now I'm just keeping it simple and showing you how you would authorize for a particular rule In set of your application. So right now if we navigate to the categories page and try to authenticate as the costumer, then we're going to get this access denied page. Now this page we didn't create, it's once again one of those pages that we can scaffold and modify if we wish, but it is there in the identity slash cones slash access denied directory. All right, So while we did authenticate as the user or as the customer in this situation, we cannot proceed to this particular resource. However, we can go elsewhere as an authenticated person just not to the categories page. So as many pages or actions or controllers that you would want a lot don't. You can add that authorize with the rules specification there. And not when I try to do the same thing with admin one, which is a user that we just added through the register. Let it let the users their own rule. We can now access categories. Alright, so that's how that works. Now, let us jump over to advertisements. So yes, we would want advertisements to be open to the public. However, I only want customers to be able to create new, and I only want administrators to be able to edit or delete. So regular people can come and view the list of advertisements. They can click on the details. Sure, but only fewer are an authenticated user would allow you to create your own. I don't even want an admin to be able to create their own. I want customers to be able to create their own ads, and I only want the admins to be able to edit and delete. So on the index page of the advertisements, all we're going to do is modify this section that displays that create new buttons. So I'm just going to say at sign if user dot. So remember that a user represents our user principal for the logged in user, right? So I'm just going to say if user is in roll, there we go. And then here once again, we just type the name of the role which we don't necessarily want to do. We would prefer to use our constants. So roles, I would need to include that namespace in the view port. So I'm just going to say that namespace don't but bone to the view imports and then add the using statement for it. So anytime you want to use our class or anywhere else inside of the views, you just drop it in view imports or you can always drop it on that particular page. So roles, dots. And I want to check if it is a costumer. Then display that, Create New, and I'll just fix the formatting here. All right, so I want to display this only if the users in the role of costumer. Similarly, for edit and even delete, and you can modify this. I mean, I could write two statements. I don't want to write two statements. I'm just going to move details to the top, and then I'm just going to have one if statement, if the user is enroll, and then we're checking if they're in the role of administrator, then we can display these two links to them. All right, so that's it. So you can start modifying what certain users see versus what other users see. Say everybody's authenticated, some are knots. In this case, the person is looking at this advertisement are not bought. Let me just start that from no. Right? But if you are authenticated and in a particular role, then you see some of the infrared admin your own see that what you see this, alright? And if you are neither, then you won't see any of that. So let us take a look at what we get after these months. All right, so I'm navigating to the advertisement speed as our regular person. I'm not authenticated in any way, shape, or form. I'm seeing the list of us and I can always navigate to their details and that's fine. That is the expected outcome right? Now if I register our login sorry, as a customer or I navigated their while being logged in as a customer, then I will see that I can go ahead and put in my own advertisement if I want. But I'm still only restricted to viewing the details of other ads that other users might have created. Now if I go in as the administrator, I will now have the power to manipulate those ads. So I can always look at the details, yes, but they can also edit and delete them. But I cannot create one as an administrator because that's the system rule, not a customer roles. So once again, I am creating my own business rules for these scenarios, but I'm just giving you their ideas as to how you can implement the required or security protocols that we'll go over in the system in your organization. This is how it's done at the most basic level.
27. Access Claims In Application: All right, so let us discuss setting up claims-based authorization. So remember that we just went through what claims are. Claims are bits of information about the user who is currently logged been. So the more claims that we have available to us are, the more decisions that we can make to know if we should allow our restricts the user from a particular resource or endpoints. So what I'm going to do is work with the create page for the advertisement. Let us see that no user that is under the age of 18 is allowed to create an ad. Alright? So you shouldn't be able to create an advertisement unless you are minimum 18 years old. Now we already know how we restrict them using the authorized flag up top. And we're going to look at is policies, but I want to show you different ways they can actually interact with the cleans. Because we did see that you can access the cleans instead of needing to hit the database. So what if you needed to access the claim? Make a decision based on that claim, whether in this case it's the, you know, show them access denied. For instance, REO some other business rule that you need to implement what we just want to know what the value of the claim is. So let us say that I wanted the minimum age of the current user. I can start off by saying var is minimum age is equal to user, which represents the user object that claims principal object in the HTTP contexts. So user dot find first. Before I even show you the fine first if you say user.email actually see claims coming opposite. You see multiple identities you can determine is in roll. You can see claims, et cetera, et cetera, et cetera, right? All of those are available to you. So if you do claims, claims is really just a collection of the claims. So you could actually use this to say, first our defaults are just query it, interrogate the list just the same way you'd have interrogated something in the database. I could say Klimt for as our default lambda expression q dot. And then I could find that that's I want, right, is equivalent to, so the type here is a string. And then that's why we have our user claims constant class. So I don't have to type over those static strings all the time. So it will say user claims that his minimum age. And then after I get that, this would no be a claim. So of course, getting the claim, I don't know if it would actually exists. I'm just going to do question mark dots. So that's my null coalescing where it would say, If it doesn't exist, just return null, otherwise, attempt to get the value if it does exist. All right, so that's one way of finding the minimum age. So you see here we can interrogate the list of claims just like we would any other list in C sharp. Now an alternative to this would've been the first one I started off with, which would be the find first. So user.name find first. And then inside of that, we could actually just put in the string represents that claim. So find first takes the type as a parameter and it just returns null if no much his phone. And then the return type of course is still clean. So that means I would still have to try and get that value. Of course that value is going to be string, so we still don't have that as a Boolean. So that's another thing that you would have to consider. And although thing too is that this find first method could also take a lambda expression similar to what we did with the fine first. So I'm just showing you all of your options is good to know your options, but of course at the same time is good to settle on a standard so that when everybody has to work together, everybody's on the same a quarter, right? So these are different ways you can use to access particular claim and then the value that they scream has. And then of course, based on the data type you're expecting or that you need to process, then you have to do your conversion. So what I'm going to do is have this if statement that says if the minimum age is equivalent to null, meaning that clean type probably does not exist for this user. Or if after parsing, we get the value of false, then we want to redirect to identity slash our colon slash access denied. So access denied is a pH that is available to us through the identity suite of pages. Of course, if you add another piece that you wanted them to go to, you could just read them there at that point. So that is all that we're doing. So let us run a test with our customer who we know is on the 18th. So after logging in with customer under 18 and then trend to create new, we see that we are no redirected to the access denied. You cannot access that as you are under 18 years old? No. I'm trying this again in debug mode or the same user, I just hit up breakpoints are put a breakpoint rather on our if statements so that we could stop. And I can show you what's really happening behind the scenes. So we have our user claims principle. If we extend this, we see that we have all the claims. If we look in the claims, then we see that we have the standard ones that we know, and then the custom ones. So the minimum age is false as expected. And so when we get to this point, it says false, so we don't even have to check for it to be. So that knowledge check was really me be overly cautious. But at this stage, given that we are controlling what claims go in, That's what we did in the last lesson. At no point should I use a login without the particular claim, right? So unless something changed the entire system. And that's why we have light regression on testing and unit testing to make sure that these things don't happen, right? So if it is the minimum edge, I can actually do with all that. But after parsing that string, we check if it is equivalent to false and it is so then that is why we go to the Return redirect. So you can go ahead and test that patina user whose date of birth would put them beyond 18 years-old. And then try this scenario again and see what happens. So that's step number 1 of how we can use claims during the runtime of the system. When we come back, we'll look at how we can implement policies. So, well, of course it would be kind of difficult to be putting this kind of logic here, there and everywhere. You would necessarily wouldn't necessarily want to do that. So we'll start looking at policies that we can use nano to enforce that particular claims must be present and probably can even extend it to C, must have certain values before these users can be admitted to certain places.
28. Implement Policy Based Authorization: All right guys, So the lesson we're here, we're discussing why it is not practical to have this kind of logic all over the place anytime we want to enforce certain restrictions based on claims. So in this lesson we're going to look at this construct called policy. So that journey starts off in the startup dot CSS file where we have to add authorization to our service, his Batman. So I'm just doing that right after the add default identity and read before the arteries of pages authorize filter. So I'm just saying I'd authorization and then the options I'm feeding into it would be to add up policy. And you'll see that I have policies dot is minimum. So we look at that in a few. That's just another constant that I created. So you can just go ahead options that ad policy, policies dot is minimum age. And then we have a lambda expression where we see policy require claim, and then we have our claims reference to that is minimum edge and then the value that we expect. So the general syntax for adding up policy and adding the requirements to set policy at the most basic level, something like this, right? We're just opening up an options block. We see options dot add up policy. We give the policy a name. So this could easily have been aesthetic stream. All I'm doing really is referencing constants string from a class called policies, the military arrangements with the photos also. So remember that originally our user claims class, which is our static class with all of our constants, strings are originally, I had it on other services, But no, I want more constants of a similar nature, right? So instead of putting them all on the identity of moved it to its own folder, change the namespace accordingly also, no, it's constants and then user claims, and then we have policies joining it in that namespace. So policies is just going to be stored in the name of the different policies that we want to enforce across application. So in the startup I'm just referencing odd policy, policies. Dot is minimum age, which is a string minimum age. And then I'm starting up a lambda expression where I'm seeing that these are the options are, these are the configurations for us in policy. So here I'm seeing Policy dots require clean with this name, which is minimum age. And the value. And the truth is that you could actually list out potential value, so it doesn't have to be one file. You could just come to separate the different possible values that this cream needs to have in order for that user to be seen as legitimate candidate to carry out a particular action. Now what if you wanted more than one claims in a particular policy? Here you could see at policy and then for this lamda expressions, we'll just start up on object block, right? And then you can see policy dots. And then just start adding all of the configurations for that particular policy accordingly. So you just semicolon and then you have policy does require another claim with these sets of values, et cetera, et cetera, et cetera. So it's really that easy to enforce or to create a policy that the application will know exists. So I'm going to revert to the simple that I had before where we're just seeing adopt policy called is minimum age are called minimum age and then require that policy require that claim, sorry, is minimum age with a value of true. So now that we have defined the policy, we need to put it to use. So let's go to our Create page. And if you look at the top, I have added an author as filter. And instead of this authorize filter out policies equal to what is the name of the policy. So that's another reason at all. A boat's doing the constant classes and trying to eliminate or reduce as much as possible the extremes. Because if you have a typo right here, it would be much harder to figure out why this is not letting me through even though I clearly have the clean data policy says I need it's just because you probably use the wrong policy name or misspelled policy name. So it's always good to kind of just have those strings in constants all over the place, are in one place rather. So you don't have to use them all over the place and then you just make a reference. So just by doing this, we actually eliminated the need to manually go into the user cleans and this then try and figure out what the values are. Because no, our authorized mechanism will do all of that for us. So anywhere that we want to enforce a particular policy, this is all you need to do. And of course, once you put a filter above a page, it will override the default policy that would have been sit in your application. So this is just the default authorized. So once you put it there. Money, well, it will override it and say, well, I want to authorize based on this policy. So while we're on this topic, I'm going to show you another way that we could actually enforce these global filters, which would be a more global way of doing it in any core application. So where it looked at the fact that if we're adding Razor pages would have to do with this. Particularly if we're doing it with MVC, the syntax would look slightly different. But then I can actually remove all of this and just revert to the attorneys of pages or AD controllers and views and know that I have this authorization block with policies be all lined, our options being online, I can add an option lines I can see options dot fall Buck policy is equal to new authorization policy builder. And then I have to go ahead and include the using statement. And then on this bill there we're just going to touch on a few other configurations. So the first one that I'm going to see is require authenticated user. So this is me sitting above the robot policy with authorizations work full. And we're seeing we require the authenticated user. And then you could say require claim. So this would just be like I said, global, this wouldn't be customized one lakh overseeing. We want this option. So you can sit up everything you want as a global authorization fall Buck policy on what the policy is, is basically what should I do when that authorized filter or a low anonymous filter is not present? So if one is not prison, money wildly, like how we put this one explicitly here, then what do I do? Very similar to how we just had the global requirement for authorization here. But you will get a little more granular with this method because now we can build out exactly what requirements, what schemes, everything that we want at the gate goal from default before we just called Build. And then build with no say. Okay, this is my fall Buck policy. Whenever there is no author as our explicit authorization filter with any specific requirements in there, then this is what I wanted to do. So now we have two things. Statista, we're going to test that the policy works. So whatever we just proved on this page, when a user is under 18, there should not be able to access this page. And we're going to prove that we still get the default prompt to login for anything that is said to be authorized. All right, so we're here in our application and ultimately to do firstly, I'm not authenticated. I went to go into categories. And remember that categories is supposed to be. It doesn't allow anonymous. So advertisements allows anonymous, which I'm still able to browse through because that allow anonymous filter is overriding that fall above policy. And then when I go to categories which doesn't allow anonymous, I'm being prompted to login. So that's working as far as I can see. So when I do login as a customer who is under 18, well, the system may access is denied because I'm a customer says should be able to get the categories, that's fine. But when I go to advertisements, I should not be able to create new because of the policy for is minimum age. So when I tried to create new, I'm getting access denied. Right. Just the same way. So right there. I don't have to manually say return, local direct access denied the system, the fallback policy, in combination with my explicit policy that I'm using to protect the speech, is doing that for me. It's checking the claim and it's rewrote it. So that is all you really have to do. And you want to get kind of granular with certain permissions. You create the claims that you know, person's needs. So one person should be able to edit, what another person should be able to edit. You just make sure that they are the claims didn't need at any point. And then you just protect your different pages with the policies that you have aligned in your startup file.
29. Section Review - Claims and Roles: All right guys, so that's another milestone and we're just going to review what we've done in this section. So on we reviewed basic authorization, went over to look at how it works in a blazer up all the filters were. And in our startup, we had also looked at how we can enforce that author as filter globally across all Razor pages and by extension MVC options and controllers if you're using such an up. Since then we also implemented policies where we know how to do it more globally without mixing and much in the syntax, we can just do something like this. We also looked at creating our own policies based on claims. So creams are bits of information that we know how to dynamically add to the user once the login weekend make certain determinations based on information that they provided or based on their user required. And then we can add those claims to that identity or the claims principle before that user actually gets authenticated into the system. As a results, we can know implement policies that allow us to restrict or allow certain actions or privileges based on the claims that they have prisons. So we also had taken a look at roles. We took a look at how we can allow a user to select the role they want in the system, and then how we actually add them to that role afterwards. If it is a born to allow them to slit the role, then you can just add the rule to the user once they're logging in. Because think of bigger websites like Amazon on YouTube. You don't really select the role you want to have with a YouTuber cones. They just know once you create a colon, you are a user. So they actually would have automatically put you through as a user. And then they have another mechanism where they add their own admins and other rows and so on. So at that point you'd want to look into creating the values on management dashboard that allows you to have full control over something like that. But for the users coming in through the internet, you give them their role in the system, and that is their role going forward. So based on your model, you know, know how to handle that situation. So ultimately, that's it for this section. Like I said, I know you would have gone through quite a few things. It's not a one shoe fits all. So I'm just showing a different scenarios and different ways that you can get creative and practical around how you secure your application for yourself and for your users.
30. Section Overview - What is OpenIdConnect: Hey guys, welcome back. So in this new section we're going to be implementing OpenID Connect identity providers in our AP. That's a mouthful, but I'm just going to kind of break it down for you. So I'm on the OpenID dotnet slash Connect website and it does under direct opposite of what OpenID Connect really is. So in a nutshell, it allows clients. Clients being your website, you're up, whatever it is that your customer or your users are using that front-facing, That's your client. It's a low stress to verify the identity of an end-user based on the authentication and performed by an authorization server, as well as obtain basic profile information the end-user, in our risks like manner. So in a nutshell, anytime you go to an app and it allows you to say, sending our login with Facebook or with Google, right? I need to stop that Potnia seat. Goes over to Google and you will they have to type in your credentials or maybe you're already signed into Google on that machine or on that device. And it just allows you to go through and, and all of a sudden you're signed in the new websites has all the information has provided by Google. Google provides an OpenID Connect Service as those windows, as this Facebook. And we're kinda looked at it in the earlier parts where we were adding all of these services at Twitter and Google and Microsoft and Facebook. All of those can double as OAuth servers. So auth provider, sorry, So in this section we're actually going to implement it. We didn't do it then because it was kind of early in the game. And I gave you a few techniques, but we're going to review those things. And what we're going to do is focus on doing it with Google. But once we get Google out of the way, at least you would understand that if you wanted to support all of those other ones and you're up, give your users all those options, then at least you'll have an appreciation of how that can be done. So in the next section we're going to do is go through how you can go about getting the key and secret from Google. And then we'll wholly integrated into our AP going forward.
31. Sign Up For Google OAuth Credentials: All right guys, so in this lesson we're going to just quickly walk through how we can get the Klan key and a secret that we need from Google to allow us to authenticate against Google accounts. Now you can navigate to the Cloud platform by going to console dot cloud dot google.com. You will have to sign in with a Google account and then you get access to this dashboard. And that would be similar for any of the other providers. You will have to sign in with an account that belongs to that provider in order to get access to the backend where they give you the keys, right? So after you've logged in or you created a Googler cones and you've accessed a similar screen to this. You want to go to credentials and then you're going to click create credentials. So also if all of these options we're choosing OAuth client ID because that's what we're after. And then we specify what kind of application. I'm just going to say web application where you see you have different options and you can give it a specific name if you wish, SQL colleague classifieds or whatever your project is. And then you go ahead and hit Create. And once you hit creates, that will give you that ID and that secretes, and that's it. So you need to copy these values. And remember that we have to use these in our app so you want to keep them safe, least what they don't load the JSON or not, but keep them safe or no, it doesn't make sense if you try to copy mine because by the time you're doing this course, I would've destroyed the evidence anyway. So I recommend that you try it, gets your own key and secret, and then you can have your own controlled experience on your end. So when we come back, we'll be integrating these into our AP.
32. Add Google Auth to App: So after we've retrieved or keys, we're going to jump back over to our up and we're going to go to the startup class where we want to add a new block that we're going to see services that add authentication. So remember last time or earlier in the course when we're doing this, we had added the add Google to the services, the authentication block where we were specifying that we're using the cookie off. All right, So we actually could have removed it because we did all the things that handle all of that. Well, no, we can go back for it. And we'll add on Google, right? And whichever other provider, make sure you have the required library. So for that one in case you may have removed the libraries since we didn't use it. You definitely need to have Microsoft dot ASP, Core Authentication Google. So if you don't have it, you can just go and find it in NuGet packages, right? And I still have all the other packages from the other providers that we may not end up using right now. But those are the libraries that you need in case you choose one of the above, and not necessarily Google as I'm demonstrating. So back to the startup after we've added Google wants to say Options. And then we have our object block where we're seeing Google options. That trend ID is this. And the secret is that no, we already discussed that it's a bad idea to one puts the ID and secret value is dead in the startup, the alternative probably would have been the app settings, but then between the two of them, we will definitely be tricking it into source control. And if it's a publicly accessible source control, like GitHub, repo is public, then that's a very bad idea. So what we want to do is add them to the secret. So you just right-click our projects. And then we go to Manage Users secrets, which will then give us our secret config file, right? So I'd already kind of retrofitted it with the client ID and secret. So no, practically get to see how it's used. So we will take this value. So that's is the client ID. Put it here, this is a client ID for Google. And then we do the same thing with the secret, puts it over here for the secret. And once again, you follow that same pattern for Facebook, Twitter, et cetera, et cetera. Right? So once we do all of that, what we're going to do is say configuration, configuration. And the key that we want would be Google colon client ID. So Google colon client ID. And then we would repeat that for the secret. So it's a colon and I did sequence secrets. So it is bu colon client secret and just that, that we have securely added the auth keys and secrets are key and secret to our application? No. After we've added this authentication configuration and look at what happens when we go to the login screen. To the right, you're going to see that you have the service google to use red. So remember, when we did the money, well, the weird ones who actually listed them all the Facebook, Twitter, et cetera, et cetera. We listed the mode, know the scaffolded login page already had the mechanism, you remember over here had a little write-up about the external providers and so on. Because what's happening in the file or in the code behind rather is that it is, let me just quickly find login logic and gets, it is saying, Get me the external authentication schemes courtesy of sand in Manager, san and monitor is actually going to go to the startup and say, are there any other schemes defined here in the startup we saw, oh yes, you have Google. Okay, So we'll add the Google button for you. Right? So in the login page, if there are none that they get the right or otherwise, list them out. And for each one, just create a button with the provider name. That's all that's really happening, right? So sometimes, you know, a scuffle these things and we see them ourselves. We don't need that, I will just remove them, but it's always good to understand why you see certain things a certain time, what configurations are needed to get certain things to work? And this is certainly one of the configurations that you rarely see. People actually take the time or to go through step-by-step and help you to understand. So that is basically how you would start adding them. And I could as many as you chain on here like we saw with the Twitter, Facebook, et cetera, et cetera. As many as your chain on, you're going to get those buttons automatically. So I'm just doing this step-by-step little by little. When we come back, we will test together how that login logic works.
33. Test Google Auth Login Flow: All right guys, So we're back and the objective this time is to verify that our log, it actually works. So the first step 1 is go to the login page. So step two is click the blue button. So when we click Google, what you're going to notice is that it's navigating away from our right. So we are at localhost something, and then when we click that, it's actually navigating always. So make sure you have Internet when you're doing this off course. And it is trying to go to a colon slash google.com sign in and they're giving us an error. So the error here is a 400, which means bad request. And this is the reason redirect URI mismatch. So they give you a little reading. And again, SEO is doing some reading just to make sure that I fully understood it. And if you click Request details, then they're going to tell you, if you're the developer makes sure these Request details comply with Google policies. So they're giving you what the redirect URI needs to be, which is localhost, which they know where you're coming from. But you need to have that endpoint on its sole. I'm going to copy this and then I'm going to jump back over to my credentials manager and that client that we had created, the same one with the App ID. And the secret, what you want to do is go down to the authorized redirect URIs. So you're going to add Ury and then put in that URL or urea, that link. And then you click Save. And then once that is saved, what I'm going to do is just click OK. And then we're going to click Google again. And this time you're going to see that it is no asking me to sign in with my icon. So I'll do just that. And after providing my e-mail address, password and potentially getting challenged for two if a verification by Google, I am no led to this page where it says, do you want to associate your Google up cones? And then they give you the email address and ask you to register. Now you'd see that the page does it navigates through is identity slash slash external login. And the return URL is just whatever the axis, right? So that is the page that you can modify. Know if you wanted to add or allow the user to add more details than just their e-mail address. Because this e-mail address is going to double as their username and they won't have a first name, last name, et cetera. Granted, you can probably tweak the settings a bit more with Google to see get more information from Google, a boat, this user so I can fill into my system. I'm not going to go into all of those things, right? No. So you can look out for that now, one other thing that you may end up getting is one of those 400 errors after you tried to login with Google credentials, you might get that same 400 page. If you do, you can probably come back here and just add the URL without this sanding Google just add that as another URI. Because what happens is that these URLs tell Google what my client should look for are should navigate to when it is finished with Google. So our what Google's should try it to navigate back to when it is finished doing its thing. So that's a part of that security. Remember when we were talking about setting up the secure registration and login, how we always do the redirect, the local redirects so that we make sure we're redirecting to a page in our AP that is similar to what Google is trying to accomplish here, to see what domain should I always look for whenever I'm finished authenticating this person? So you may end up needing to add another entry and it's in blood is on Yuri. Did there and save no harm done, read or write any whole buck to our up. Once I click Register, I am going to need to confirm cones. That's fine. We know that that is the standard procedure, but I wanted to bring us over to the database so that we can see what is happening. So in the database, you're going to see a new user created with the email address. I can just set this to true from here. And the security stamp, all of these things, no password, no password is required because we're not handling the password for this user and this is a Google user. So all of those things that user outcomes is created, if we go with the ASP NET user logins would notice too, that we get a new entry where we know the provider, the provider key, the display name, and the user to whom this login is attributed.
34. OAuth Section Review: All right guys, so in this section we took a look at how you can set up Google authentication. And by extension, the same techniques can be applied for other third party Auth Providers. We only use Google because maybe more than, more than likely have a Gmail account or Google account. And it's much easier to just get started with that. Both the techniques can be applied across the board. Certain things that we have to do. One, we have to go to that third party platform, whatever it is, whether it's Google or windows, or Twitter or Facebook, we have to go there, register a new web client. And that would give us the necessary key and authentication credentials that we need to authorize our app. We also need to put in authorize redirect URLs based on our domain addresses. And then after doing that, we would be encouraged to go back to our application and add users secrets are up secrets and store our client ID and secret there instead of in the regular configuration or in plain text in the code, right? So you'd want to add those secrets to the AP, access them accordingly. We add the authentication schema, or schemas based on how many you have. And then once that is done, the app will automatically render them based on the boilerplate code from our scaffolded login and register Pages. Know after we've been able to authenticate as a Google account holder, then we can log in and the same privileges as a regular user had will be applied here. No, you're clearly going to see that there are certain things that are missing because we don't know about the date of birth, we don't know full name. So there are certain bits of information that we can allow the user to manage afterwards or we can transcript from the third-party provider given how much leeway and leverage they give. Because there are just certain standard bits of information that they're going to give buck. So name identifier, we are getting that. Sure. Well, their name, e-mail address, those are coming from the user record. And in here we see that this has an authentication method of Google. If we go to external logins, you'll see Google. So personal data and all. You'd probably want to allow them to manage those things in their profile money-wise. So phone number, you can add first name, last name, date of birth. So I load that third party authenticated person to create their cones, but then fill in the details afterwards. So there are a number of ways, like I said, it's not a one-size-fits-all. You have to find the tetany that works for you and your users and your situation. That being said, though, we have successfully set up Google authentication in our dotnet Core up.
35. Conclusion: All right guys, so we've come to another milestone and we've completed this course. This course taught you how to implement authentication and authorization in your dotnet Core application. Not only did it teach you how to do that, because the reality is that we can actually get all of that feature set out of the box at the most basic level. But we explored the ins and outs of how all of the parts fit together to give us a nice secure application. We also looked at the fact that you have to be careful when you're balancing security measures with usability because then you might make your AP so secure that it's hardly usable. And on the flip side, you don't want it to be very usable but not very secure. So you always want to take those things into consideration. It's always one thing to do. A tutorial or a course where we're teaching you how to build this system and sprinkle a little bit of this and that feature. But it's another thing when you sit down and look at that feature set and that library in its entirety and fully appreciate all the intricacies that can guide you with your development and design considerations going forward. In this course, we have pretty much exhausted the basics. And we looked at the fundamentals and we looked at some advanced stuff we looked at so you can extend what comes out of the box. We'll look at how you can take advantage of what comes out of the box and how all of these things fit together. So I want to thank you for sticking with me through this journey. And I hope that you can take what you've learned from this course and build a beautiful the secure application for yourself and your users.