2015-03-03 1 views
0

Вопрос: запрашивается ли 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

ответ

1

Может быть выполнены следующие работы для вас, добавьте его в Global.asax

protected void Application_AcquireRequestState() 
{ 
    if (Context.Session!=null && Context.Session.IsNewSession) 
    { 
     //do something 
    } 
} 
+0

Это выглядит как очень хорошая идея, так что я в основном скопированный мой код базового контроллера в метод как предложено. К сожалению, похоже, что значение IsNewSession установлено равным true, и пользователь перенаправляется, как если бы их сеанс был исчерпан. Это не происходит, когда код находится в базовом контроллере. – Sam

+0

проблема с таймаутом сеанса, похоже, связана с хром, который ищет favicon.ico. Это правильный ответ. – Sam

+0

рад, что он работает для вас в конце :) – hammadmirza