WEBVTT

00:00.000 --> 00:00.330
Okay.

00:00.330 --> 00:01.740
Welcome to section nine.

00:01.740 --> 00:04.950
And in this section we're going to cover identity.

00:04.980 --> 00:12.240
We're going to set up authentication and authorization in our application and allow the users to log

00:12.240 --> 00:14.430
in and register of course.

00:14.430 --> 00:20.850
So coming up in this section then we're going to take a look at setting up ASP.Net identity, something

00:20.850 --> 00:28.170
that has been made a lot more simple than it used to be since about dotnet eight, not surprisingly,

00:28.170 --> 00:34.170
integrates very well with Entity Framework, and it's going to provide the set of tables that we need

00:34.200 --> 00:39.060
to manage our users, our roles, and our claims in our application.

00:39.210 --> 00:41.580
We're also going to take a look at forms in react.

00:41.580 --> 00:46.500
We haven't done much with forms yet, but now we're going to start to look at things like logging in

00:46.500 --> 00:47.220
and registering.

00:47.220 --> 00:52.560
We're going to need to take more information from the user, and the way that we do that is to use forms,

00:52.560 --> 00:57.330
of course, and we don't want to stick with just using react for that, because the code that we write

00:57.360 --> 00:59.360
becomes very verbose very quickly.

00:59.360 --> 01:01.160
So we're going to use a package to help us.

01:01.160 --> 01:04.520
The most popular way to do this just now is to use react hook forms.

01:04.520 --> 01:05.840
So that's what we'll implement.

01:05.840 --> 01:12.080
And we're also going to take a look at form validation as well, so that we can stop the user from sending

01:12.080 --> 01:17.510
a network request to our API if they haven't provided the information that we're looking for of course.

01:17.510 --> 01:21.140
So what is ASP.Net identity.

01:21.140 --> 01:23.210
And there's that term ASP again.

01:23.210 --> 01:27.830
And just a reminder that stands for Active Server pages which no longer exist.

01:27.830 --> 01:29.330
But the branding has.

01:29.360 --> 01:35.330
And Microsoft just continued to use it to identify web based aspects of.

01:35.660 --> 01:36.560
Net.

01:36.560 --> 01:37.850
So what is it then?

01:37.850 --> 01:39.620
Well, it's a membership system for.

01:39.830 --> 01:46.040
Net and it provides us a number of different features to help us manage users in our application.

01:46.040 --> 01:50.720
And because our users are going to log in with a password, we need to be able to compare their password.

01:50.720 --> 01:53.960
But we don't want to store their password in clear text.

01:53.960 --> 02:00.980
So when a user does register with a password, then we'll send up the password as a string of text over

02:00.980 --> 02:02.450
Https, of course.

02:02.450 --> 02:06.500
But when it gets to our server and we need to store that in a database, then it's going to be hashed.

02:06.500 --> 02:08.750
And hashing is a one way operation.

02:08.750 --> 02:12.080
And the hash version of that is going to be stored in our database.

02:12.080 --> 02:14.030
And it's going to be salted as well.

02:14.030 --> 02:20.180
So if everybody in our application used the same password of let me in, everybody would have a different

02:20.210 --> 02:21.680
hash stored in the database.

02:21.680 --> 02:23.360
So it makes it that little bit harder.

02:23.360 --> 02:30.020
If our database was compromised for the evil hacker to work out what that password would be.

02:30.050 --> 02:34.160
Not impossible, of course, but it would slow them down.

02:34.160 --> 02:36.440
So then we need to be able to validate that password.

02:36.440 --> 02:42.620
So again, as a user logs in and provides their password they send up the password.

02:42.620 --> 02:48.320
But then that password is hashed using the same algorithm that was hashed the first time for that user.

02:48.500 --> 02:52.010
And then it's compared against the hashed value that's stored in the database.

02:52.010 --> 02:56.560
And if they match, of course, we let them proceed to the next step.

02:56.620 --> 03:00.790
ASP.Net identity also handles user storage.

03:00.790 --> 03:05.770
And as mentioned, we're going to be using the Entity Framework integration for this.

