在ASP.Net Core中内置具有自定义表功能的ASP.Net Identity [英] ASP.Net Identity built in functions with custom tables in ASP.Net Core

查看:105
本文介绍了在ASP.Net Core中内置具有自定义表功能的ASP.Net Identity的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在.Net 2.1 Framework上使用ASP.Net Core Web Api 2 我有自定义的AppUsers和AppRoles表,并与桥表AppUserRoles链接

I am using ASP.Net Core Web Api 2 on .Net 2.1 Framework I have custom AppUsers and AppRoles tables, linked with bridge table AppUserRoles

我的主要问题是我想使用[Authorize(Roles = "UserRole")] 由于User.Identity工作正常,并且我从User.Identity.Name获取用户ID,所以我认为可以通过某种方法设置角色并在控制器请求之前检查角色,或者使用User.IsInRole("UserRole")在控制器内部进行检查.

My main problem is that I want to use [Authorize(Roles = "UserRole")] As User.Identity is working fine and I am getting user Id from User.Identity.Name I thought there was some way to set roles and check them before controller request, or to use User.IsInRole("UserRole") for checking inside controller.

是否可以以某种方式重建或重载.IsInRole("UserRole")函数或[Authorize(Roles = "UserRole")]属性后台函数,所以我可以编写自己的逻辑来检查用户权限?或者将我的表设置为要使用的默认表,这样它就可以在自逻辑上工作. 对于我的任务,速度和安全性息息相关.

Is it possible to rebuild or overload .IsInRole("UserRole") function or [Authorize(Roles = "UserRole")] attribute background function somehow, so I could write my own logic to check user permissions? Or to set my tables as default tables to use, so it could work on self logic. For my task, speed matters as much as security.

如果有其他方法,我愿意提出建议,但我的观点也是要对这些功能有更好的了解.

I am open to suggestions, if there is some other way, but my point also is to get better understanding in those functions.

推荐答案

您不需要覆盖Authorize或IsInRole.只需将角色声明为User.Identity即可.您可以使用中间件来进行声明转换.

You don't need to override Authorize or IsInRole. Just add the roles as claim to the User.Identity. You can use middleware to do the claims transformation.

作为示例,我建议您看一下 PolicyServer .它具有相同的方法. 免费的OSS版本在中间件中添加了声明.

As an example I suggest you take a look at the PolicyServer. It has the same approach. The free OSS version adds claims in the middleware.

/// Add the policy server claims transformation middleware to the pipeline.
/// This middleware will turn application roles and permissions into claims
/// and add them to the current user
public static IApplicationBuilder UsePolicyServerClaims(this IApplicationBuilder app)
{
    return app.UseMiddleware<PolicyServerClaimsMiddleware>();
}

PolicyServerClaimsMiddleware在哪里:

Where PolicyServerClaimsMiddleware is:

public class PolicyServerClaimsMiddleware
{
    private readonly RequestDelegate _next;

    /// <summary>
    /// Initializes a new instance of the <see cref="PolicyServerClaimsMiddleware"/> class.
    /// </summary>
    /// <param name="next">The next.</param>
    public PolicyServerClaimsMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    /// <summary>
    /// Invoke
    /// </summary>
    /// <param name="context">The context.</param>
    /// <param name="client">The client.</param>
    /// <returns></returns>
    public async Task Invoke(HttpContext context, IPolicyServerRuntimeClient client)
    {
        if (context.User.Identity.IsAuthenticated)
        {
            var policy = await client.EvaluateAsync(context.User);

            var roleClaims = policy.Roles.Select(x => new Claim("role", x));
            var permissionClaims = policy.Permissions.Select(x => new Claim("permission", x));

            var id = new ClaimsIdentity("PolicyServerMiddleware", "name", "role");
            id.AddClaims(roleClaims);
            id.AddClaims(permissionClaims);

            context.User.AddIdentity(id);
        }
        await _next(context);
    }
}

