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

How to authorize users more than once using custom authorize attribute?

我有一个自定义授权属性 class 来检查 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;
    }

}

I wrote the code and it is working. But I want to know whether it is the correct way to authorize users ?

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

AuthorizeAttribute 具有简单的布尔函数 IsAuthorized,无论用户是否获得授权,您都可以(并且应该)将其覆盖为 return。基本实现已经检查

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

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

You should never access the static HttpContext.Current member in Web API/MVC. In this particular case, the actionContext is being passed in as a parameter, which you can (and should) use.

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;
    }
}