如何在MVC Core 2.0(AspNetCore.Identity)中创建自定义授权声明验证用户布尔属性
嘿,我来帮你搞定这个自定义声明的事儿!其实步骤很清晰,咱们一步步来:
第一步:在用户登录时注入自定义声明
咱们需要把IsDeveloper这个属性转换成声明,添加到用户的身份凭证里。最规范的方式是通过扩展UserClaimsPrincipalFactory来实现,完全贴合ASP.NET Core Identity的设计逻辑:
- 先写一个自定义的声明工厂类:
using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Options; using System.Security.Claims; using System.Threading.Tasks; public class CustomUserClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationUser> { public CustomUserClaimsPrincipalFactory(UserManager<ApplicationUser> userManager, IOptions<IdentityOptions> optionsAccessor) : base(userManager, optionsAccessor) { } protected override async Task<ClaimsIdentity> GenerateClaimsAsync(ApplicationUser user) { // 先拿到系统默认生成的所有声明 var identity = await base.GenerateClaimsAsync(user); // 把咱们的自定义属性转成声明加进去,这里的类型名称可以自己定义 identity.AddClaim(new Claim("IsDeveloper", user.IsDeveloper.ToString())); return identity; } }
- 然后在
Program.cs里注册这个工厂,让Identity使用它:
builder.Services.AddScoped<IUserClaimsPrincipalFactory<ApplicationUser>, CustomUserClaimsPrincipalFactory>();
如果你不想用工厂,也可以在登录逻辑里手动塞声明(比如AccountController的Login方法),不过这种方式不如工厂优雅:
var user = await _userManager.FindByEmailAsync(model.Email); if (user != null && await _userManager.CheckPasswordAsync(user, model.Password)) { var claims = new List<Claim> { new Claim(ClaimTypes.Name, user.UserName), // 直接添加自定义声明 new Claim("IsDeveloper", user.IsDeveloper.ToString()) }; var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity)); // 后续跳转逻辑... }
第二步:创建专属授权策略
接下来咱们可以把这个声明做成一个可复用的授权策略,这样在控制器或Action上就能一键限制访问了。在Program.cs里配置:
builder.Services.AddAuthorization(options => { options.AddPolicy("DeveloperOnly", policy => // 要求声明类型为IsDeveloper,且值为True policy.RequireClaim("IsDeveloper", "True")); });
第三步:用起来!
现在就可以在需要权限控制的地方直接用这个策略了:
- 控制器级别(整个控制器下的所有Action都需要开发者权限):
[Authorize(Policy = "DeveloperOnly")] public class DeveloperToolsController : Controller { // 这里的所有接口都只有开发者能访问 }
- Action级别(只限制单个Action):
public class HomeController : Controller { [Authorize(Policy = "DeveloperOnly")] public IActionResult DeveloperDashboard() { return View(); } }
额外技巧:代码里直接判断声明
如果需要在业务逻辑里直接判断当前用户是不是开发者,也可以这么写:
var isDeveloper = User.Claims.Any(c => c.Type == "IsDeveloper" && c.Value == "True"); if (isDeveloper) { // 执行开发者专属逻辑 }
另外,建议把声明类型定义成常量,避免拼写错误,比如:
public static class CustomClaimTypes { public const string IsDeveloper = "http://your-app-domain.com/claims/is-developer"; }
之后就用CustomClaimTypes.IsDeveloper代替字符串,更规范。
内容的提问来源于stack exchange,提问作者davewilliams459
相关产品推荐
相关产品推荐

