【问题标题】:How to authorize users more than once using custom authorize attribute?如何使用自定义授权属性多次授权用户?
【发布时间】:2016-07-11 19:46:49
【问题描述】:

我有一个自定义的授权属性类来检查isAuthorize 两次。

我想要什么:

1) 首先检查用户是否为super admin。如果他是,那么他将是authorized

2) 如果是he is not,那么它会检查他是否有一个名为“Deal User”的角色。如果he is not,那么他就是unauthorized

3) 现在如果用户is in 是“Deal User”角色,我想检查用户是否拥有该交易。因此,如果用户拥有该交易,我会检查数据库。如果he owns,那么他就是authorized。否则他将是Unauthorized

public class DealManageCustomAuthorizeAttribute : AuthorizeAttribute

{

    private static ApplicationDbContext Context = new ApplicationDbContext();
    private static UserStore<ApplicationUser> userStore = new UserStore<ApplicationUser>(Context);
    private UserManager<ApplicationUser> userManager = new UserManager<ApplicationUser>(userStore);

    private enum Result
    {
        Authorize,
        Unauthorize,
        InternalServerError
    }

    public override void OnAuthorization(HttpActionContext actionContext)
    {

        var result = AuthorizeRequest(actionContext);
        if (result == Result.Authorize)
        {
            return;
        }
        else
        {
            HandleUnauthorizedRequest(actionContext);
        }

    }

    protected override void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        //Code to handle unauthorized request
        base.HandleUnauthorizedRequest(actionContext);
    }

    private Result AuthorizeRequest(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        base.Roles = "Super Admin";
        bool authorized = base.IsAuthorized(actionContext);
        if (!authorized)
        {
            try
            {

                base.Roles = "Deal User";

                bool auth = base.IsAuthorized(actionContext);

                if (!auth)
                {
                    return Result.Unauthorize;
                }

                Uri uri = actionContext.Request.RequestUri;
                Guid dealId = new Guid(HttpUtility.ParseQueryString(uri.Query).Get("dealId"));
                string userId = HttpContext.Current.User.Identity.GetUserId();

                var retval = new Deal(Common.Common.TableSureConnectionString).CheckDealByIdAndUserId(dealId, userId);

                if (retval)
                {
                    return Result.Authorize;
                }
                return Result.Unauthorize;
            }
            catch (Exception)
            {
                return Result.InternalServerError;
            }
        }
        return Result.Authorize;
    }

}

我编写了代码并且它正在运行。但我想知道是不是 授权用户的正确方式?

【问题讨论】:

    标签: c# asp.net-mvc asp.net-web-api authorization asp.net-identity


    【解决方案1】:

    尚不清楚您的自定义授权属性为何不起作用,但很明显它的实现过于复杂。

    AuthorizeAttribute 具有简单的布尔函数IsAuthorized,您可以(并且应该)覆盖它以返回用户是否被授权。基本实现已经检查

    1. 用户是否登录。
    2. 用户是否处于提供的角色之一。

    所以您需要做的就是在用户处于 Deal User 角色时添加额外的逻辑。

    您应该永远访问 Web API/MVC 中的静态 HttpContext.Current 成员。在这种特殊情况下,actionContext 作为参数传入,您可以(并且应该)使用它。

    using Microsoft.AspNet.Identity;
    using System;
    using System.Linq;
    using System.Net.Http;
    using System.Security.Principal;
    using System.Web.Http;
    using System.Web.Http.Controllers;
    
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true)]
    public class DealManageCustomAuthorizeAttribute : AuthorizeAttribute
    {
        public DealManageCustomAuthorizeAttribute()
        {
            // Set the Super Admin and Deal User roles
            this.Roles = "Super Admin,Deal User";
        }
    
        protected override bool IsAuthorized(HttpActionContext actionContext)
        {
            // This checks whether the user is logged in, and whether
            // they are in the Super Admin or Deal User role.
            var isAuthorized = base.IsAuthorized(actionContext);
    
            IPrincipal user = actionContext.ControllerContext.RequestContext.Principal;
    
            // Special case - user is in the Deal User role
            if (isAuthorized && user.IsInRole("Deal User"))
            {
    
                var queryString = actionContext.Request.GetQueryNameValuePairs()
                    .ToDictionary(kv => kv.Key, kv => kv.Value, StringComparer.OrdinalIgnoreCase);
    
                // Ensure the query string contains the key "dealId"
                if (!queryString.ContainsKey("dealId"))
                {
                    return false;
                }
    
                Guid dealId;
                if (!Guid.TryParse(queryString["dealId"], out dealId))
                {
                    // If the Guid cannot be parsed, return unauthorized
                    return false;
                }
    
                // Now check whether the deal is authorized.
                var userId = user.Identity.GetUserId();
    
                return new Deal(Common.Common.TableSureConnectionString)
                    .CheckDealByIdAndUserId(dealId, userId);
            }
    
            return isAuthorized;
        }
    }
    

    【讨论】:

    • 哦。你节省了我的时间......工作正常。一个问题。属性用法我不懂。
    • MSDN Doc。 AttributeUsage 只是告诉编译器该属性在方法(操作)或类(控制器)上有效。在后一种情况下,您可以使用一个属性授权整个控制器。例如,如果您尝试将其放在属性或程序集上,它是无效的 - 您将收到编译器错误。由于它也是filter,因此也可以在应用程序范围内注册。
    猜你喜欢
    • 2014-10-28
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    • 2020-04-11
    • 2015-03-03
    • 1970-01-01
    相关资源
    最近更新 更多