Hi, welcome to Coding Droplets and
thank you for watching this video. This is a complete course to learn .Net Blazor
development. So this video is part of a series and this is part 11 of dotnet blazor tutorial
series. You can check out the playlist link that is mentioned in the video description for
finding the other videos in this series. Before starting the implementation, let me show
you the final output of the blazor server project with authentication and authorization. Now here
in this home page or in the index razor component, you can see a greeting message, hello guest. Also we
have a login option on the top right corner of the page. Currently there are no users logged in and
that is the reason it is showing hello guest. Now let me click on the login option and you can see
a login page or razor component in which we have options to provide the credentials. Currently there
are two different users with two different roles. So first let me login by providing the credentials
of the first user. Both the username and password is user. Once the user got authenticated you
might have noticed the changes in the UI. Now the greeting message changed to hello
user. A new display greeting alert button got displayed. Also previously there was
only the home option in the left side menu. But now it is also showing counter option in the
menu. There is also one more change in the UI. Now instead of login it is showing logout
option. The users can log out by clicking that. Now let me click on the display greeting alert
and you can see it is showing an alert, 'hello user'. The reason for giving this button is to
demonstrate how we can access the logged in username or other user information in the onclick
event or in the code section. Now let me navigate to counter razor component and you can see that
this user is able to access the counter page. So now let's logout and login with the
second user. The username and password is admin. This user is having a different role.
Now you can see it is showing 'hello admin' and there are three options in the left side menu.
Fetch data was not available for the previous user. The alert message will also
show the name of the new user. You can see it is showing 'hello admin'. Admin
user can access counter razor component. Also admin user can access fetch data which
was not available before. Now let's see how we can implement this type of authentication
and authorization in a blazor server project. Here we are using role-based authorization
for changing the UI based on the user roles. Don't miss the upcoming videos in this channel.
Please subscribe the channel named CodingDroplets and don't forget to press the bell icon so that
you will get notified once we upload new videos. I have opened visual studio. First let's create a
new blazor server project. So I am clicking on create a new project. Here I can search for
blazor server app and select it. Then click next to continue. Providing the project name as
blazor server authentication and authorization. Again clicking on next. I'm using dotnet6
framework for this project and just unchecking the configure for https checkbox. Now clicking on the
create button. So the project will get created now. It got created and we are able to see the project
files in the solution explorer. So the first thing what i need to do is, creating a folder named
authentication under the project. We'll be keeping all the classes related to authentication in
this particular folder. Now we are going to create a new class named custom authentication
state provider. We have to inherit this class from authentication state provider. We have to
import 'microsoft.aspnetcore.components.authorization' in order to use authentication state provider. Now
let's see what is authentication state provider. In blazor authentication state provider is
the built-in service for blazor server apps that obtains authentication state
data from the asp.net core's 'HttpContext.User'. Now we can implement the
abstract class and it will override a new method 'GetAuthenticationStateAsync'. This method
will get executed when the application get opened or the page got refreshed. Here let me declare
private 'ProtectedSessionStorage' object. For that we have to import 'microsoft.aspnetcore.
components.server.protectedbrowserstorage'. We are going to save the login user details in
the protected session storage. Also let me declare private claim principle object. For that
we need to import 'system.security.claims'. We'll be using this object for anonymous users.
Now I'm creating a constructor for this class and provide protected session storage as a
parameter. We will be adding protected session storage in dependency injection. So that we can
receive the object here in the constructor. Next we can assign the value for the private protected
session storage object from the constructor. Now let's move to the program.cs class and
do the dependency injection for protected session storage. So we are now ready to implement
the 'GetAuthenticationStateAsync' method in our custom authentication state provider
class. Here first we can try reading the user session details from the protected session
storage. So session storage dot get async of user session. We have to create a model class
named user session. We will do it soon and here the user session in string represents the key of
the protected session storage. Protected session storage will keep data in key value format. So we
are going to save the logged in user details with the key, user session. Also we need to make this
method async as this session storage function is awaited. Next let's create the model class named
user session. I am only providing two properties for this model class - username and role. You can
provide more if you need. Now assigning the value to a variable named user session. User session
storage result dot success will be a boolean value based on get async method. If the value is
successfully fetched it will be true. Otherwise it will be false. So here we are assigning a null
value to the user session variable if it is false. Next we are implementing an if condition
to return the anonymous user authentication state if the user session is null. If it is
not null, we'll create a new claims principle object with two claims in it - name and role. Also
we have to provide an authentication type string value. It can be anything. If you are not providing
anything, the application will consider it as an anonymous user. So here I have provided custom auth.
After that we can return the authentication state with the newly created claims principle. Now
I am providing a try-catch method and placing the code in it. This can be helpful if a user try
to modify the encrypted user session details from the protected session storage. If a user
modify the encrypted value, the application will not be able to fetch the user session from it
and the application will throw an error. So we can return the anonymous authentication state in
the catch section. Now let's create one more method for updating the authentication state.
We'll call this method when a user login or logout. I have provided the user session object
as a parameter for this method. So we can pass the user session object from the UI when a user login.
First I am declaring a claims principle object. Then checking whether the user session object is
null. Here we will pass a null value from the UI when a user logout. So the else part means the
user has logged out. First let's implement what to happen if a user is logged in. Session storage
dot set async of the key user session and value is what we have received as the parameter. We
are assigning the value of user session in protected session storage. Then we create a new
claims principle with two claims username and role. We are assigning it in our object. Now let's
move to the else part. So we just need to delete the user session value from the protected
session storage. Then we make the claims principle as anonymous. Finally we are calling notify
authentication state changed method which is a part of blazor authentication state
provider and we are passing the authentication state along with the claims principle. Next
let's implement the dependency injection for our custom authentication state provider
class in 'program.cs'. It is a scoped dependency. builder dot services dot add scope authentication
state provider which is the blazor service. Then comma custom authentication
state provider which is our class. Now we need to fetch user data from the database
for validation. Currently in this sample project I am not doing any database implementation. But you
can use any database and implement the method for fetching user data from your database here.
I'll be hard-coding user data. First I'll create a model class named user account and it is
having three properties - username, password and role. Next creating a service named user account service.
I am creating a private list of user accounts for saving the user data temporarily in memory. So
you don't need this private list of user accounts. You can fetch the data from your database. Now
as I am not using a database, I am using a list variable to fetch the data. So in the constructor
of this user account service class, I'll hard code two users - admin and user. You can see both of the
users have different roles - administrator and user. Now we need a method for fetching the user data by
filtering with their username. This 'GetByUsername' method will return the user account which matches
the username provided in its parameter. After that I am adding this service in dependency injection
and registering this as a singleton service. We also need to add
'builder.services.AddAuthenticationCore' in dependency. Now we have completed the configuration
part for blazor server authentication. Please don't forget to give me a thumbs up for
this video if you are enjoying it. Also let me know your feedback in the comments section. I
would like to hear from you. Now let's move to the UI development. In UI, first we need a login
razor component with which the users can login. I am creating a new razor component and naming it as
login. Now assigning the page directive '/login'. So that this page can be accessed with this URL.
Next let me add some of the injected dependencies - UserAccountServer, IJSRuntime,
AuthenticationStateProvider and NavigationManager. I have pasted the design for the login component.
It includes two inputs - username and password and we have one button with the text login. This
is the model class for binding the values provided in the inputs. I am also creating an object of
the model class. Next I am providing a method named authenticate which has been provided in the
onclick event of the login button. In this method we'll fetch the user data by calling the 'GetByUserName'
method in our user account service. As a parameter we are sending the username
which we got from the input. Next we are just verifying the user account is not null. If the user
account does not exist with the provided username we'll get a null value here. Also we are validating
the password with an or operator. So if the user account is null or password is invalid, we are
just showing an alert to the user by invoking with IJSRuntime. Now what if the username and password
is valid. I am creating an object of the custom authentication state provider by casting it from
the injected authentication state provider. Then we can call the update authentication state method
which we have implemented. So this method will save the value in the session storage. Finally, we are
navigating the user to home page or index razor component. Next we are making some changes in the
index razor component. So in the home page we need to show a greeting message along with the username.
For that I am implementing blazors authorized view component. Inside authorized view component we can
provide different designs for three authorization statuses - Authorized, NotAuthorized and Authorizing.
Authorizing means the application is executing 'GetAuthenticationStateAsync' method in our
custom authentication state provide class. But the execution is not completed. So here we
only need two separate designs. One for Authorized and another one for NotAuthorized. We will not be
showing anything if the status is authorizing. We'll greet the user with their username if they
are authorized. Otherwise we'll just display 'hello guest'. Now we need one more authorized view for
displaying the greeting button. Here we only need authorized design. We don't show anything if the
user is not authenticated. Next in the code section we need to implement method for button onclick
event. Just before that I am opening 'App.razor' file and changing the RouteView to AuthorizeRouteView.
We can only use authorized view in the razor components if we have mentioned authorized
route view here. Then only the razor component will receive the user authorization details.
Next we need to add one more cascading parameter. That is cascading authentication state. This is for
getting the user authorization details in the code section. Now in the code section we can declare a
cascading parameter - task of authentication state. You can provide any name for this cascading
parameter. Next we can implement the onclick event. First I'll get the authentication state by
awaiting the cascading parameter. So the message to be displayed is hello and whatever value we have
in the 'authState.User.Identity.Name'. Then finally, invoking the alert javascript
function using IJSRuntime. For using IJSuntime, we need to inject it. Now we use IJSRuntime. Let's
invoke alert using 'InvokeVoidAsync' method in IJSRuntime and providing the await keyword. Next we
need to make some modifications in the left side navigation menu. We are showing the menu options
based on the user roles. So let me open the nav menu razor component in the shared folder. Then
implementing the authorized view razor component by mentioning the roles parameter. We need to show
the fetch data menu option only for the users with role administrator. Hence we can move the fetch
data menu option to the authorized component of the authorized view with roles administrator.
Next we need one more authorized view for counter menu option. Counter menu option should be visible
for users with both administrator and user roles. We can provide multiple roles by just separating
them with a comma. Now we can move the counter menu to the newly created authorized view. These are
the changes we need to do in the left side menu. Next in main layout, we can add
option to login and logout. And under NotAuthorized we can place the login option.
For logout, we can provide an onclick event to remove the user session details from the session
storage. So let's implement the logout method. As we did before I am parsing the
custom authentication state provider from the authentication state provider. We
have to inject the dependencies as well. Now we can call the update authentication state
method in our custom authentication state provider and pass the parameter value as null. After that
just navigating the user to the home page. The next important thing we need to do is to provide
the authorized attribute in the razor components. The users will only be able to see menu
options based on their user roles. But still they can manually enter the URL in the browser's
address bar and access the page. So let's restrict the unauthorized users from accessing the razor
component itself. In fetch data razor component, I have provided the authorized attribute which will
allow only administrator users. Then in counter razor component, I am providing the authorized
attribute which will allow both administrator and user roles. Now let's run the application
and see whether it is working as expected. Let me login with admin user credentials
both username and password are admin. Display greeting button is working fine. User is
able to view all pages from the menu options. Let's logout and login with the second credentials.
Both username and password are user. You can see that only counter option is available in the menu
and display greeting button is also working fine. Now I'll show how we are saving the user session
details in the session storage. If you open the developer options in the browser, you can navigate
to application tab and inside session storage you will be able to find the details. Here you can
see the user session details are stored in an encrypted format and that is how the protected
session storage save the data. Now I'm trying to modify the encrypted value. Let's refresh the page
and you can see that the user got logged out. Next I'll show you few more things. In '_host.cs'
file, you can see an option named render mode. By default it will be server prerendered. So let
me give you a brief idea of what is renter mode. Basically there are two types of server render
modes. The first one is server prerendered. Renders the component into static html and
includes a marker for a blazor server side application. When the user agent starts it uses
this marker to bootstrap a blazor application. The second one is server. Renders a marker
for a blazor server side application. This doesn't include any output from the component.
When the user agent starts it uses this marker to bootstrap a blazor application. If the render
mode is server prerendered we'll receive an error in the 'GetAuthenticationStateAsync' method of
our custom authentication state provider class while refreshing the page. Because the application
cannot process IJSRuntime which will be used to access the session storage. But we'll not see that
error as we have implemented the try-catch method. If you need to remove that error you
can use server in the render mode. Now let's run the application and you can see
everything works fine. I'm trying to login with credentials and authentication
got succeeded. So all are working fine. Now without authenticating let
me try to access fetch data page and you can see an error message 'Not Authorized'.
We can even customize this message or we can show a different design
instead of this message. Let me show you how to do that. In 'App.razor' file we can provide
a different design for 'NotAuthorized' state. So i am providing a custom
message 'You are not authorized' and this is a custom message in brackets. Also we can show custom design for
authorizing state. I am providing a custom message for that as well - 'You are getting
authorized' and custom message in brackets. Now in order to display the authorizing message, I
am providing an awaitable task.delay of 5 seconds. Let's run the application. It is getting
compiled. Uou can see the authorizing message now. Now let me try to navigate to fetch
data by entering the url manually. So it shows the authorizing message and after 5
seconds it will show the not authorized message. Now I am authenticating with admin user and
accessing the fetch data razor component and you can see it is working properly. So
that's it for this video. Hope you enjoyed it. Please like, share and comment the video.
See you all in the next video. Thank You!