1

我有我的網站的某個部分,檢查登錄用戶是否可以訪問記錄的ID(報告ID),如果是的話,他們可以查看該頁面上的內容。可以有各種不同類型的用戶/公司來查看內容。自定義屬性+使用查詢字符串驗證權限?

寫一個自定義屬性來檢查用戶是否可以訪問該id的最佳做法是什麼?我應該傳入查詢字符串嗎?請注意,該ID將來自路由/網址。

E.g.報告ID = 678 網址:

  • /報告/ 678 /詳情
  • /報告/ 678 /進展/分段
  • /報告/ 678 /任務管理/ 78/
  • /報告/ 678 /與會者

下面的代碼使用率

[ReportAuthorizationAttribute())] //get query string yourself 
[ReportAuthorizationAttribute (Request.Querystring["reportid"))] //this does not look possible to do??? 

//將被添加到基本控制器這一領域

public class ReportAuthorizationAttribute : AuthorizeAttribute 
{ 

    /// <summary> 
    /// inject via Ninject - there must be a better way? Using service locator? 
    /// </summary> 
    [Inject] 
    public readonly IReportRepo _repo { get; set; } 
    [Inject] 
    public readonly IUserSession _user { get; set; } 

    private int _reportid; 

    public ReportAuthorizationAttribute() 
     : base() 
    { //*Is this way the best way?* 
    _reportid= Int32.Parse(HttpContext.Current.Request.QueryString["reportid"]); 
    } 

    public ReportAuthorizationAttribute(params int reportid) 
     : base() 
    { 
     _reportid = reportid; 
    } 

    public ReportAuthorizationAttribute(params string reportid) 
     : base() 
    { 
     _reportid= Int32.Parse(reportid); 
    } 


    public bool AlwaysAllowLocalRequests = false; 


    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 

     if (httpContext == null) 
      throw new NoAccessException("httpContext is null"); 

     if (!httpContext.User.Identity.IsAuthenticated) 
      throw new NoAccessException("unauthorized user"); 

     var companyid = _user.GetCurrentUser().CompanyID; 
     if (AlwaysAllowLocalRequests && _repo.IsCompanyParticipantInReport(_reportid, companyid)) 
      return true; 

     return false; 
    } 


} 

回答

2

// 代碼是這樣的最佳方式?

_reportid= Int32.Parse(HttpContext.Current.Request.QueryString["reportid"]);

如果使用路由,reportid不會是查詢字符串的一部分。您需要從路由中獲取它:

var reportId = filterContext.RequestContext.RouteData.Values["reportId"]; 

也不要在您的操作過濾器構造函數中使用HttpContext.Current。只使用它裏面的AuthorizeCore方法:

public class ReportAuthorizationAttribute : AuthorizeAttribute 
{ 
    [Inject] 
    public readonly IReportRepo _repo { get; set; } 

    [Inject] 
    public readonly IUserSession _user { get; set; } 

    public bool AlwaysAllowLocalRequests = false; 

    private string _reportId; 

    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     _reportId = filterContext.RequestContext.RouteData.Values["reportId"] as string; 
     base.OnAuthorization(filterContext); 
    } 

    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     if (httpContext == null) 
      return false; 

     if (!httpContext.User.Identity.IsAuthenticated) 
      return false; 

     int reportId; 
     if (!int.TryParse(_reportId, out reportId)) 
      return false; 

     var companyid = _user.GetCurrentUser().CompanyID; 
     return AlwaysAllowLocalRequests && 
       _repo.IsCompanyParticipantInReport(reportId, companyid)); 
    } 
} 
+0

查詢字符串和路由數據,我不知道有什麼區別,我所知道的,這將是在我的網址,我已經設置了路由,這樣如果我說/報告/ {reportid} /細節,你說這是在路由數據訪問,而不是查詢字符串?對不起,我真的不知道! – Haroon

+2

@Harron,查詢字符串是在URL中的'?'之後出現的。例如:'/ Report/Detail?reportId = 678'。在這種情況下,你可以使用'Request.QueryString'。但在你的例子中,reportId是路由定義的一部分:'/ Report/{reportid}/Details',所以你不能使用QueryString來獲取它。你應該使用我的答案中顯示的RouteData。 –

+0

謝謝,但這行不行,我似乎無法訪問RequestContext:httpContext.Request.RequestContext.RouteData.Values [「」] – Haroon