03:05.770 --> 03:11.320
So when we implement this with not too many lines of code, by the way, we're going to have another

03:11.320 --> 03:17.770
six tables in our database all to deal with handling users in our application.

03:17.920 --> 03:20.380
And we also get roles with this.

03:20.380 --> 03:25.840
So if we want an admin user that can only do admin related things, then we have that functionality

03:25.840 --> 03:26.920
as well.

03:26.980 --> 03:32.770
And since dotnet eight Microsoft introduced ASP.Net identity endpoints.

03:32.770 --> 03:37.180
And these are really designed for Spars like our react application.

03:37.180 --> 03:44.290
And with just a couple of lines of code, then we get a full identity system configured for us, including

03:44.290 --> 03:50.560
the controller endpoints for all of these different types of request.

03:51.340 --> 03:54.070
So by adding these lines of code, just a few of them.

03:54.070 --> 04:00.640
Then automatically we have effectively an API controller that can handle registering of users logging

04:00.640 --> 04:01.270
in.

04:01.360 --> 04:04.990
The refresh refers to token refresh.

04:04.990 --> 04:11.890
If we were using JWT tokens, which we're not going to, but if we were then we would have a refresh

04:11.890 --> 04:13.030
token endpoint.

04:13.060 --> 04:19.270
Also, we've got endpoints for confirming email and sending confirmation email forgot, password reset,

04:19.270 --> 04:25.960
password managed two factor authentication, manage info and update the user's info as well.

04:25.960 --> 04:30.730
And all of those endpoints are provided for us with just a couple of lines of code.

04:31.270 --> 04:39.580
And Microsoft specifically recommend using this to secure a web API that's in use for single page applications.

04:39.580 --> 04:43.480
So we're going to follow their recommendations and do just that.

04:43.720 --> 04:48.190
So as with any identity system, the one we choose does come with pros and cons.

04:48.190 --> 04:52.780
And there's compromises and benefits to be gained from whichever one you choose to pick.

04:52.810 --> 04:59.110
I've made the choice for this application to go for ASP.Net identity integrated with our application.

04:59.110 --> 05:03.460
And let's just take a look at the pros and cons of this choice.

05:03.490 --> 05:06.700
So the first pro is it's integrated with dotnet.

05:06.730 --> 05:07.120
We've got a.

05:07.300 --> 05:08.800
Net application.

05:09.010 --> 05:15.070
And in my mind it makes sense to simply use a dotnet provided authentication system.

05:15.070 --> 05:18.520
So it's ideal for our application in that respect.

05:18.550 --> 05:23.320
It's also highly customizable and we can create our own custom user stores.

05:23.320 --> 05:24.910
We can create additional claims.

05:24.910 --> 05:30.400
We can extend our user model if we need to take more information than just an email address and password,

05:30.400 --> 05:32.110
then we could do so very easily.

05:32.110 --> 05:39.580
We can also take advantage of its built in features things like password hashing, role based access

05:39.580 --> 05:40.420
control.

05:40.420 --> 05:42.670
It also comes with a secure defaults.

05:42.670 --> 05:47.530
When we use this, we don't need to spend hours upon hours tweaking things to make it secure.

05:47.560 --> 05:52.720
Obviously, with an identity system, you would hope that it comes secure out of the box, and you don't

05:52.720 --> 05:55.240
need to spend hours tweaking it to make it secure.

05:55.240 --> 05:58.330
And it also comes with roll and claims management as well.

05:58.330 --> 06:03.760
So it's very simple for us to integrate a roll based authentication system into our application.

06:03.760 --> 06:04.990
Some of the cons then.

06:04.990 --> 06:07.180
Well, it is tightly coupled with nets.

06:07.210 --> 06:08.140
Of course it's a.

06:08.320 --> 06:09.160
Net system.

06:09.160 --> 06:14.140
So if we did need this to work with other non-microsoft tech stacks then we would need to use something

06:14.140 --> 06:14.770
else.

06:14.800 --> 06:20.050
Also, we might have scalability challenges as the way that we're going to implement this is really

