2011-03-25 58 views
2

我們有一個MVC應用程序,它具有自定義窗體身份驗證視圖/控制器。控制器將驗證事情,然後執行FormsAuthentication.RedirectFromLoginPage調用。MVC中的兩步認證?

在Global.asax中的這一點上,我們將收到Application_OnAuthenticateRequest調用,我們將從中獲取其Context.User信息,並再次調用以收集與此帳戶相關的信息,然後我們將其存儲在Context.User & System.Threading.Thread.CurrentPrincipal。我們也對這些信息做了一點緩存,因爲在我們的系統中檢索我們需要的是昂貴的,導致緩存失效&重新檢索這些信息。

在這一點上,我們似乎有點奇怪,我們將這些分離爲不同的調用。我幾乎想知道登錄控制器是否應該收集細節作爲其身份驗證檢查的一部分並存儲它們。然後,Application_OnAuthenticateRequest只能擔心緩存是否需要失效,並重新檢索用戶詳細信息。

或者也許有一些其他的方式來處理這個我甚至不知道..?

+0

https://stackoverflow.com/questions/47368154/how-to-make-google-authentication-scan-qr-code/47368506#47368506在這裏你得到你的解決方案 – 2017-11-18 17:32:26

回答

2

您可以通過使用RedirectToRouteResult和自定義緩存更新ActionFilter來實現MVC中的目標。這被稱爲PRG(Post-Redirect-Get)模式。你實際上已經在做這件事,但它有點混亂,因爲你正在做的是經典的ASP.NET做事方式和MVC做事方式之間的交叉。這沒有什麼不對您最初的方法(前提是它工作正常),而是做了同樣的事情,並有它是如何工作的事情你可以做類似的方案更多的控制和了解:

public class AuthenticationController :Controller 
{ 
    [HttpPost] 
    public RedirectToRouteResult Login(string username, string password) 
    { 
     //authenticate user 
     //store authentication info in TempData like 
     bool authenticated = true|false; // do your testing 
     if(authenticated) 
     { 
      TempData["MustUpdateCache"] = true | false; 
      return RedirectToAction("LoginSuccess", new{userId = membershipUser.UserId});     
     } 
     else 
     { 
      TempData["MustUpdateCache"] = true | false; 
      return RedirectToAction("Login"); 
     } 
    } 

    [HttpGet, UpdateCache] 
    public ActionResult LoginSuccess(Guid userId, string url) 
    { 
     HttpContext.User = LoadUser(userId); 
     return View(); 
    } 

    [HttpGet, UpdateCache] 
    public ViewResult Login() 
    { 
     return View(); 
    } 

} 
public class UpdateCacheAttribute:ActionFilterAttribute 
{ 
    public override void OnResultExecuting(ResultExecutingContext filterContext) 
    { 
     var tempData = filterContext.Controller.TempData; 
     if (tempData.ContainsKey("MustUpdateCache") && (bool)tempData["MustUpdateCache"]) 
     { 
      UpdateCache(filterContext); 
     } 
    } 

    void UpdateCache(ControllerContext controllerContext) 
    { 
     //update your cache here 
    } 
}