在 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)
{
}
}
這樣的配置可以確保你能夠靈活地使用基於角色的策略,限制訪問特定資源,使應用更具安全性和可控性。