This is the third article towards Angular 5 User Authentication and Authorization with Web API. In this part we’ll discuss Angular 5 Role Based Authorization with Web API. Here is the complete article list.
GitHub link up to this article : https://goo.gl/3zHQB1.
So Far …
In previous articles, we have created user using registration form and implemented login and logout using token based authentication. So let’s check what we got for this part.
– Web API Role Based Authorization.
– Role Based Menu in Angular 5.
– Role Based Routing in Angular 5.
Add Some Roles
First of all I will add few roles manually inside the asp.net identity table – Role. Admin, Author and Reader.
we’ll be showing these roles as a Checkbox list in Angular 5 user registration form. In-order to work with roles, let’s create a RoleController inside that create GetRoles function to fetch all roles from the roles table.
Now we have to update registration POST web method – Register inside AccountController. Because we have an additional string array for selected roles.
So first update AccountModel class with Roles array.
Now update Register web method inside RegisterController.
The specific line from the above web method will insert selected roles for the user in UserRole table. Number of roles selected will be same as the number records inserted inside the table. ie, one record for each role.
Update Angular 5 App for User Registration Form
First add new method in UserService class from shared folder, to fetch all roles in client side.
In previous article we discussed use of No-Auth header property, If it is true, we won’t add access token in Authorization header. we set No-Auth because GetAllRoles can be consumed anonymously.
Now we’ll call this function inside SignUpComponent and save these roles inside roles array.
Now let’s update corresponding html file. to display checkbox list before submit button with this roles array and unordered list as follows.
there you can see change event for checkbox. it will set or unset role array properties accordingly.
And update resetForm function for resetting roles array.
Since we have an additional string array, we have to make few changes in previous form submission procedure.
Update OnSubmit function inside UserComponent.
Now the registerUser method inside UserService class.
Now we have a working updated user registration form.
Implement Role Based Authorization
Now let’s implement role based authorization in Web API and then in client side.
For that First of all, we have to store roles assigned to a user in Claims during authentication or login, Authentication is done inside token based authentication function GrantResourceOwnerCredentials in ApplicationOAuthProvider.cs file.
we have stored roles assigned to the user inside userRoles variable and with a for-each loop, each of those roles are added to ClaimTypes.Role.
As part of the token request response we have to return assigned roles also. for that we have created an object of AuthenticationProperties with the roles in JSON format. In-order to combine this additional data we have used AuthenticationTicket. Finally we returns the token.
In-order to receive this token in client side with proper format we have to override one more function as follows
Let’s Test the Authorization
In-order to test the implemented role based authorization 3 additional HttpGet Web Methods are added inside Account Controller.
First and second methods can only be accessed by users with Admin and Author roles respectively. But last method can be accessed with either Author or Reader role.
If users doesn’t have the sufficient role(s), Web API project must return 403- Forbidden Status Code, But by default – it returns 401-Unauthorized status code. To override this behavior, we can create new c# class file – AuthorizeAttribute.cs as follows.
Role Based Authorization in Client Side
First of we have to store user role in local storage, for that I’ll update login form submit event.
As part of the token request we will get roles assigned to a particular user. here we save the roles inside userRoles key in local Storage.
Role Based Menu
Let me create a new-empty component admin-panel. it can only be accessed for users with admin role. now let’s add a route for this component as follows.
route path will be adminPanel, here we have an additional data property that we discuss later. Now let’s add a menu item for this component in home component html file.
For the new li element we have ngIf directive. Which conditionally hide/show the li element. Now let’s define the UserService class function roleMatch.
inside this function we will match require array of roles with array of roles assigned to the user. if there is any match then it will return true otherwise false. Above ngIf directive passed an array containing admin role. Now we have role based menu in angular 5 project !.
Role Based Routing in Angular 5
As part of this role based routing we have already provided data property in admin-panel component route with required role admin. Now we have to update existing AuthGuard for role based authorization in routing.
First of all we retrieve roles array passed through routing parameter data. Compare it with user roles if no match found we will navigate to forbidden path.
we have to create this component forbidden. component html will be like this.
for this component we have added an additional image inside /assets/img/403.png. Final component will look like this.
now let’s add a route for this component as follows.