.NET Core MVC 在授权前的开发中向本地用户添加角色声明

.NET Core MVC add role claim to local user when in development before authorization

我正在寻找一种 "easy" 方法来自动向本地用户添加角色声明以测试我的授权逻辑;也就是说,想要在我的控制器授权之前向本地用户添加一些特定的声明。

我了解到过去可以为控制器完成类似的操作:

#if DEBUG 
protected override void OnAuthorization(AuthorizationContext filterContext)
{
    var roles = new[] { "role-under-test"};
    HttpContext.User = new GenericPrincipal(new GenericIdentity("DebugUser"), roles);
    base.OnAuthorization(filterContext);
}
#endif

然而那是在 .NET Core 之前,而我现在正在从事的工作。慢慢地,我按照自己的方式编写了下面显示的代码,它似乎可以工作,但与上面的示例相比显然要麻烦得多。所以我的问题是是否有人知道实现此目标的更好、更简单的方法?

自定义授权属性:

public class CustomAuthAttribute : RolesAuthorizationRequirement {
    public CustomAuthAttribute(IEnumerable<string> allowedRoles) : base(allowedRoles) { }

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RolesAuthorizationRequirement requirement) {
#if DEBUG
        context.User.AddIdentity(new ClaimsIdentity(new GenericIdentity("DebugUser"), new[] {
            new Claim(ClaimsIdentity.DefaultRoleClaimType, "users"),
            new Claim(ClaimsIdentity.DefaultRoleClaimType, "admins")
        }));
#endif
        return base.HandleRequirementAsync(context, requirement);
    }
}

在Startup.cs

public void ConfigureServices(IServiceCollection services) {
    // ...

    services.AddAuthorization( options =>
        options.AddPolicy("UsersAndAdmins",
            policy => policy.AddRequirements(new CustomAuthAttribute(new []{"users", "admins"}))));
}

然后在控制器中使用它:

[Authorize(Policy = "UsersAndAdmins")]    
public class HomeController : Controller {
    // ...

您想要理赔转换;

写一个看起来像

的声明转换
public class ClaimsTransformer : IClaimsTransformer
{
    public Task<ClaimsPrincipal> TransformAsync(ClaimsTransformationContext context)
    {
        ((ClaimsIdentity)context.principal.Identity).AddClaim(new Claim("Admin", "true"));
        return Task.FromResult(principal);
    }
}

并在 Configure 内连接 startup.cs

app.UseClaimsTransformation(new ClaimsTransformationOptions
{
    Transformer = new ClaimsTransformer()
});

当然,如果它是用于测试,您会将其包装在环境检查中以确保您处于开发环境中:)