Вопрос: запрашивается ли OnAuthorization для каждого запроса? Если нет, где я могу проверить тайм-аут сеанса до Атрибуты авторизации называются?Включена ли OnAuthorization для каждого запроса?
Фон: Мне нужен способ определить, существует ли сеанс и не был ли он отключен. Я хочу сделать это при каждом вызове метода для каждого контроллера в моем приложении. Мне нужно сделать это до того, как будут вызываться фильтры авторизации, потому что я сохраняю hashset разрешений в сеансе, и мой атрибут authorize смотрит на эти разрешения. Мне нужно сделать это для каждого запроса, независимо от того, применяется ли атрибут авторизации или нет.
Пара ответов Я прочитал (одно приведенное ниже) состояние, чтобы переопределить OnActionExecuting в базовом контроллере. Это имеет смысл, однако я обнаружил, что OnActionExecuting не вызывается до тех пор, пока не будет вызван AuthorizeCore в атрибуте фильтра.
Подход, к которому я дошел до сих пор, - это проверить сеанс в базовом контроллере и проверить разрешение в атрибуте authorize.
BaseController.cs:
protected override void OnAuthorization(AuthorizationContext filterContext)
{
// This base does two things:
// 1.) Ensures that Session exists
// 2.) Ensures that the Security object exists and is initalized.
HttpContextBase httpContext = filterContext.HttpContext;
// Check if session exists
if (httpContext.Session == null)
filterContext.Result = Redirect(core.SecurityConstants.SessionTimeoutRedirectURL);
else
{
if(!Security.IsInitialized())
filterContext.Result = Redirect(core.SecurityConstants.PermissionDeniedRedirectURL);
else if (httpContext.Session.IsNewSession) // check if a new session id was generated
{
// If it says it is a new session, but an existing cookie exists, then it must have timed out
string sessionCookie = httpContext.Request.Headers["Cookie"];
if ((null != sessionCookie) && (sessionCookie.IndexOf("ASP.NET_SessionId") >= 0))
{
if (httpContext.Request.IsAjaxRequest())
{
filterContext.HttpContext.Response.StatusCode = 401;
httpContext.Response.End();
}
filterContext.Result = Redirect(core.SecurityConstants.SessionTimeoutRedirectURL);
}
}
}
base.OnAuthorization(filterContext);
}
SecurityAttribute.cs:
public class SecurityAttribute : AuthorizeAttribute
{
public Permission Permission { get; set; }
public SecurityAttribute(Permission permission)
{
Permission = permission;
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
base.AuthorizeCore(httpContext);
return Security.HasPermission(Permission);
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
base.HandleUnauthorizedRequest(filterContext);
//if (filterContext.RequestContext.HttpContext.User.Identity.IsAuthenticated)
//{
filterContext.RequestContext.HttpContext.Response.Redirect(SecurityConstants.PermissionDeniedRedirectURL);
//}
}
}
Список литературы
When OnAuthorization method is called?
With ASP.NET MVC redirect to login page when session expires
Это выглядит как очень хорошая идея, так что я в основном скопированный мой код базового контроллера в метод как предложено. К сожалению, похоже, что значение IsNewSession установлено равным true, и пользователь перенаправляется, как если бы их сеанс был исчерпан. Это не происходит, когда код находится в базовом контроллере. – Sam
проблема с таймаутом сеанса, похоже, связана с хром, который ищет favicon.ico. Это правильный ответ. – Sam
рад, что он работает для вас в конце :) – hammadmirza