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