首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在ASP.NET核心中创建自定义AuthorizeAttribute?

如何在ASP.NET核心中创建自定义AuthorizeAttribute?
EN

Stack Overflow用户
提问于 2015-07-17 04:55:54
回答 10查看 373.4K关注 0票数 561

我正在尝试在ASP.NET核心中创建一个自定义的授权属性。在以前的版本中,可以覆盖

..。但这不再存在于

..。

目前定制AuthorizeAttribute的方法是什么?

我想要完成的事情:我在Authorization头中收到一个会话ID。通过这个ID,我可以知道某个特定的操作是否有效。

EN

回答 10

Stack Overflow用户

发布于 2018-01-12 22:32:05

似乎使用ASP.NET Core2,您可以再次继承

,您只需要实现

(或

):

代码语言:javascript
复制
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class CustomAuthorizeAttribute : AuthorizeAttribute, IAuthorizationFilter
{
    private readonly string _someFilterParameter;

    public CustomAuthorizeAttribute(string someFilterParameter)
    {
        _someFilterParameter = someFilterParameter;
    }

    public void OnAuthorization(AuthorizationFilterContext context)
    {
        var user = context.HttpContext.User;

        if (!user.Identity.IsAuthenticated)
        {
            // it isn't needed to set unauthorized result 
            // as the base class already requires the user to be authenticated
            // this also makes redirect to a login page work properly
            // context.Result = new UnauthorizedResult();
            return;
        }

        // you can also use registered services
        var someService = context.HttpContext.RequestServices.GetService();

        var isAuthorized = someService.IsUserAuthorized(user.Identity.Name, _someFilterParameter);
        if (!isAuthorized)
        {
            context.Result = new StatusCodeResult((int)System.Net.HttpStatusCode.Forbidden);
            return;
        }
    }
}
票数 139
EN

Stack Overflow用户

发布于 2017-05-05 00:52:32

基于Derek Greer

太棒了

答案是,我用枚举做到了这一点。

下面是我的代码示例:

代码语言:javascript
复制
public enum PermissionItem
{
    User,
    Product,
    Contact,
    Review,
    Client
}

public enum PermissionAction
{
    Read,
    Create,
}


public class AuthorizeAttribute : TypeFilterAttribute
{
    public AuthorizeAttribute(PermissionItem item, PermissionAction action)
    : base(typeof(AuthorizeActionFilter))
    {
        Arguments = new object[] { item, action };
    }
}

public class AuthorizeActionFilter : IAuthorizationFilter
{
    private readonly PermissionItem _item;
    private readonly PermissionAction _action;
    public AuthorizeActionFilter(PermissionItem item, PermissionAction action)
    {
        _item = item;
        _action = action;
    }
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        bool isAuthorized = MumboJumboFunction(context.HttpContext.User, _item, _action); // :)

        if (!isAuthorized)
        {
            context.Result = new ForbidResult();
        }
    }
}

public class UserController : BaseController
{
    private readonly DbContext _context;

    public UserController( DbContext context) :
        base()
    {
        _logger = logger;
    }

    [Authorize(PermissionItem.User, PermissionAction.Read)]
    public async Task Index()
    {
        return View(await _context.User.ToListAsync());
    }
}
票数 56
EN

Stack Overflow用户

发布于 2016-11-27 07:46:34

您可以创建自己的AuthorizationHandler来查找控制器和操作上的自定义属性,并将它们传递给HandleRequirementAsync方法。

代码语言:javascript
复制
public abstract class AttributeAuthorizationHandler : AuthorizationHandler where TRequirement : IAuthorizationRequirement where TAttribute : Attribute
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, TRequirement requirement)
    {
        var attributes = new List();

        var action = (context.Resource as AuthorizationFilterContext)?.ActionDescriptor as ControllerActionDescriptor;
        if (action != null)
        {
            attributes.AddRange(GetAttributes(action.ControllerTypeInfo.UnderlyingSystemType));
            attributes.AddRange(GetAttributes(action.MethodInfo));
        }

        return HandleRequirementAsync(context, requirement, attributes);
    }

    protected abstract Task HandleRequirementAsync(AuthorizationHandlerContext context, TRequirement requirement, IEnumerable attributes);

    private static IEnumerable GetAttributes(MemberInfo memberInfo)
    {
        return memberInfo.GetCustomAttributes(typeof(TAttribute), false).Cast();
    }
}

然后,您可以将其用于控制器或操作上所需的任何自定义属性。例如添加权限要求。只需创建自定义属性即可。

代码语言:javascript
复制
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public class PermissionAttribute : AuthorizeAttribute
{
    public string Name { get; }

    public PermissionAttribute(string name) : base("Permission")
    {
        Name = name;
    }
}

然后创建一个要求以添加到您的策略中

代码语言:javascript
复制
public class PermissionAuthorizationRequirement : IAuthorizationRequirement
{
    //Add any custom requirement properties if you have them
}

然后,继承我们之前创建的AttributeAuthorizationHandler,为您的自定义属性创建AuthorizationHandler。它将传递HandleRequirementsAsync方法中所有自定义属性的IEnumerable,这些属性是从您的控制器和操作中累积而来的。

代码语言:javascript
复制
public class PermissionAuthorizationHandler : AttributeAuthorizationHandler
{
    protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionAuthorizationRequirement requirement, IEnumerable attributes)
    {
        foreach (var permissionAttribute in attributes)
        {
            if (!await AuthorizeAsync(context.User, permissionAttribute.Name))
            {
                return;
            }
        }

        context.Succeed(requirement);
    }

    private Task AuthorizeAsync(ClaimsPrincipal user, string permission)
    {
        //Implement your custom user permission logic here
    }
}

最后,在您的Startup.cs ConfigureServices方法中,将您的自定义AuthorizationHandler添加到服务中,并添加您的策略。

代码语言:javascript
复制
services.AddSingleton();

        services.AddAuthorization(options =>
        {
            options.AddPolicy("Permission", policyBuilder =>
            {
                policyBuilder.Requirements.Add(new PermissionAuthorizationRequirement());
            });
        });

现在您可以简单地使用您的自定义属性来装饰您的控制器和操作。

代码语言:javascript
复制
[Permission("AccessCustomers")]
public class CustomersController
{
    [Permission("AddCustomer")]
    IActionResult AddCustomer([FromBody] Customer customer)
    {
        //Add customer
    }
}
票数 40
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31464359

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档