2012-03-07 58 views
1

我從一個自定義的授權屬性所採取的代碼,並提出了這一點:自定義授權屬性並不總是工作

public class PortalAuthorizeAttribute : AuthorizeAttribute 
{ 
    private WebSiteSession m_UserSession; 
    protected WebSiteSession myUserSession 
    { 
     get 
     { 
      if (m_UserSession == null) 
       try { m_UserSession = (WebSiteSession)HttpContext.Current.Session["UserSession"]; } 
       catch 
       { 
        m_UserSession = new WebSiteSession(); 
        HttpContext.Current.Session["UserSession"] = m_UserSession; 
       } 
      return m_UserSession; 
     } 
    } 

    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     if (filterContext.Result is HttpUnauthorizedResult || myUserSession == null || !myUserSession.IsAuthenticated || myUserSession.AdvertiserId == 0) 
     { 
      filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary 
      { 
        { "client", filterContext.RouteData.Values["client"] }, 
        { "controller", "Account" }, 
        { "action", "Login" }, 
        { "returnUrl", filterContext.HttpContext.Request.RawUrl } 
      }); 
     } 
    } 
} 

我從一個更大的項目中工作,所以我們從更高的命名空間讓我們的會議。如果我註銷或者我沒有授權(重定向到區域登錄頁面),但它似乎如果我閒置(會話超時??)它將仍然按照我的授權行事,但不會有任何憑據附加到會話。所以它仍然認爲我有效登錄,但我不是。我在過濾器檢查中忘記了什麼嗎?該Cookie不再有效,但它仍像用戶仍能訪問該頁面。

感謝

回答

1

與您的代碼的問題,從一個事實,即ASP.NET MVC 3可以緩存的作用過濾器實例莖。這是breaking changes之一:

在ASP.NET MVC的早期版本中,動作過濾器每 請求創建除了在少數情況下。這種行爲從來沒有保證 的行爲,但只是一個實施細節和合同 過濾器是認爲他們無國籍。在ASP.NET MVC 3中,更積極地緩存過濾器 。因此,任何自定義操作篩選器不正確地存儲實例狀態可能會被破壞。

既然你已經緩存在m_UserSession私人領域進入行動過濾器,它從來沒有空,你的測試沒有通過。

所以,這裏是你如何能繼續:

public class PortalAuthorizeAttribute : AuthorizeAttribute 
{ 
    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     var userSession = filterContext.HttpContext.Session["UserSession"] as WebSiteSession; 
     if (userSession == null || !userSession.IsAuthenticated || userSession.AdvertiserId == 0) 
     { 
      filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary 
      { 
       { "client", filterContext.RouteData.Values["client"] }, 
       { "controller", "Account" }, 
       { "action", "Login" }, 
       { "returnUrl", filterContext.HttpContext.Request.RawUrl } 
      }); 
     } 
    } 
} 

至於創建和存儲新WebSiteSession實例到會話中,這不是東西,授權過濾器應該做的。在成功驗證後,您應該在Login操作中執行此操作。授權過濾器僅用於檢查用戶是否有權訪問該操作。

+0

非常感謝,這已經爲我澄清了這個問題。我不知道它緩存了。 – Darren 2012-03-07 17:51:22