方法属性

本文关键字:属性 方法 | 更新日期: 2023-09-27 18:04:37

在ASP中为方法分配安全逻辑的最佳方法是什么?净WebForms吗?如果用户登录了,我们不能使用方法属性而不是在每个方法下检查吗?例如,不这样做:

protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        if (!UserLoggedIn)
        {
            Response.Redirect("/login");
        }
        //Do stuff
    }

我想做下面的事情。我在ASP中见过这样做。. NET MVC应用程序,但我想知道我是否可以把它与webforms。还有,确保只有经过身份验证的用户才能继续,而其他用户被重定向到登录页面的最佳实践是什么?

:交货。其中Secure是方法属性:

[Secure]
    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        //Do stuff
    }

如何创建这样的方法属性?如果这是不可能的,你建议我怎么做?我有很多用户控件需要这个在page_load或oninit,我正在寻找一个更好的方法来做到这一点。

方法属性

声明属性

[AttributeUsage(AttributeTargets.Class)]
public class SecureAttribute: Attribute
{             
}

为所有表单创建自定义基页类

public class PageBase: Page
{
    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        var secureAttr = Attribute.GetCustomAttribute(this.GetType(), typeof (SecureAttribute));
        if (secureAttr != null)
        {
            bool UserLoggedIn = false; // get actual state from DB or Session
            if (!UserLoggedIn)
            {
                Response.Redirect("/login");
            }
        }
    }
}

从PageBase继承所有表单

[Secure]
public partial class Profile: PageBase
{
}

为用户控件创建类似的UserControlBase

一个可能的解决方案是使用PageBase helper类来避免在ASP上的每个页面上检查该条件。. NET web表单,只是继承你的aspx.cs类中的页面基。类似下面的代码:

例如,你想确保一些web表单只能由Admin用户访问,那么你可以有一个AdminPageBase类来检查你所有的web页面的这个条件。

你的基类:

public class AdminPageBase : System.Web.UI.Page
{
    protected void Page_Init(object sender, EventArgs e)
    {
        if (!Context.User.Identity.IsAuthenticated ||
            !HttpContext.Current.User.IsInRole(Roles.Admin.ToString()))
        {
            this.RedirectToLogin();
        }
    }
    protected void RedirectToLogin()
    {
        //...
        Response.Redirect("~/SignIn.aspx");
    }
}

注意:Roles.Admin.ToString()是一个enum,但如果您喜欢,也可以使用普通字符串

,在你的web表单类中,你只继承这个基类,像这样:

。AdminPage1.aspx.cs

public partial class AdminPage1: AdminPageBase
{
    //....
}

。AdminPage2.aspx.cs

public partial class AdminPage2: AdminPageBase
{
    //....
}

,您可以对解决方案中的所有其他页面执行相同的操作。你也可以改变Page_Init Page_Load在你的PageBase类,但我选择Page_Init的原因是因为你可能需要Page_Load事件来检查你的页面上的其他事情,所以这是一个很好的地方来检查你的网站安全。

为了拦截方法调用,我建议使用一些AOP框架,例如PostSharp,它允许在方法执行前后通过声明自定义方面轻松注入行为:

[Serializable]
public class SecureAttribute : OnMethodBoundaryAspect
{
    public override void OnEntry(MethodExecutionArgs args)
    {
        bool UserLoggedIn = false; // get from DB
        if (!UserLoggedIn)
        {
            HttpContext.Current.Response.Redirect("/login");
        }
    }
}

并将该属性应用于任何方法

public partial class Profile : Page
{
    [Secure]
    protected void Page_Load(object sender, EventArgs e)
    {
    }
    [Secure]
    protected void Button1_Click(object sender, EventArgs e)
    {
    }
}

据我所知,PostSharp会导致轻微的性能影响,或者根本不会导致性能影响,因为PostSharp会发出MSIL指令。