Когда я создаю новое приложение 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