Lec11 Identity
Lec11 Identity
Lec11 Identity
2
Basics of User Authentication
■ User Authentication refers to the process of proving users'
identities.
▬ E.g., logging in with username and password is a typical way of
doing this.
■ Recall that in 300582 TWA, you are asked to implement the
features of user registration, login and logout by PHP from
scratch.
▬ You need to implement input textboxes, database lookup and
session variables for remembering users all by yourself.
▬ We emphasize that all these implementations are essential for
understanding the fundamentals of how websites work.
■ However, for real website development, it is desirable not to
repeat the same efforts.
3
Lecture outline
■ Basics of User Authentication
■ Authentication by ASP.NET Core Identity package
■ Understanding the ASP.NET Core Identity package
■ Add, scaffold and migrate Model classes
■ User authorization
■ Anatomizing the sample project for this lecture
4
The ASP.NET Core Identity package
■ In ASP.NET Core, features related to user authentication are
provided in the Identity package.
■ The Identity package supports many methods of
authentications including:
▬ Using username and password maintained by a web application
itself
▬ Using third-party credentials such as those from Google,
Facebook, Microsoft, etc.
▬ Using Two-factor authentication such as normal password plus
security code sent to mobile
■ This unit still focuses on using the first method. But after you
get how to use the first method, it becomes very easy to learn
other methods.
5
Include Identity in your project
■ To have the Identity package in your project, you need to set
up the authentication when you create the project in VS.
■ This can be done by following the steps below:
▬ Select File > New > Project > ASP.NET Core Web Application.
▬ Select “Web Application (Model-View-Controller)”, then select
Change Authentication.
6
Include Identity in your project (cntd)
▬ Select “Individual User Accounts” and click OK.
7
Change the DB provider for Identity
■ The Identity package by default uses SQL Server LocalDB to
store user names and passwords
■ You need to change this to SQLite for the submission and
marking of your project.
■ As you learned before, you can achieve this by changing the
DbContext in the ConfigureServices() method in the Startup.cs
file (See the screenshots in next slide)
8
Change the DB provider for Identity (cntd)
■ Specifically, change
■ To
9
Change the DB provider for Identity (cntd)
■ Specifically, change
■ To
10
Change the DB provider for Identity (cntd)
■ At this stage, the database file XXX.db has not been created
yet.
▬ You need to use migration to create it.
■ Fortunately, when you create a project with authentication
enabled, the migration for creating the database is already
created for you under the 'Data/Migrations' folder. (NB: not
the 'Migrations' folder as usual).
■ In Solution Explorer, you'll see:
11
Change the DB provider for Identity (cntd)
■ Now you can simply run the 'Update-Database' command in
Package Manager Console.
■ Then, you'll see the XXX.db file is created for you.
▬ We are going to use this database to store not only
usernames/passwords but also the data for the web applications.
■ Finally, you can compile and run this project.
▬ You'll see the Register and Login links appear in the right of the
navigation bar.
▬ Note that, in ASP.NET Core Identity, a user's email address is used
as his/her username.
12
Lecture outline
■ Basics of User Authentication
■ Authentication by ASP.NET Core Identity package
■ Understanding the ASP.NET Core Identity package
■ Add, scaffold and migrate Model classes
■ User authorization
■ Anatomizing the sample project for this lecture
13
Understanding the Identity package
■ If you look at the Solution Explorer, you'll notice that Identity
adds the following two controllers and their associated views
to the project (for details, see our sample project):
▬ AccountController: providing the action methods such as
Register(), Login(), Logout(), etc.
▬ ManageController: providing the action methods such as
ChangePassword(), TwoFactorAuthentication(), etc.
14
Understanding the Identity package (cntd)
■ If you examine the database used by Identity with Sqlite DB
Browser, you'll notice that Identity uses the following seven
database tables (for details, see our sample project):
15
The AspNetUsers Table
■ This table mainly stores the login-related information for
registered users. This definition of this table is shown in the
picture below.
16
The AspNetUsers Table (cntd)
■ You need to understand the following fields of this table.
▬ The Id field is a string randomly generated by the Identity package.
o As it is the primary key, its uniqueness is guaranteed by the Identity's
generation algorithm.
▬ Both the Email field and the UserName field store the user's email
address.
17
The AspNetUsers Table (cntd)
▬ The PasswordHash field stores the hash values of passwords, instead
of passwords themselves.
o Thus, even when a hacker gains access to this table, this hacker will not
know what the passwords are.
o For us, this means that we should not manually edit the PasswordHash
field, which has to be generated by the Identity package.
18
The AspNetRoles Table
■ Identity supports assigning different roles to registered users.
▬ For instance, some users can be assigned the role of 'customers', and
some users can be assigned the role of 'administrators'.
■ Then, what we talk about the Authorization part, you'll see that
different access rights can be granted based on roles.
■ The AspNetRoles table stores the information about roles. This
definition of this table is shown in the picture below.
19
The AspNetRoles Table (cntd)
■ You are only required to understand the following two fields of
this table.
▬ Similar to the Id field for users, the Id field for roles is also a string
randomly generated by Identity.
▬ The Name field stores the role names such as "Customers" and
"Administrators", which are used to specify authorization rules.
20
The AspNetUserRoles Table
■ This table stores the mappings from users to roles. This definition
of this table is very simple, consisting of only two fields as
illustrated below:
21
The AspNetUserRoles Table (cntd)
■ You are required to understand both fields of this table.
▬ The UserId field is a foreign key referencing the Id field in the
AspNetUsers table;
▬ The RoleId field is a foreign key referencing the Id field in the
AspNetRoles table;
■ Each row in this table stores a mapping from a user to a role.
▬ The users are identified by their Ids in the AspNetUsers table
▬ The roles are identified by their Ids in the AspNetRoles table.
■ From the above, we can see that Identity supports that a user
assumes multiple roles simultaneously.
▬ However, in most cases, we only need to assign a user with one role.
22
Notes for the Identity database
■ The tables in it should be managed by the Identity page.
▬ You should not manually modify those tables.
■ But you can use Sqlite DB Browser to examine the tables to
check whether your web apps are working as expected.
23
Lecture outline
■ Basics of User Authentication
■ Authentication by ASP.NET Core Identity package
■ Understanding the ASP.NET Core Identity package
■ Add, scaffold and migrate Model classes
■ User authorization
■ Anatomizing the sample project accompanying this lecture
24
Add Model classes into the project
■ Adding Model classes into a project with Identity follows the
same procedure as discussed in Lecture 4.
■ One place needing consideration is the Model class for the users.
▬ Since a project with Identity involves the concept of users, this is a
class you must have in the project.
■ There are two ways to define this Model class:
▬ Use the ApplicationUser class generated for you.
▬ Define a new one by yourself.
25
Use the ApplicationUser class
■ It is defined in the ApplicationUser.cs file under the 'Models'
folder.
■ It extends the IdentityUser class which is mapped to the
AspNetUsers table.
27
Define a new Model class for users (cntd)
■ Then, the 'Email' property in both MovieGoer class and
IdentityUser class will allow you to combine the data for a user in
both tables together.
■ NB: In this way, we cleanly separate the users' profiling data with
their authentication data, so it is also a good approach.
28
Scaffold Model classes
■ Scaffolding Model classes in a project with Identity basically
follows the same procedure as discussed in Lecture 8.
■ The only difference is that you should choose the
ApplicationDbContext used by Identity as the DbContext (i.e.,
use the same database as used by Identity.)
▬ See the screenshot below.
■ In our sample project, we did this for three Model classes: Movie,
MovieGoer and Order.
29
Migrate Model classes
■ Migrating Model classes in a project with Identity basically
follows the same procedure as discussed in Lecture 8.
▬ NB: you can scaffold all Model classes first, and then migrate them
together.
■ The only difference is that after executing the 'add-migration
<MigrationName>' command, you need to manually comment
out some migration code in the migration .cs file.
■ This is because the generated migration code includes a lot of
detailed operations for the database, but some of them are not
necessary and may not be supported by Sqlite, thus giving you
error messages.
30
Migrate Model classes (cntd)
■ Specifically, SQLite does not support the migration operation
('AddForeignKeyOperation').
▬ This doesn't mean Sqlite doesn't support foreign key.
▬ This only means that Sqlite doesn't support adding the foreign key
after the class has been migrated.
▬ Sqlite definitely supports adding the foreign key in the very
beginning.
■ Since we created our Model classes fully in the beginning, we
don't actually need this operation.
■ So you can safely comment out those codes related to
'AddForeignKey' or 'DropForeignKey'.
31
Migrate Model classes (cntd)
■ You should comment out the following in the Up() method in the
migration file (see our sample project for details):
32
Migrate Model classes (cntd)
■ You should comment out the following in the Down() method in
the migration file (see our sample project for details):
33
Migrate Model classes (cntd)
■ Then, you can issue the 'update-database' command to get the
migration applied.
▬ If you encounter other error messages related to 'operation not
supported by Sqlite', you should comment out those operations from
the migration file as well.
▬ Based on our experience, there shouldn't be.
■ Then, you can hit Ctr + F5 to run the project and see all the
controllers for Movie, MovieGoer and Order are running as
expected.
34
Modify the controller and views for
Order
■ Then, you can follow Lecture 8 to modify the controller and
Views for Order to improve those codes that are not generated
intelligently enough.
■ For the controllers and views for Movie and MovieGoer, you can
leave them as they are, since the generated codes for them are
OK.
■ NB: The scaffolding generates a lot of controllers and views for
you. If you don't need some of them in your real project, you
should remove them.
35
Lecture outline
■ Basics of User Authentication
■ Authentication by ASP.NET Core Identity package
■ Understanding the ASP.NET Core Identity package
■ Add, scaffold and migrate Model classes
■ User authorization
■ Anatomizing the sample project for this lecture
36
What is authorization?
■ Authorization deals with granting users with due privileges for
accessing a website. For example, some web links are only
available to logged-in users, and some web links are only
available to users with an administrator role.
37
Authorization in ASP.NET Core
■ Authorization can be easily implemented with the [Authorize]
attribute class in ASP.NET Core.
■ This attribute class is in the
Microsoft.AspNetCore.Authorization namespace.
■ So you should add 'using
Microsoft.AspNetCore.Authorization;' in the beginning of a .cs
file.
38
Authorization in ASP.NET Core (cntd)
■ The [Authorize] class supports the following ways of
authorization:
▬ Simple authorization
▬ Role-based authorization
▬ Policy-based authorization
▬ And more …
■ This unit only requires the simple authorization and the role-
based authorization.
Ref: https://docs.microsoft.com/en-
us/aspnet/core/security/authorization
39
Simple Authorization
■ Simple Authorization allows you to specify whether a web link
should be only available to a logged-in (i.e., 'authenticated' in
ASP.NET jargon) user.
■ You can simply add the [Authorize] attribute before a
controller class to make all action methods within that
controller only accessible to logged-in users.
■ You can also add the [Authorize] attribute before an action
method to make that method only accessible to logged-in
users.
■ The ASP.NET Core has managed to achieve the following:
▬ If a non-logged-in (i.e., 'anonymous' in ASP.NET jargon) user
somehow enters a link requiring authentication in browser, the
user will be redirected to the login page by the website.
40
Simple Authorization – Example 1
■ Below will require authentication for all action methods
implemented inside the OrdersController.
41
Simple Authorization – Example 2
■ Below will require authentication only for the Edit() method
inside the OrdersController.
42
Role-based Authorization
■ Role-based Authorization allows you to specify whether a web
link should be only available to logged-in users with certain
roles.
■ You can add the [Authorize] attribute with the 'Roles'
parameter before a controller class or an action method to
achieve this.
■ Syntax:
▬ [Authorize(Role="Role names separated by comma")]
NB: the role names are stored in the AspNetRoles table
43
Role-based Authorization – Example 1
■ The following code only allows the users with the
'Administrator' role to access the action methods in the
AdministrationController:
44
Role-based Authorization – Example 2
■ The following code only allows the users with either the
'HRManager' role or the 'Finance' role to access the action
methods in the SalaryController:
45
Role-based Authorization – Example 3
■ The following code only allows the users with both the
'PowerUser' role and the 'ControlPanelUser' role to access the
action methods in the ControlPanelController:
46
Lecture outline
■ Basics of User Authentication
■ Authentication by ASP.NET Core Identity package
■ Understanding the ASP.NET Core Identity package
■ Add, scaffold and migrate Model classes
■ User authorization
■ Anatomizing the sample project of this lecture
47
Tasks done in this sample project
■ In our sample project, we have implemented the following:
▬ Creating two roles: "Admin" and "Moviegoers"
▬ Creating an admin user with the role "Admin"
▬ Assigning a normally registered user the 'Moviegoers' role
▬ Implementing the 'MyDetails' link to allow a logged-in user to
enter/modify his/her details
▬ Redirecting a newly-registered user to the 'MyDetails' link
▬ Implementing dynamic links in the navigation bar based on roles
48
Creating roles and the single admin user
■ For this task, our sample project implements the following
three subtasks:
▬ Creating two roles as follows:
o Admin
o Moviegoers
▬ Creating a single admin user with his/her credentials as follows:
o Username: [email protected]
o Password: P@ssw0rd
▬ Assigning this admin user with the 'Admin' role
49
Step 1: Storing the admin's credentials
■ Store the username and password for the admin user in the
configuration file 'appsettings.json':
▬ This is better than hard coding them in our source code.
▬ We'll read the "UserSettings" section of the configuration file for
the username and password when initializing this power user.
50
Step 2: Creating a static method for
accomplishing all three subtasks
■ We name this static method CreateRoles() and put it inside a
new class named SeedRoles under the 'Data' folder.
51
Step 3: Invoking the CreateRoles()
method in the Main() in Program.cs
■ You should replace the original body of Main() with what are
present in Main() in our sample project.
▬ An excerpt of important code is shown below:
52
Assigning a normally registered user
the 'Moviegoers' role
■ In our sample project, we assume that all normally registered
users will assume the 'Moviegoers' role after registration.
■ We implemented this by adding the following two lines of
code into the [HttpPost] Register() in the AccountController.cs.
53
Implementing the 'MyDetails' link to
allow a logged-in user to enter/modify
his/her details
■ This link is implemented by adding the following components:
▬ MyDetails(), MyDetailsCreate() and MyDetailsUpdate() methods in
MovieGoersController
o NB: We removed all action methods in MovieGoersController generated
by scaffolding, since we don't need them for this sample project.
▬ Views/MovieGoers/MyDetailsCreate.cshtml
▬ Views/MovieGoers/MyDetailsUpdate.cshtml
▬ Views/MovieGoers/MyDetailsSuccess.cshtml
■ You should read all these components in our sample project to
fully understand them.
54
Redirecting a newly-registered user to
the 'MyDetails' link
■ Redirecting a registered user to the 'MyDetails' link
▬ In [HttpGet] Register() in AccountController:
55
Implementing dynamic links in the
navigation bar based on roles
■ In our sample project, the links in navi bar are displayed
dynamically in the following way:
▬ The 'Home' and 'Movies' links are displayed to all users no matter
logged-in or not
▬ The 'My Details' link is only displayed for the logged-in users with
the role 'Moviegoers'.
▬ The 'Orders' link is only displayed for the logged-in users with the
role 'Admin'.
56
Implementing dynamic links in the
navigation bar based on roles (cntd)
■ This can be easily implemented by modifying the _Layout.cshtml
file with the following revision:
■ NB: you need to add the following line in the top of _Layout.cshtml:
@using Microsoft.AspNetCore.Identity
57
Implementing dynamic links in the
navigation bar based on roles (cntd)
■ You can test the dynamic links by using the following users:
■ [email protected]
▬ Role: Admin
▬ Password: P@ssw0rd
■ [email protected]
▬ Role: Moviegoers
▬ Password: Parra.2150
■ You can also register a new user to check whether it is in the
role of 'Moviegoers'.
58
Summary
■ The Identity package allows you to have authentication in your
website with just a few mouse clicks.
■ The [Authorize] attribute allows you to implement
authorization based on roles, policies, etc. very easily.
■ You should fully understand the sample project for this lecture
to implement our unit project.
59