开发者

Custom Attribute + validating permissions with query string?

开发者 https://www.devze.com 2023-04-13 03:46 出处:网络
I have a certain part of my site that checks if the logged on user can access the id of a record (Report id), if so they can view the content on that page. There can be various different types of user

I have a certain part of my site that checks if the logged on user can access the id of a record (Report id), if so they can view the content on that page. There can be various different types of users/companies that will view the content.

What is the best practise for writing a custom attribute that will check if user can access the id? Should I pass in a query string? Note that the id will come from the route/url.

E.g. Report id = 678. urls:

  • /Report/678/Detail
  • /Report/678/Progress/Staged
  • /Report/678/TaskManager/78/
  • /Report/678/Participants

usage of code below

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

//Code that will be added to the base controller for this area

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)开发者_JAVA百科)
            return true;

        return false;
    }


}


//Is this way the best way?

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

If you use routing, reportid won't be part of the query string. You need to fetch it from the route:

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

Also don't use HttpContext.Current in your action filter constructor. Use it only inside the AuthorizeCore method:

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

精彩评论

暂无评论...
验证码 换一张
取 消