从启动开始:

public void ConfigureServices(IServiceCollection services)
{

    services.AddMvcCore(options =>
    {
        // workaround: https://github.com/aspnet/Mvc/issues/7809
        options.AllowCombiningAuthorizeFilters = false;
    })
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
    .AddAuthorization();

    // This is not relevant for you, but just to show how policyserver is implemented.
    // The bottom line is that you can implement this anyway you like.

    // this sets up the PolicyServer client library and policy
    // provider - configuration is loaded from appsettings.json
    services.AddPolicyServerClient(Configuration.GetSection("Policy"))
        .AddAuthorizationPermissionPolicies();

}

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

    // add this middleware to make roles and permissions available as claims
    // this is mainly useful for using the classic [Authorize(Roles="foo")] and IsInRole functionality
    // this is not needed if you use the client library directly or the new policy-based authorization framework in ASP.NET Core
    app.UsePolicyServerClaims();

    app.UseMvc();
}

该示例从文件读取配置,这也可能是您的一个选择.但是您也可以实现存储并添加一些缓存.

The example reads the configuration from file, which may be an option for you as well. But you can also implement a store and add some caching.

如果要添加一些授权逻辑,则建议您创建一些策略和授权处理程序.只需确保在正确的位置使用中间件即可.

If you want to add some authorization logic then I suggest you create some policies and authorization handlers. Just make sure that you use the middleware at the right place.

一种替代方法是使用您自己的过滤器/属性:

An alternative is to use your own filter / attribute:

//using Microsoft.AspNetCore.Authorization;
//using Microsoft.AspNetCore.Mvc;
//using Microsoft.AspNetCore.Mvc.Filters;

public class CustomPolicyAttribute : AuthorizeAttribute, IAsyncAuthorizationFilter
{
    private int _number;

    public CustomPolicyAttribute(int number)
    {
        _number = number;
    }

    public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
    {
        var service = (IAuthorizationService)context.HttpContext.RequestServices.GetService(typeof(IAuthorizationService));

        var requirement = new CustomRequirement
        {
            Number = _number
        };
        var result = await service.AuthorizeAsync(context.HttpContext.User, null, requirement);
        if (!result.Succeeded)
            context.Result = new ForbidResult();
    }
}

您可以通过两种方式使用它.用作属性(等效的Authorize):

You can use this in a couple of ways. Use as attribute (the Authorize equivalent):

[CustomPolicy(1)]
public async Task<IActionResult> DoSomething()
{

}

或手动验证(等效于IsInRole):

Or validate manually (the IsInRole equivalent):

public class MyController : Controller
{
    private readonly IAuthorizationService _authorizationService;

    public MyController(IAuthorizationService authorizationService)
    {
        _authorizationService = authorizationService;
    }

    public async Task<IActionResult> DoSomething(int number)
    {
        var requirement = new CustomRequirement
        {
            Number = number
        };
        var result = await _authorizationService.AuthorizeAsync(User, null, requirement);
        if (!result.Succeeded) return Forbid();

        return View("success");
    }
}

您将需要AuthorizationHandler来评估需求:

You will need an AuthorizationHandler to evaluate the requirement:

public class CustomRequirementHandler : AuthorizationHandler<CustomRequirement>
{
    // Use dependency injection to include services you need.
    public CustomRequirementHandler ()
    {
    }

    protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, CustomRequirement requirement)
    {
        // Add your advanced check here.
        if (requirement.Number > 0)
        {
            context.Succeed(requirement);
        }
    }
}

并在启动时注册它:

services.AddTransient<IAuthorizationHandler, CustomRequirementHandler>();

在处理程序中,您可以添加自己的逻辑.在这种情况下,您不必添加策略,也不必添加授权作为声明.

In the handler you can add your own logic. In that case you won't have to add policies and you don't have to add authorization as claims.

这篇关于在ASP.Net Core中内置具有自定义表功能的ASP.Net Identity的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