Атрибуты метода в WebForms

1

Каков наилучший способ назначения логики безопасности методу в ASP.NET 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
    }

Как мне создать такой атрибут метода? И если это невозможно, как бы вы порекомендовали мне это сделать? У меня есть много usercontrols, которые нуждаются в этом на page_load или oninit, и я ищу лучший способ сделать это.

Теги:
webforms

3 ответа

4
Лучший ответ

Объявите свой атрибут

[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 для пользовательских элементов управления.

  • 0
    Спасибо, это здорово! Но вместо того, чтобы приписывать весь класс, есть ли способ только приписать метод? Пример: позволить Page_Load быть видимым без аутентификации, но гарантировать, что Button_submit перенаправляет на страницу входа в систему, если нет сеанса аутентификации?
  • 0
    Плз, смотри мой второй ответ
1

Чтобы перехватить вызовы методов, я бы рекомендовал использовать некоторую структуру 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.

1

Одним из возможных решений будет вспомогательный класс PageBase, чтобы избежать проверки этого условия на каждой отдельной странице веб-форм ASP.NET и просто наследует базу страниц в ваших классах aspx.cs. что-то вроде кода ниже:

например, вы хотите убедиться, что некоторые веб-формы доступны только пользователям Admin, тогда у вас может быть класс AdminPageBase для проверки этого условия для всех ваших веб-страниц.

ваш базовый класс:

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() - это перечисление, но вы также можете использовать простую строку, если хотите.

и в ваших классах веб-форм вы наследуете этот базовый класс следующим образом:

например, 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, чтобы проверить другие вещи на вашей странице, чтобы было неплохо проверить безопасность вашего сайта.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню