Implementing Authentication in ASP.NET Core MVC

This tutorial guides you through the process of adding authentication to your ASP.NET Core MVC application. We'll cover common scenarios, including form-based login and the integration of external authentication providers.

Core Concepts

Authentication is the process of verifying the identity of a user. In ASP.NET Core, this is typically achieved through:

Step-by-Step Implementation

1. Project Setup

Create a new ASP.NET Core MVC project:

Use the ASP.NET Core project template. Ensure you select the "Individual User Accounts" option during creation if you want ASP.NET Core Identity pre-configured.

dotnet new mvc --auth Individual -o MyAuthApp
Configure Services in Startup.cs (or Program.cs in .NET 6+)

You'll need to register the Identity services and configure the authentication options. For .NET 6+, this is primarily done in Program.cs.

Ensure you have added the necessary NuGet packages: Microsoft.AspNetCore.Identity.EntityFrameworkCore and Microsoft.EntityFrameworkCore.Tools.

// In Program.cs (.NET 6+)
builder.Services.AddDbContext(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

builder.Services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores();

builder.Services.AddControllersWithViews();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication(); // Crucial: enables authentication middleware
app.UseAuthorization();  // Crucial: enables authorization middleware

app.MapRazorPages(); // If using Razor Pages for auth UI
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();
Add migrations and update the database:

ASP.NET Core Identity uses Entity Framework Core to manage user data. You need to create and apply migrations.

dotnet ef migrations add InitialCreate
dotnet ef database update

2. User Interface for Authentication

The "Individual User Accounts" template automatically generates views for:

These are typically located in the Areas/Identity/Pages/Account folder if you used Razor Pages alongside MVC, or within controllers and views if you opted for a pure MVC structure.

3. Protecting Routes

You can protect controllers or individual actions using the [Authorize] attribute.

using Microsoft.AspNetCore.Authorization;

[Authorize] // This controller requires authentication for all actions
public class AccountController : Controller
{
    // ... actions
}

public class ProtectedController : Controller
{
    [Authorize] // This specific action requires authentication
    public IActionResult SecretData()
    {
        return View();
    }

    [AllowAnonymous] // This action is publicly accessible
    public IActionResult PublicInfo()
    {
        return View();
    }
}

If an unauthenticated user tries to access a protected resource, they will typically be redirected to the login page configured in your authentication settings.

4. Customizing Authentication

4.1. Cookie Authentication

By default, ASP.NET Core Identity uses cookie authentication. You can configure its behavior:

// In Program.cs
services.AddAuthentication(options =>
{
    options.DefaultScheme = IdentityConstants.ApplicationScheme;
    options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
})
.AddCookie(IdentityConstants.ApplicationScheme, options =>
{
    options.Cookie.HttpOnly = true;
    options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
    options.LoginPath = "/Account/Login"; // Default path
    options.AccessDeniedPath = "/Account/AccessDenied";
});

4.2. External Authentication Providers (OAuth/OpenID Connect)

Integrating with providers like Google, Facebook, or Microsoft is common.

Example: Google Authentication

  1. Obtain client ID and client secret from the provider's developer portal.
  2. Add the appropriate NuGet package (e.g., Microsoft.AspNetCore.Authentication.Google).
  3. Configure the service in Program.cs:
// In Program.cs
builder.Services.AddAuthentication().AddGoogle(googleOptions =>
{
    googleOptions.ClientId = builder.Configuration["Authentication:Google:ClientId"];
    googleOptions.ClientSecret = builder.Configuration["Authentication:Google:ClientSecret"];
});

Store your secrets securely in appsettings.json or user secrets.

// appsettings.json
{
  "Authentication": {
    "Google": {
      "ClientId": "YOUR_CLIENT_ID",
      "ClientSecret": "YOUR_CLIENT_SECRET"
    }
  }
}

You'll need to add buttons or links in your login view to initiate the external authentication flow.

5. Claims and Roles

Beyond basic identity, you can assign users claims (attributes like "Admin" or "Country") and roles (groupings like "Administrators" or "Users").

You can authorize based on claims or roles:

// Authorize by Role
[Authorize(Roles = "Administrator")]
public IActionResult AdminPanel() { ... }

// Authorize by Claim
[Authorize(Policy = "RequireAdminClaim")]
public IActionResult RestrictedFeature() { ... }

You typically define authorization policies in Program.cs (or Startup.cs):

// In Program.cs
builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("RequireAdminClaim", policy =>
        policy.RequireClaim("IsAdmin", "true")); // Example: user must have an "IsAdmin" claim with value "true"
});

Conclusion

Implementing authentication in ASP.NET Core MVC is a robust process that offers significant flexibility. By leveraging ASP.NET Core Identity and its middleware, you can build secure and user-friendly applications.

Remember to always handle credentials securely and follow best practices for authorization.