Google Code Prettify

ASP.NET Core 中,生成基於角色(Role)的授權

在 ASP.NET Core 中,生成基於角色的授權策略是非常常見的做法。這些策略可以用來限制只有特定角色的用戶才能訪問某些資源。以下是如何生成和使用基於角色的授權策略的完整示例。 步驟 1:設定角色和用戶 首先,你需要確保你的身份驗證系統已經正確設定,並且用戶擁有相關的角色。假設你使用的是 ASP.NET Core Identity,這是如何為用戶分配角色的示例。

    
public class SeedData
{
    public static async Task Initialize(IServiceProvider serviceProvider, UserManager<ApplicationUser> userManager)
    {
        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));
            }
        }

        var user = await userManager.FindByEmailAsync("admin@admin.com");
        if (user == null)
        {
            user = new ApplicationUser
            {
                UserName = "admin@admin.com",
                Email = "admin@admin.com",
            };
            await userManager.CreateAsync(user, "Password123!");
            await userManager.AddToRoleAsync(user, "Admin");
        }
    }
}
   
  

步驟 2:配置角色策略 在 Program.cs 中,你可以配置角色策略。這裡我們會設定一個基於角色的策略,確保只有 Admin 角色的用戶可以訪問某些資源。


var builder = WebApplication.CreateBuilder(args);

// 設定身份驗證和 JWT Bearer
builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = "yourissuer",
        ValidAudience = "youraudience",
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("yoursecretkey"))
    };
});

// 設定授權策略
builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("AdminOnly", policy => policy.RequireRole("Admin"));
});

builder.Services.AddControllers();

var app = builder.Build();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();

步驟 3:在控制器中使用策略 在控制器中應用你定義的策略。你可以使用 [Authorize] 屬性來限制訪問。


using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

[Route("api/[controller]")]
[ApiController]
public class SampleController : ControllerBase
{
    // 只有 Admin 角色的用戶可以訪問這個端點
    [Authorize(Policy = "AdminOnly")]
    [HttpGet("admin")]
    public IActionResult GetForAdmin()
    {
        return Ok("This is an admin endpoint.");
    }

    // 所有經過身份驗證的用戶都可以訪問這個端點
    [Authorize]
    [HttpGet("user")]
    public IActionResult GetForUser()
    {
        return Ok("This is a user endpoint.");
    }
}
    

完整範例 以下是完整的設定,包括初始化角色和用戶、配置授權策略,以及在控制器中使用這些策略的示例:


// Program.cs
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddDbContext(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

builder.Services.AddIdentity()
    .AddEntityFrameworkStores()
    .AddDefaultTokenProviders();

builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = "yourissuer",
        ValidAudience = "youraudience",
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("yoursecretkey"))
    };
});

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("AdminOnly", policy => policy.RequireRole("Admin"));
});

builder.Services.AddControllers();

var app = builder.Build();

using (var scope = app.Services.CreateScope())
{
    var services = scope.ServiceProvider;
    var userManager = services.GetRequiredService>();
    SeedData.Initialize(services, userManager).Wait();
}

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();

// SeedData.cs
public class SeedData
{
    public static async Task Initialize(IServiceProvider serviceProvider, UserManager userManager)
    {
        var roleManager = serviceProvider.GetRequiredService>();

        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));
            }
        }

        var user = await userManager.FindByEmailAsync("admin@admin.com");
        if (user == null)
        {
            user = new ApplicationUser
            {
                UserName = "admin@admin.com",
                Email = "admin@admin.com",
            };
            await userManager.CreateAsync(user, "Password123!");
            await userManager.AddToRoleAsync(user, "Admin");
        }
    }
}

// SampleController.cs
[Route("api/[controller]")]
[ApiController]
public class SampleController : ControllerBase
{
    [Authorize(Policy = "AdminOnly")]
    [HttpGet("admin")]
    public IActionResult GetForAdmin()
    {
        return Ok("This is an admin endpoint.");
    }

    [Authorize]
    [HttpGet("user")]
    public IActionResult GetForUser()
    {
        return Ok("This is a user endpoint.");
    }
}

// ApplicationUser.cs
public class ApplicationUser : IdentityUser
{
}

// ApplicationDbContext.cs
public class ApplicationDbContext : IdentityDbContext
{
    public ApplicationDbContext(DbContextOptions options)
        : base(options)
    {
    }
}

這樣的配置可以確保你能夠靈活地使用基於角色的策略,限制訪問特定資源,使應用更具安全性和可控性。