When it comes to developing secure web applications, implementing a robust user authentication and authorization system is paramount. Fortunately, ASP.NET Core provides an integrated framework dubbed Identity that simplifies this task. In this blog, we will take a closer look at how to get started with ASP.NET Core Identity, set up user authentication, and incorporate role-based authorization.
What is ASP.NET Core Identity?
ASP.NET Core Identity is a membership system that adds user login functionality to your application. It includes features for managing user accounts, storing user information, handling password hashing, and providing responses to unauthorized requests.
Setting Up Your Application
Let’s kick things off by creating a new .NET Core application and setting up ASP.NET Core Identity. You can create a new project via the .NET CLI using the following command:
dotnet new webapp -n SecureApp --no-https
This will create a new Razor Pages application. Navigate to the project folder:
cd SecureApp
Now, let’s add the necessary Identity packages:
dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore dotnet add package Microsoft.EntityFrameworkCore.SqlServer dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
Configuring Identity in Startup.cs
Next, we need to configure services and middlewares in our Startup.cs
. Open the file and modify the ConfigureServices
method to add Identity:
public void ConfigureServices(IServiceCollection services) { services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddIdentity<IdentityUser, IdentityRole>() .AddEntityFrameworkStores<ApplicationDbContext>() .AddDefaultTokenProviders(); services.AddControllersWithViews(); }
Make sure to set up your ApplicationDbContext
class to inherit from IdentityDbContext
. The following code demonstrates how to do this:
using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; public class ApplicationDbContext : IdentityDbContext<IdentityUser> { public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } }
Also, don't forget to configure your database connection string in the appsettings.json
file:
{ "ConnectionStrings": { "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=SecureApp;Trusted_Connection=True;MultipleActiveResultSets=true" } }
Setting Up User Registration and Login
Now that we have set up the Identity framework, let’s create pages for user registration and login. In the Pages
folder, create a new Razor Page named Register.cshtml.cs
:
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using System.Threading.Tasks; public class RegisterModel : PageModel { private readonly UserManager<IdentityUser> _userManager; public RegisterModel(UserManager<IdentityUser> userManager) { _userManager = userManager; } [BindProperty] public string Username { get; set; } [BindProperty] public string Password { get; set; } public void OnGet() { } public async Task<IActionResult> OnPostAsync() { var user = new IdentityUser { UserName = Username }; var result = await _userManager.CreateAsync(user, Password); if (result.Succeeded) { return RedirectToPage("Login"); } return Page(); } }
For the login functionality, create another Razor Page called Login.cshtml.cs
:
public class LoginModel : PageModel { private readonly SignInManager<IdentityUser> _signInManager; public LoginModel(SignInManager<IdentityUser> signInManager) { _signInManager = signInManager; } [BindProperty] public string Username { get; set; } [BindProperty] public string Password { get; set; } public void OnGet() { } public async Task<IActionResult> OnPostAsync() { var result = await _signInManager.PasswordSignInAsync(Username, Password, isPersistent: false, lockoutOnFailure: false); if (result.Succeeded) { return RedirectToPage("Index"); } return Page(); } }
Role-Based Authorization
ASP.NET Core Identity also allows us to implement role-based authorization easily. Here’s how to manage roles in your application:
- Create roles in the database.
- Assign roles to users.
- Protect resources using role-based authorization.
To create roles, you can use the RoleManager
class provided by Identity. Add the following code to a service or to your Startup.cs
in the Configure
method:
var roleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>(); string[] roleNames = { "Admin", "User" }; IdentityResult roleResult; foreach (var roleName in roleNames) { var roleExist = await roleManager.RoleExistsAsync(roleName); if (!roleExist) { roleResult = await roleManager.CreateAsync(new IdentityRole(roleName)); } }
To protect certain pages or APIs with these roles, simply use the [Authorize(Roles = "Admin")]
attribute over your Razor Page or controller actions.
Accessing User Information
Finally, to get information about the logged-in user, you can access the User
property provided by the base PageModel
or Controller
class:
public class IndexModel : PageModel { public void OnGet() { var userName = User.Identity.Name; // Use this information as needed } }
By implementing these steps, we now have a basic user authentication system in place, along with role management that can secure our application's resources by limiting access based on user roles.
That’s a wrap on securing .NET Core applications with Identity!