2012-06-12 43 views
0

設置ASP.NET MVC - 驗證一次且僅一次,直到會話了

我使用自定義窗體身份驗證 - 所有標準的東西。

在我的帳戶控制器上的登錄操作,

  • 我覈對了數據庫
  • 用戶的詳細信息,如果成功的話,我創建一個窗體身份驗證票
  • 商店登錄的會員數據庫行ID在在的UserData票
  • 加密票
  • 存儲在cookie中
  • 門票添加餅乾在Reponse.Cookies收集
  • 重定向到索引操作家用控制器

我註冊了全球ASAX的處理程序AuthenticateRequest事件。在我的處理程序中,

  • 我從HttpContext.Current.Request.Cookies [FormsAuthentication.FormsCookieName]中檢索cookie;
  • 如果存在cookie,我將解密Cookie中的Forms Authentication工單的值
  • 使用存儲在認證工單UserData中的Id從db中檢索用戶的詳細信息。
  • 創建自定義主體並將用戶(它具有自定義LoggedInUser屬性)設置爲從數據庫中檢索到的用戶。
  • 將HttpContext.Current.User到自定義主

問題

我調試了主頁的請求,我已經登錄,並注意後,該AuthenticateRequest處理程序的Global.asax每頁請求被擊中不止一次。我檢查了HttpContext.Current.Request.Path,這是因爲我的頁面上的每個資源(實際上,每個HTTP GET)都觸發了認證請求,所以,GET jquery.js,GET logo.png等...

問題

在第一次處理AuthenticateRequest我去到數據庫,然後設置HttpContext.Current.User到我的自定義主體。避免將數據庫導入到引發AuthenticatRequest的後續HTTP GET會是一種好方法。實際上,只有在用戶關閉瀏覽器或直到認證單過期之前,才進行一次認證。

TIA

回答

1

而不是使用在Global.asax中AuthenticateRequest方法我建議你寫一個全球行動過濾器。這樣,動作過濾器將僅在執行某個動作並填充用戶之前應用。事實上自定義[Authorize]屬性是實現這一目標的最佳途徑:

public class MyAuthorizeAttribute : AuthorizeAttribute 
{ 
    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     var authorized = base.AuthorizeCore(httpContext); 
     if (!authorized) 
     { 
      return false; 
     } 

     // TODO: go ahead and work with the UserData from the authentication cookie 
     // basically all the steps you described for your AuthenticateRequest handler 
     // except for checking the presence of the forms authentication cookie because 
     // we know that at this stage it exists and the user was successfully authorized 

     return true; 
    } 
} 
+0

這是一個很好的解決方案,只要用戶並不需要提供授權給單個資源(如照片或PDF格式的文件或其他文件用戶可能想要控制對其的訪問)。 –

+1

這些資源通常應通過控制器操作提供,並因此回退到標準的ASP.NET MVC授權過程。 –

+0

不一定,可以使用web.config位置。但是,由於認證是在行動層面完成的,因此在全球層面上不會有任何授權。這可能很好。我只想指出,如果您只保護控制器操作,此方法纔有效。 –