In the recent new releases of the .NET Framework, Microsoft provides a new authentication process or mechanism called ASP.NET Core Identity. ASP.NET Core Identity is a membership system that provides login functionality including user registration in any ASP.NET Core applications. This new authentication system is intended to replace the existing membership system of classic ASP.NET. This new authentication system is based on the OWIN (Open Web Interface for . NET) library. In this article, we will discuss the below topics
- Overview of ASP.NET Identity
- Benefits of ASP.NET Core Identity
- Limitations of ASP.NET Identity
- How to create an application using Identity Authentication in ASP.NET Core
OVERVIEW OF ASP.NET IDENTITY
In ASP.NET, developers normally use Forms Authentication or Windows Authentication along with Membership, Roles, and Profile features to maintain the security of their web application. But as the years passed, these techniques became inefficient to deal with the new changing requirements related to web application security. Like today, most websites provide us login authentication along with social site authentication like Facebook, Google, etc. Also, some applications or websites provide a custom authentication mechanism like OAuth-based authentication. ASP.NET membership techniques do not have any process to deal with this type of authentication requirement. Besides this, there are also some other disadvantages of ASP.NET Membership techniques like rigid database structure, and complex object models.
So, to overcome this situation, Microsoft introduced a new authentication technique called ASP.NET Identity. This authentication technique is based on the OWIN (Open Web Interface for . Net) Library. In the ASP.NET Identity system, there is a total of six important parts available as related to the local user accounts. They are –
- User
- Role
- User Manager
- Role Manager
- Authentication Manager
- Entity Framework DBContent
User Objects always represent the Login User information which contains the user ID, password, as well as, profile information of any user. In ASP.NET Identity, the IdentityUser class always is used to capture the basic authentication information related to the user. If we want to store any custom information like profile details etc., then we can create our custom class which must be inherited from the IdentityUser as a base class.
Role Objects represent user role objects. In ASP.NET Identity, the IdentityRole class is used to provide the information related to the user role.
User Manager represents how to operate or manage the user information or account like creating user accounts, removing user accounts, changing the password, adding a role to the user, removing a role from the user, etc. These types of user-related operations can be performed by using a user manager. In Asp.Net Identity, the UserManager class can be used for this purpose.
Role Manager is representing how to manage the roles related to the user. Using Role Manager, we can perform different role-related operations like creating a role, removing a role, etc. In ASP.NET Identity, the RoleManager class can be used for this purpose.
So, in the above discussion, all the classes are related to users and roles. These classes do not perform any authentication operations. Authenticating a user login or signing depends on the Authentication Manager. In ASP.NET Identity, the IAuthenticationManager interface represents an authentication manager.
Benefits of ASP.NET Core Identity
ASP.NET Core Identity has many advantages or benefits like the following.
- ASP.NET Core Identity provides separation of storage. It means ASP.NET Core Identity provides a separate storing concept for identity information (like username, and password) and code for security implementations (like password hashing, password validation, etc.).
- Most of the APIs in the ASP.NET Core Identity are asynchronous.
- In ASP.NET Core Identity, we can implement custom password hashing using UserManager APIs with the help of the IPasswordHasher interface.
- ASP.NET Core Identity supports any type of external login provider like Facebook, Google, etc. to authenticate user details.
- Now, ASP.NET Core Identity implements Entity Framework to store the user information.
Drawbacks of ASP.NET Core Identity
Despite the above benefits, ASP.NET Core Identity has some drawbacks like,
- In this system, if a user is authenticated, then we can retrieve the custom-defined user properties in the claims collections of the ClaimsIdentity.
- There are no APIs to perform any custom-based query.
- It does not support the systems that use Non-Entity Framework or use NoSql Databases.
Create an application using Identity Authentication in ASP.NET Core
Step 1. First, open Visual Studio 2017 and click File --> New --> Project.
Step 2. Select the Web Application project and click the OK button.
Step 3. Now, in the Project Template Dialog box, Select Web Application (Model-View-Controller) Project Template.
Step 4. After selecting the Project Template, click on the "Change Authentication" button.
Step 5. In the "Change Authentication" box, Select the individual User Accounts options and then click the OK button.
Step 6. After the above step, Visual Studio creates projects with default templates.
Step 7. Now, open the appsettings.json file and provide the database name, database server name, and related credentials to establish the connection with the database.
{
"ConnectionStrings": {
"DefaultConnection": "Server=xxx;Database=DemoAuthentication;Trusted_Connection=True;MultipleActiveResultSets=true;user id=sa;password=xxxxxx;"
},
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*"
}
Step 8. Now, open the Package Manager Console from the Tools menu and run the below commands one by one.
add migration test1
update-database
Step 9. After successfully running the above commands, go to the SQL Server and check that a related database has been created.
Step 10. Now, build and run the applications. After running the application in the browser, click on the "Sign In" button.
Step 11. Since we do not have any login credentials, we need to register first and then try to log in.
Step 12. For that, click on the link Register as a New User.
Step 13. In the Registration form, provide a Username and Password to register.
Step 14. After successful registration, the application allows us to log into the application.
Step 15. Now, return to the SQL server and run a query to select records from the table dbo.AspNetUsers
Step 16. This Table contains the registered user details as below.
Scaffolding the Login (Shared Views)
Now, if we check our existing project code, we do not find any Login or Register user UI. but when we check the views folder, we find there is a shared view called _LoginPartial.cshtml. The shared view file contains the link details related to the Login and Register User UI. Actually, in this application, log-in and its related to all the UIs used as a shared UI. So, it takes the reference of that application and uses it accordingly. I have already discussed the basic concept of shared view in my previous article.
Now, if we want to customize the Login Form, then we can scaffold the Login or any other forms.
Step 1. First, select the Views folder and click and Select Add --> New Scaffold Item
Step 2. In the Scaffold Dialog Box, Select the Identity Option and Click on the Ok Button
Step 3. Now, the Identity Dialog Box appears when we can select any of the available files to override. We will Select Account\Login Form and Click on the Add Button.
Step 4. The Selected Identity Form is added under the Identity Folder in the Areas Section.
Step 5. Now we can change some UI design for the Login Page as below
@page
@model LoginModel
@{
ViewData["Title"] = "Log in";
}
<h1>@ViewData["Title"]</h1>
<div class="row">
<div class="col-md-4">
<section>
<form id="account" method="post">
<h4>Existing User Login In</h4>
<hr />
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="Input.Email"></label>
<input asp-for="Input.Email" class="form-control" />
<span asp-validation-for="Input.Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Input.Password"></label>
<input asp-for="Input.Password" class="form-control" />
<span asp-validation-for="Input.Password" class="text-danger"></span>
</div>
<div class="form-group">
<div class="checkbox">
<label asp-for="Input.RememberMe">
<input asp-for="Input.RememberMe" />
@Html.DisplayNameFor(m => m.Input.RememberMe)
</label>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Log in</button>
</div>
<div class="form-group">
<p>
<a id="forgot-password" asp-page="./ForgotPassword">Forgot your password?</a>
</p>
<p>
<a asp-page="./Register" asp-route-returnUrl="@Model.ReturnUrl">Register as a new user</a>
</p>
</div>
</form>
</section>
</div>
</div>
@section Scripts {
<partial name="_ValidationScriptsPartial" />
}
Step 6. Now, we want to implement some password policy like
- Password Length must be at least 8 characters
- Password must contain alphanumeric fields
- Password must contain 1 Unique Character
- Application Default Timeout is 5 mins
To add the above functionality, we need to add the below code in the ConfigureService() in Startup.cs Files.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>()
.AddDefaultUI(UIFramework.Bootstrap4)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.Configure<IdentityOptions>(options =>
{
// Password settings.
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequireUppercase = true;
options.Password.RequiredLength = 8;
options.Password.RequiredUniqueChars = 1;
// Lockout settings.
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
options.Lockout.MaxFailedAccessAttempts = 5;
options.Lockout.AllowedForNewUsers = true;
// User settings.
options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+#";
options.User.RequireUniqueEmail = false;
});
services.ConfigureApplicationCookie(options =>
{
// Cookie settings
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
options.LoginPath = "/Identity/Pages/Account/Login";
options.AccessDeniedPath = "/Identity/Account/AccessDenied";
options.SlidingExpiration = true;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
Now, run the application and check the above settings while registering a new user.
Conclusion
Now, in this article, we discussed the basic concepts of Identity-based Authentication in ASP.NET Core. I hope this will help the readers to understand how to implement identity-based authentication in any application. If anybody has any queries or doubts related to this article, please let me know. Feedback is most welcome related to this article. In the next article, we will discuss how to implement some external authentication in ASP.NET Core.