06:20.050 --> 06:26.020
a single server solution where we're coupling this with our web application itself.

06:26.020 --> 06:33.400
And if we did need a multiple server solution or something like single sign on, this would not be suitable.

06:33.400 --> 06:39.340
We'd need to use something like Identity Provider or Keycloak or Auth0.

06:39.370 --> 06:41.770
Any one of those would be a better option for that.

06:41.770 --> 06:45.070
But that's not something that we need to worry about with our application.

06:45.070 --> 06:50.800
And as I mentioned, it's not suitable for distributed apps, anything that's more than a single server,

06:50.830 --> 06:52.360
then this is no good.

06:52.360 --> 06:54.610
We'd need an identity provider at that point.

06:54.610 --> 06:57.760
And this is not that.

06:57.760 --> 07:06.340
And whilst customizable, is a feature of ASP.Net, identity customization can become complex for certain

07:06.340 --> 07:07.750
types of scenarios.

07:07.750 --> 07:13.750
Multi-tenant support custom authentication flows that would be challenging and time consuming.

07:13.750 --> 07:18.490
So at that point we would be looking at a different system for authentication, something like Azure,

07:18.520 --> 07:21.340
something like Keycloak, something like Identity Server.

07:21.460 --> 07:25.270
Any of those would be more suited for that task.

07:25.270 --> 07:29.980
So let's take a look at the identity flow that we're going to implement in our application.

07:29.980 --> 07:31.360
So we start off with our user.

07:31.390 --> 07:35.920
Our user goes to a login form, provides their username and password.

07:35.920 --> 07:39.160
And that information is sent to the API server.

07:39.190 --> 07:43.120
From there the API server is going to validate their password.

07:43.120 --> 07:48.240
And if they get their password correct, then the API server the way that we're going to implement this

07:48.240 --> 07:52.050
is going to issue a cookie to their browser.

07:52.050 --> 07:55.200
That cookie is going to sit inside their browser.

07:55.200 --> 08:03.270
And any time that we make an API request to our web API server, then that cookie is going to be sent

08:03.300 --> 08:10.590
to the server for requests that require authentication and also requests that do not require authentication.

08:10.590 --> 08:13.590
When we're using cookies, it's sent with every request.

08:13.590 --> 08:16.770
So just a few features of cookie authentication.

08:16.770 --> 08:18.480
That's the method that we're going to use.

08:18.510 --> 08:23.790
As I mentioned, it's sent with every single request to the API server whether or not authentication

08:23.790 --> 08:24.900
is required.

08:24.930 --> 08:31.170
It is HTTP only, the cookie that is provided from ASP.Net identity.

08:31.170 --> 08:34.470
There is no access from JavaScript code.

08:34.500 --> 08:42.180
So our react application that we're developing, we cannot access that cookie from our client side code.

08:42.480 --> 08:47.370
Now that in itself does provide some challenges for us, not insurmountable challenges.

08:47.370 --> 08:53.190
But we do need to be aware of that, and we cannot at any point, check the user's browser to see if

08:53.190 --> 08:54.360
they are authenticated.

08:54.360 --> 08:59.520
We need another way to identify from our client side app if they are authenticated.

08:59.520 --> 09:03.690
Also, with regards to cookies, cookies are only available in browsers.

09:03.690 --> 09:05.820
They're not available in mobile apps.

09:05.820 --> 09:13.710
If we did need to support a mobile app, then this system that we are using does provide a way to issue

09:13.710 --> 09:19.530
a token instead of a cookie, but we wouldn't be able to issue a cookie to a mobile app.

09:19.530 --> 09:23.640
But we're not creating a mobile app, so it's not something that I'm concerned about.

09:23.640 --> 09:29.400
And for a single page application, which we are concerned about, then using the approach that I'm

09:29.400 --> 09:36.030
going to demonstrate is Microsoft's recommendation for single page applications, at least ones where

09:36.030 --> 09:40.830
we're integrating identity with the back end API itself.

09:41.460 --> 09:42.780
So that's what's coming up.

09:42.780 --> 09:44.160
And let's begin.
