自定义属性 +使用查询字符串验证权限?

发布于 2024-12-09 13:22:47 字数 1993 浏览 0 评论 0原文

我网站的某个部分检查登录用户是否可以访问记录的 ID(报告 ID),如果可以,他们可以查看该页面上的内容。可以有各种不同类型的用户/公司查看内容。

编写检查用户是否可以访问 id 的自定义属性的最佳实践是什么?我应该传入查询字符串吗?请注意,id 将来自路由/url。

例如,报告 ID = 678。 urls:

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

使用下面的代码

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

//将添加到基本控制器的代码< /strong> 该区域

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;
    }


}

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))
            return true;

        return false;
    }


}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

戒ㄋ 2024-12-16 13:22:47

//这是最好的方式吗?

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

//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));
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文