Пользовательский атрибут + проверка прав доступа с помощью строки запроса? - PullRequest
1 голос
/ 14 октября 2011

У меня есть определенная часть моего сайта, которая проверяет, может ли вошедший в систему пользователь иметь доступ к идентификатору записи (идентификатору отчета), и если так, он может просматривать содержимое на этой странице.Существуют различные типы пользователей / компаний, которые будут просматривать контент.

Каков наилучший способ написания пользовательского атрибута, который будет проверять, может ли пользователь получить доступ к идентификатору?Должен ли я передать строку запроса?Обратите внимание, что идентификатор будет получен из маршрута / URL.

Например, идентификатор отчета = 678. URL:

  • / Report / 678 ​​/ Detail
  • / Report /678 / Progress / Staged
  • / Report / 678 ​​/ TaskManager / 78 /
  • / Report / 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;
    }


}

1 Ответ

2 голосов
/ 14 октября 2011

// Это лучший способ?

_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));
    }
}
...