如何使用自定义授权属性多次授权用户?

时间:2016-07-11 05:05:49

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

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

我想要的是什么:

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

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

3)现在,如果用户is in a" 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;
    }

}
  

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

1 个答案:

答案 0 :(得分:3)

目前还不清楚为什么你的自定义授权属性不起作用,但很明显它的实现过于复杂。

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

  1. 用户是否已登录。
  2. 用户是否处于其中一个提供的角色中。
  3. 所以您需要做的就是在用户处于交易用户角色时添加其他逻辑。

      

    您应该从不访问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;
        }
    }