Когда я создаю новое приложение asp.net mvc 4.0, одним из первой вещи, которую я делаю, является создание и установка настраиваемого авторизации global filter
следующим образом:
//FilterConfig.cs
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
//filters.Add(new HandleErrorAttribute());
filters.Add(new CustomAuthorizationAttribute());
}
Затем я создаю CustomAuthorizationAttribute
следующим образом:
//CustomAuthorizationAttribute.cs
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
//Handle AJAX requests
filterContext.HttpContext.Response.StatusCode = 403;
filterContext.Result = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
else
{
//Handle regular requests
base.HandleUnauthorizedRequest(filterContext); //let FormsAuthentication make the redirect based on the loginUrl defined in the web.config (if any)
}
}
У меня есть два контроллера: HomeController
и SecureController
HomeController украшен атрибутом [AllowAnonymous]
.
SecureController НЕ, украшенный атрибутом [AllowAnonymous]
.
Index() ActionResult
HomeController
отображает вид с помощью простой кнопки.
Когда я нажимаю кнопку, я делаю вызов ajax методу GetData(), который живет внутри SecureController
, например:
$("#btnButton").click(function () {
$.ajax({
url: '@Url.Action("GetData", "Secure")',
type: 'get',
data: {param: "test"},
success: function (data, textStatus, xhr) {
console.log("SUCCESS GET");
}
});
});
Излишне говорить, что когда я нажимаю кнопку, я запускаю CustomAuthorizationAttribute
, потому что это глобальный фильтр, но также потому, что SecureController
НЕ украшен атрибутом [AllowAnonymous]
.
Хорошо, я сделал с моим вступлением...
С введением asp.net mvc 5.0
мы теперь вводим новый authentication filter
, который вызывает срабатывание до фильтра авторизации (что отлично и дает нам более подробный контроль над тем, как я может отличаться от пользователя, который НЕ аутентифицирован (http 401) от пользователя, который прошел аутентификацию IS и кто НЕ НЕ разрешен (http 403)).
Чтобы дать этой новой попытке authentication filter
, Ive создал новый asp.net mvc 5.0 (VS Express 2013 для Интернета) и начал с выполнения следующего действия:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
//filters.Add(new HandleErrorAttribute());
filters.Add(new CustomAuthenticationAttribute()); //Notice I'm using the word Authentication and not Authorization
}
Затем атрибут
public class CustomAuthenticationAttribute : ActionFilterAttribute, IAuthenticationFilter
{
public void OnAuthentication(AuthenticationContext filterContext)
{
}
public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
{
var user = filterContext.HttpContext.User;
if (user == null || !user.Identity.IsAuthenticated)
{
filterContext.Result = new HttpUnauthorizedResult();
}
}
}
Ive создал a HomeController
. HomeController
украшен атрибутом [AllowAnonymous]
.
Перед запуском приложения из VS 2013 Ive установил две точки останова в обоих методах моего атрибута CustomAuthenticationAttribute (OnAuthentication
и OnAuthenticationChallenge
).
Когда я запускаю приложение, я ударяю первую точку прерывания (OnAuthentication
). Затем, к моему удивлению, код в Index() ActionResult
моего HomeController
выполняется и только после того, как я возвращаю View(), я попал в точку прерывания по методу OnAuthenticationChallenge()
.
Вопросы: У меня два вопроса.
Вопрос 1)
У меня создалось впечатление, что атрибут [AllowAnonymous]
обходит любой код внутри моего CustomAuthenticationAttribute
, но я ошибся! Мне нужно вручную проверить на наличие атрибута [AllowAnonymous]
и пропустить любой код?
Вопрос 2)
Почему код внутри моего метода Index()
моего HomeController
выполняется после OnAuthentication
? Только для того, чтобы понять, что после того, как я возвращаю View(), выполняется ли код внутри OnAuthenticationChallenge()
?
Меня беспокоит, что я не хочу, чтобы код из метода Index()
выполнялся, если пользователь НЕ аутентифицирован.
Возможно, я смотрю на это неправильно.
Если кто-то может помочь мне пролить свет на это, это будет здорово!
С уважением Vince