1

로그온 한 사용자가 레코드 ID (Report id)에 액세스 할 수 있는지 확인하는 특정 사이트 부분이 있습니다. 그렇다면 해당 페이지의 콘텐츠를 볼 수 있습니다. 다양한 유형의 사용자/회사가 콘텐츠를 볼 수 있습니다.사용자 지정 특성 + 쿼리 문자열 사용 권한 유효성 검사?

사용자가 ID에 액세스 할 수 있는지 확인하는 사용자 지정 특성을 작성하는 가장 좋은 방법은 무엇입니까? 쿼리 문자열을 전달해야합니까? 이 ID는/url 경로에서 가져옵니다.

예. 보고서 ID = 678 URL을 :

  • /신고/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 방법 안에 그것을 사용 : 나는 내 URL에있을 것이라는 점을 아는, 내가 경로를 설정 한 차이가 무엇인지 확실하지 않다,

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

쿼리 문자열 및 경로 데이터를하는 경우 그래서 say/Report/{reportid}/Details, 경로 문자열 데이터가 아니라 쿼리 문자열에 액세스 할 수 있다고 말하고 있습니까? 미안, 나는 정말로 모른다. – Haroon

+2

@Harron, 쿼리 문자열은 URL에서'? '다음에 오는 것입니다. 예 :'/ Report/Detail? reportId = 678'. 이 경우에는'Request.QueryString'을 사용할 수 있습니다. 그러나 당신의 예제에서 reportId는'/ Report/{reportid}/Details' 경로 정의의 일부이므로 QueryString을 사용하여 가져올 수는 없습니다. 내 대답에 표시된대로'RouteData'를 사용해야합니다. –

+0

감사합니다. 그러나이 줄은 작동하지 않습니다. RequestContext에 대한 액세스 권한이없는 것 같습니다. httpContext.Request.RequestContext.RouteData.Values ​​[ ""] – Haroon

관련 문제