文章

第24天:驗證與授權

課程簡介

今天的課程將重點介紹 ASP.NET Core 中的 驗證(Authentication)授權(Authorization) 機制。這兩個功能對於確保應用程式的安全性至關重要。驗證是指確認使用者身份的過程,而授權則是控制使用者在系統中可以執行哪些操作。


學習目標

  • 了解驗證與授權的基本概念
  • 學習如何在 ASP.NET Core 中實作驗證機制
  • 掌握基於角色或權限的授權控制
  • 建立一個簡單的登入系統

課程內容

1. 驗證與授權的基本概念

  • 驗證(Authentication):確認使用者的身份是否合法,例如使用登入系統進行身份驗證。
  • 授權(Authorization):根據使用者的身份,決定其是否有權執行某些操作或訪問某些資源。

驗證和授權經常配合使用,先驗證使用者的身份,再根據授權規則來決定使用者的操作權限。


2. 使用 ASP.NET Core Identity 進行驗證

ASP.NET Core 提供了 ASP.NET Core Identity,一個完整的身份驗證與管理框架。它可以輕鬆地管理使用者登入、註冊、密碼管理等功能。

設定 Identity:

首先,我們需要在專案中安裝 ASP.NET Core Identity 的必要元件,並將其設定在 Startup.cs 檔案中。

設定 Identity 的 Startup.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public void ConfigureServices(IServiceCollection services)
{
    // 註冊 Entity Framework 和 Identity 服務
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddIdentity<ApplicationUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();

    services.AddControllersWithViews();
}

public void Configure(IApplicationBuilder app)
{
    app.UseAuthentication(); // 啟用身份驗證
    app.UseAuthorization();  // 啟用授權
    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

這段程式碼設定了 ASP.NET Core Identity 的服務,並啟用了身份驗證和授權。

使用 Identity 註冊與登入

  • 註冊頁面:允許使用者建立帳號。
  • 登入頁面:讓已註冊的使用者登入系統,並生成身份驗證 Cookie。

這些頁面可以使用 Identity Scaffold 自動生成,或是自行編寫控制器和視圖來管理註冊與登入。


3. 基於 Cookie 的驗證

ASP.NET Core 中的身份驗證系統經常使用 Cookie 驗證 來保持使用者的登入狀態。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie(options =>
        {
            options.LoginPath = "/Account/Login";
            options.AccessDeniedPath = "/Account/AccessDenied";
        });
}

public void Configure(IApplicationBuilder app)
{
    app.UseAuthentication();
    app.UseAuthorization();
}

這段程式碼啟用了 Cookie 驗證,並設定了當使用者未登入時,會被重定向到登入頁面。


4. 基於角色的授權

在 ASP.NET Core 中,我們可以透過 角色(Roles) 來進行授權控制。每個使用者可以被分配一個或多個角色,系統根據使用者所屬的角色來決定其權限。

設定角色:

首先,必須在 Identity 註冊階段,為使用者分配角色。

1
2
3
4
5
6
public async Task<IActionResult> AssignRole(string userId, string roleName)
{
    var user = await _userManager.FindByIdAsync(userId);
    await _userManager.AddToRoleAsync(user, roleName);
    return Ok();
}

基於角色的授權控制:

在控制器或動作方法中,可以透過 [Authorize] 屬性來限制訪問權限。例如:

1
2
3
4
5
[Authorize(Roles = "Admin")]
public IActionResult AdminPanel()
{
    return View();
}

這段程式碼表示只有具有 Admin 角色的使用者才能訪問此控制器方法。

多角色授權:

1
2
3
4
5
[Authorize(Roles = "Admin,Manager")]
public IActionResult ManagementPanel()
{
    return View();
}

這裡的授權設定允許 AdminManager 角色的使用者訪問該方法。


5. 基於權限的授權

除了基於角色的授權,ASP.NET Core 也支援更細粒度的 基於權限的授權,可以針對某些具體的行為或資源進行授權控制。

設定基於權限的授權:

可以建立自訂的授權需求,並在應用程式中註冊。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class AgeRequirement : IAuthorizationRequirement
{
    public int MinimumAge { get; }

    public AgeRequirement(int minimumAge)
    {
        MinimumAge = minimumAge;
    }
}

public class AgeRequirementHandler : AuthorizationHandler<AgeRequirement>
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, AgeRequirement requirement)
    {
        if (!context.User.HasClaim(c => c.Type == ClaimTypes.DateOfBirth))
        {
            return Task.CompletedTask;
        }

        var dateOfBirth = Convert.ToDateTime(context.User.FindFirst(c => c.Type == ClaimTypes.DateOfBirth).Value);

        int calculatedAge = DateTime.Today.Year - dateOfBirth.Year;
        if (calculatedAge >= requirement.MinimumAge)
        {
            context.Succeed(requirement);
        }

        return Task.CompletedTask;
    }
}

註冊自訂授權需求:

1
2
3
4
5
services.AddAuthorization(options =>
{
    options.AddPolicy("Over18", policy =>
        policy.Requirements.Add(new AgeRequirement(18)));
});

使用自訂授權需求:

1
2
3
4
5
[Authorize(Policy = "Over18")]
public IActionResult RestrictedContent()
{
    return View();
}

這樣的設計可以根據具體的需求自訂授權邏輯,使應用程式的安全性控制更加靈活。


6. 實作練習

  1. 建立註冊與登入系統
    • 實作一個簡單的使用者註冊與登入功能,並使用 Cookie 驗證來保持登入狀態。
    • 在登入成功後,將使用者重定向到一個受保護的頁面。
  2. 基於角色的授權
    • 建立兩個角色(例如:Admin 和 User),並將不同的頁面限制給特定角色使用者訪問。
    • 驗證當未授權的使用者訪問受限頁面時,會被重定向到登入或錯誤頁面。
  3. 基於權限的授權
    • 自訂一個授權需求,根據使用者的特定屬性(例如:年齡或其他數據)來決定其是否有權訪問某些資源。

教學重點

  • 理解驗證與授權的核心概念,並掌握如何在 ASP.NET Core 中實作身份驗證系統。
  • 掌握基於角色和權限的授權機制,實現更精細的使用者權限控制。
  • 實作一個完整的登入、註冊系統,並透過角色與授權來控制應用程式的訪問權限。

接下來的課程將進一步探討如何使用 單元測試與集成測試 來確保 ASP.NET Core 應用程式的正確性和穩定性。

本文章以 CC BY 4.0 授權