0

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

} 

我写的代码,它工作正常。但是我想知道是否是 正确授权用户的方式?

回答

2

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

AuthorizeAttribute具有简单的布尔函数IsAuthorized您可以(也应该)重写以返回用户是否被授权。基实现已经检查

  1. 无论用户被登录。
  2. 用户是否是在所提供的角色之一。

所以您只需在用户处于交易用户角色时添加其他逻辑。

你应该从未访问静态HttpContext.Current成员的Web API/MVC。在这种情况下,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; 
    } 
} 
+0

哦。你节省了我的时间......正常工作。一个问题。我不明白使用属性的用法。 –

+1

请参阅[MSDN文档](https://msdn.microsoft.com/en-us/library/system.attributeusageattribute(v = vs.110).aspx)。 AttributeUsage只是告诉编译器该属性在方法(动作)或类(控制器)上是有效的。在后一种情况下,您可以*授权具有一个属性的整个控制器。例如,如果您尝试将其放置在属性或程序集上,则无效 - 您将收到编译器错误。由于它也是[过滤器](https://msdn.microsoft.com/en-us/library/gg416513(VS.98).aspx),因此它也可以在应用程序范围内注册。 – NightOwl888