Tuesday, May 15, 2018

Setting up Two-Factor Authentication in ASP.NET Core 2.0

In this article, I’m going to write bit about security aspects in ASP.Net Core 2.0.

Whenever you create a new ASP.NET Core application, you must notice that there is an option on dialog with a button captioned as Change Authentication and once you click on that, you will land upon a dialog having below 4 options as shown below:

  

I’ll discuss about each of these options in detail but as of now, to get started, let’s take a high-level idea about these
  • No Authentication – which means application is completely anonymous and open for everyone to access it.
  • Individual User Accounts – it uses local database for storing the information related to user.
  • Work or School Accounts – it means application will work with Office365, Active Directory, support for cloud, etc..
  • Windows Authentication – For internet application and uses IIS capabilities to know who has logged in.
Here I’ll be choosing my option as ‘Individual User Accounts’ which is very easy, simplest as well as common too, with sub option chosen as ‘Store user accounts in-app’.  
 
Once you clicked OK, you will notice that ASP.NET Core has added the required middleware in ConfigureServices method with a default token provider, as shown below:
  public void ConfigureServices(IServiceCollection services)
  {


            services.AddDbContext<ApplicationDbContext>(options =>

                options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));



            services.AddIdentity<ApplicationUser, IdentityRole>()

                .AddEntityFrameworkStores<ApplicationDbContext>()

                .AddDefaultTokenProviders();


            services.AddMvc()

                .AddRazorPagesOptions(options =>

                {

                    options.Conventions.AuthorizeFolder("/Account/Manage");

                    options.Conventions.AuthorizePage("/Account/Logout");

                });



            services.AddSingleton<IEmailSender, EmailSender>();

   }
       
 
 
And in Configure method, same is added to the HTTP request pipeline by calling UseAuthentication method as shown below:
      
   public void Configure(IApplicationBuilder app, IHostingEnvironment env)
   {

         if (env.IsDevelopment())
         {

             app.UseBrowserLink();
             app.UseDeveloperExceptionPage();
             app.UseDatabaseErrorPage();

          }
          else
          {
             app.UseExceptionHandler("/Error");
          }


          app.UseStaticFiles();


          

   app.UseAuthentication();

          app.UseMvc();


   }
 

Is middleware configuration sequencing matters?

One important thing to notice in above code snippet is the sequence in which middleware are configured. app.UserAuthentication is called after app.StaticFiles, which means we don’t want any of our static contents to be authenticated before rendering them on to the browser.

Are you thinking, why so? Well, let’s understand this with a most common example of Login page.
Login page, which usually has static contents like css, image, etc. If we will shuffle the sequence of both the statements, then Login page will never ever come until user is authenticated. Now if user is already authenticated, then why do we need Login page. Isn’t it an interesting analogy?

What happen on click of Register?

 Now quickly run the application and click on Register and register yourself as shown below:




















Once you populated the details and click on Register, you will land upon below page: 








Nothing to worry.

This is the expected behaviour because our identity data is not stored anywhere. So, we have to create the required tables and for that we can use local SQL Express database. This can be done quickly by pressing a button Apply Migrations as shown in above screenshot. Once button is pressed, just refresh your page and you would be happy to see the web page with your email id and Log out option in top right corner as shown below:
 




 

 

Configuring the registered data

Let’s say now if we want to modify our existing authentication details. So, to do that, one can click on mail id shown on top right corner of the web page and that will land upon below screen:
 

 

 

 

 

 

 

So, in above screen, we can change the registered email id, password and can also configure two-factor authentication.

Setting up two-factor authentication

Once you selected Two-factor authentication in above screen, you will be asked to add authenticator app as shown below:

 
 
 
 
 
 
 

Once the button is clicked, we will be taken to a page which will tell us that use the given key davi e4jo yiyt kmkz gtn5 jdek jmmb jpl5 as a password. Please note, this is the key generated for me. For you, it would be different one.
But typing this key manually in a phone could be very tedious process. Isn’t it?

So, other way to get the same information on phone is by using the QR code. You can also see a hyperlink which will take you to a very nice documentation explaining about the steps on how to proceed. 

Here we have to use JavaScript library for QR code generation. So, let’s quickly add that to our application under folder wwwroot/lib/qrCode.

Next is to call the method which will generate the QR code for us. Go to EnableAuthenticator.cshtml and update @section Scripts with below code:
 
       
    @section Scripts {


    @await Html.PartialAsync("_ValidationScriptsPartial")

    <script type="text/javascript" src="~/lib/qrCode/qrcode.js"></script>

    <script type="text/javascript">

     new QRCode(document.getElementById("qrCode"),
       {


                text: "@Html.Raw(Model.AuthenticatorUri)",


                width: 150,


                height: 150
       });


    </script>

}        

