Как создать действительно простую модель безопасности в приложении MVC?

#asp.net-mvc #asp.net-mvc-3

#asp.net-mvc #asp.net-mvc-3

Вопрос:

Я хочу сделать что-то похожее на следующее

 if (Session["UserId"] == null)
            {
                RedirectToRoute("Default");
            }
  

Так что любой, кому не был предоставлен сеанс (на моей странице входа), будет удален на страницу входа. Как бы мне это сделать, чтобы это происходило на

1) выбранные действия по моему выбору 2) все действия, если необходимо

Комментарии:

1. Испытываете ли вы особое отвращение к использованию встроенной проверки подлинности FormsAuthentication, которая делает все это за вас?

Ответ №1:

Самым чистым способом было бы реализовать ее с помощью фильтров действий. Что-то вроде этого должно помочь вам начать:

 class UserLoggedInAttribute : AuthorizeAttribute {
    public override void OnAuthorization(AuthorizationContext filterContext) {
        if(filterContext.HttpContext.Session["UserId"] == null) {
            filterContext.Result = new RedirectToRouteResult("Default");
        }
    }
}
  

Тогда остается только украсить ваши контроллеры и / или действия этим атрибутом:

 [UserLoggedIn]
public class YourController {

}
  

Ответ №2:

Это поведение [Authorize] атрибута по умолчанию. Таким образом, вы могли бы выборочно украшать действия контроллера, требующие авторизации с помощью этого атрибута:

 [Authorize]
public ActionResult SomeAction()
{
    ...
}
  

И если вы хотите применить ее к нескольким действиям, вы могли бы написать базовый контроллер, а затем украсить этот базовый контроллер заданным атрибутом. Тогда для доступа ко всем дочерним контроллерам, производным от этого базового контроллера, и ко всем действиям потребуется авторизация.

У вас также есть возможность написать пользовательский атрибут авторизации на основе конкретных требований, которые у вас могут быть. Например:

 public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        return httpContext.Session["UserId"] != null;
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        // if the user doesn't have the userid value in session
        // redirect him to the index action on the home controller
        var values = new { controller = "Home", action = "Index" };
        filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(values));
    }
}
  

затем украсьте действия / контроллеры, которые должны следовать этой пользовательской логике авторизации, этим атрибутом:

 [MyAuthorize]
public ActionResult SomeAction()
{
    ...
}
  

Теперь, когда вы аутентифицируете пользователя в своем действии входа (которое, очевидно, не должно быть украшено каким-либо атрибутом authoraztion), при действительных учетных данных вы добавляете свойство userId в сеанс и перенаправляете на какое-либо другое действие контроллера, которое само украшено этим атрибутом и требует аутентификации.

Однако в большинстве случаев достаточно атрибута авторизации по умолчанию.