Make sure that path of qrcode.js is mentioned correctly. We are almost done. Now quickly launch the application and navigate back to Two-factor authentication tab. You will notice that nice QR code is ready for your scan as shown below:


Using Test Online Authenticator App

Now we have setup the two-factor authentication. In order to verify if it’s working correctly or not, we can use online authenticator app from URL: https://gauth.apps.gbraad.nl/.

Steps to use this application are: 
Give some account name and give your key as a secret key and press Add. As soon as you will click on Add, some 6-digit number will be generated as shown below:
 
 










This 6-digit number we will use to verify our authentication as shown below:




 

Quickly click on Verify button and we are done with setting up our 2FA as shown below:
 









 

Using Recovery Codes

In previous screenshot, you must have seen that some numbers are displayed in red color. Those numbers are called recovery code which are very useful in case if you lose your phone or say you got a new phone. One should keep these keys in some secure place. Let’s have a look on how to use these recovery codes.
Launch your application and supply user name password. On supplying correct details, you will be asked for Authentication Key as shown below:
 















Now click on the given hyperlink ‘log in with recovery code.’ which will further ask you to enter your recovery code. Pick any one of the recovery keys which were generated for you and enter in the given text box as shown below:















As soon as you will click on Login button, you will see that you are logged in. Aren’t you happy, even after losing your phone 😉.
Now 2FA is perfectly set up, you can go and reset your recovery code anytime.

Please note, any recovery code which were generated can be use only once but one can generate recovery code any number of times.

Hope you enjoyed learning!

Wednesday, April 11, 2018

All about Tag Helpers in ASP.NET Core 2.0

This time rather than jumping directly into the topic, let's have a look at the Login form code which you must have definitely seen while working on MVC application.


What do you think about the above code snippet?

Indeed, it works alright, but there are few problems with this. But the major problem is its a bit messy and difficult to read due to excessive use of @. So, now we have understood the problem, what is the solution? Here comes the Tag Helpers for our rescue. Let's quickly have a look at the code generated by the ASP.NET Core framework for the same functionality:




















The above code looks much cleaner. Isn’t it? If it looks interesting to you, we should learn more about it.
What are Tag Helpers
Tag Helpers are classes written in C# but are attached to HTML elements in order to run server-side code from Razor view. In other words, view created in HTML has its presentation logic defined in C#, which is ultimately executed on the web server. Examples of common built-in Tag Helpers are Anchor tag, Environment tag, Cache tag, etc. Understood...Not Understood...Confused? 
No worries. As we will proceed further, things will be much clearer.
Using Tag Helpers
So, how do we go about using Tag Helpers? In order to use the inbuilt or custom Tag Helpers, one has to first reference Tag Helper library named Microsoft.AspNetCore.Mvc.TagHelpers. It can also be taken from Nuget. Once referenced, import it inside _ViewImports.cshtml using @AddTagHelper directive as shown below:

@addTagHelper *,Microsoft.AspNetCore.Mvc.TagHelpers            
In the above line, all the Tag helpers will be imported which are mentioned in 'Microsoft.AspNetCore.Mvc.TagHelpers' assembly. As mentioned in my previous article, whatever is referenced/imported inside _ViewImports.cshtml will be available for all the views. If you don't want any of your views to use globally imported Tag Helpers, you can use @removeTagHelper in the respective view.
Where can I use Tag Helpers
Majority of Tag Helper use cases fall into one of these categories: 1) Take existing HTML elements and customize their output  2) Define totally new elements with custom or not output, i.e. Environment
Creating Custom Tag Helpers
Now we got a basic idea of what is Tag Helper, how about creating our own Tag Helper. Let's go ahead and quickly create our own Tag Helper step by step. I'll take a very simple scenario, in which we will introduce a simple tag named 'Appreciate' which will take the value as person name and same will be displayed on the screen with some nice appreciation.
Create a new class named AppreciateTagHelper and add the code as shown below:
       
  1. public class AppreciateTagHelper:TagHelper  
  2. {  
  3.         private const string appreciationText = "Great work";  
  4.         public string PersonName { getset; }  
  5.         public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)  
  6.         {  
  7.             output.TagName = "Appreciation";  
  8.             string message = $"{appreciationText}, {PersonName}";   
  9.             var attribute = new TagHelperAttribute(name: "Label", value: message);  
  10.             output.Attributes.Add(attribute);  
  11.             output.Content.SetContent(message);  
  12.         }      
  13. }                  
 
Next is to import the newly created Tag Helper and that can be done by adding a line in _ViewImports.cshtml file as shown below:
  1. @addTagHelper *,CustomTagHelper  
Then last is to update the respective view and the code for that is:
         
  1. <appreciate person-name="Shweta"></appreciate>      
 
We are all set with our custom Tag Helper and now it's time to view it in a browser. Quickly run the application and verify the output. You would be able to see the output as shown below:












Takeaways: 

1) One has the benefit of getting away from the @ symbol in RAzor view and code looks cleaner, maintainable and readable.
2) Tag Helpers are not a replacement of HTML helpers.
References:
Hope you enjoyed knowing about Tag Helpers.

Tuesday, April 3, 2018

Configure vs ConfigureServices in ASP.NET Core 2.0


Both words sound similar but there is a very thin line which differentiates these two. Let’s have a look at key differences between these two methods.


Configure
ConfigureServices
Main purpose
Does all the initial setup
Does service configurations
Default Location
Resides in Startup.cs
Resides in Startup.cs
Execution sequence
Hits prior to ConfigureServices
Hits after Configure
Ordering
Order of steps mentioned in this method matters
Order of the statements written to add services doesn’t matter
HTTP request
HTTP request first hits in this method
                                 -
Parameters
Configure(IApplicationBuilder app, IHostingEnvironment env)
ConfigureServices(IServiceCollection services)
Middleware
Setting up all the middleware are done in this method
                                 -
Services
 -           
All the required services are added in this method

Note: All the services which are added to IServiceCollection can be utilized across the application.

Tuesday, March 20, 2018

All About Pages In ASP.NET Core 2.0

I hope while working on Razor pages, one thing you have noticed is @page. 

Let’s say you added a new page (named Sample.cshtml) in Visual Studio Code in your existing application. Once the page is added, we will get an empty editor window on the right side pane where we are going to write code for our page.

In order to make things simple, I’m adding very simple HTML code:
       
 <h1> Welcome to my page </h1>       
 
Now, save the application and run.



Oops 404! Any idea why we end up looking at such a weird page?

Well, @page is holding this magic. Basically, none of the Razor pages will be considered as pages until and unless they are decorated as @page in the very first line.

But as soon as we append the @page in our newly added Sample.cshtml page, things will work as expected.

Next, we will quickly look at a few of the files which are added by default under a Pages folder with some pre-specified lines of code.























_ViewStart.cshtml:
This file contains the code which runs for every View. By default, it contains only 1 line of code as shown below, which is showing the layout page for every page.
@{
Layout = "_Layout";
}   
_ViewImports.cshtml:
This file contains all the namespaces which are to be used by every view. So, rather than adding same reference on top of each and every View, it can be moved to _viewImports.cshtml. By default, this file contains the below lines of code where WebApplciation1 is the name of my application.
       
  @using WebApplication1  
  @namespace WebApplication1.Pages  
  @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers       
 
_ValidationScriptsPartial.cshtml:
This file contains validation scripts in the form of a partial view. By default, this file contains the below code:
<environment include="Development">   <script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>   <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>   </environment>  
<environment exclude="Development">      <script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.14.0/jquery.validate.min.js"         asp-fallback-src="~/lib/jquery-validation/dist/jquery.validate.min.js"         asp-fallback-test="window.jQuery && window.jQuery.validator"         crossorigin="anonymous"         integrity="sha384-Fnqn3nxp3506LP/7Y3j/25BlWeA3PXTyT1l78LjECcPaKCV12TsZP7yyMxOe/G/k">      </script>      <script src="https://ajax.aspnetcdn.com/ajax/jquery.validation.unobtrusive/3.2.6/jquery.validate.unobtrusive.min.js"         asp-fallback-src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"         asp-fallback-test="window.jQuery && window.jQuery.validator && window.jQuery.validator.unobtrusive"         crossorigin="anonymous"         integrity="sha384-JrXK+k53HACyavUKOsL+NkmSesD2P+73eDMrbTtTk0h4RmOF8hF8apPlkp26JlyH">      </script>   </environment>        
Now if this validation script has to be used in any View then it can be done using the RenderPartialAsync method as shown below:
       
  @{await Html.RenderPartialAsync("_ValidationScriptsPartial"); }        
 
_Layout.cshtml:
This file is for layout of the application and contains a lot of code which is required to create a layout for our application. The most important method in this file is @RenderBody() which embeds other views into it.

I hope you enjoyed reading about Pages. 

Tuesday, March 13, 2018

Mapping Similar Objects In ASP.NET Core 2.0

This post is about Automapper. As its name suggests, it will do some sort of mapping. Now, the question is, what sort of mapping? Well, this mapping is all about mapping the properties of two objects with each other. If you have worked on MVC, you must have come across the scenario, where the situation demands you to map properties of the model with the properties of ViewModel. More...