2014-03-24 50 views
1

開發一個新的MVC5項目。我有我的腳手架來實現CRUD功能,但是要求在插入或更新數據時需要電子簽名。在將數據提交給數據庫之前,必須向用戶提供一個頁面,要求他們再次輸入用戶名和密碼以確認數據。如果輸入的用戶名和密碼有效且用戶名與當前登錄的用戶相匹配,則輸入的原始數據可以保存到其表(例如成員),並將電子簽名信息保存到單獨的表(ES簽名)中。我很感激任何關於這方面最好的方法的幫助 - 一個結合了成員和ESignature的視圖模型,或者是從帳戶控制器重新使用LoginViewModel來檢查身份驗證,還是一種替代方法?我需要一些可以在需要電子簽名的半打控制器上使用的東西。MVC5 EF6如何在提交數據之前添加帶有附加認證的確認屏幕

回答

0

好吧,也許我的方法不是最好的,但我會嘗試。

我的解決方案是創建一個CustomAttributeAuthorizeAttribute並修飾所有需要「簽名」的操作。在您的CustomAttribute實現中,您將重定向到與Login類似的控制器操作,但只需稍作修改即可。

public class CustomAuthorize : AuthorizeAttribute 
    { 
     public override void OnAuthorization(AuthorizationContext filterContext) 
     { 
      base.OnAuthorization(filterContext); 

      var url = filterContext.HttpContext.Request.Url; 
      var query = url.Query; 
      if (query.Contains("g=")) 
      { 
       var code = query.Split(new String[] { "g=" }, StringSplitOptions.None); 
       //You can create time sensistive token and validate it. 
      } 
      else 
      { 
       //Redirect User to a particular page 
       filterContext.Result = new RedirectToRouteResult(
             new RouteValueDictionary 
            {          
            { "controller", "Account" }, 
            { "action", "elogin" }, 
            { "redirectUrl", url.AbsolutePath} 
            } 
       ); 
      } 
     } 

    } 

然後用它裝飾例如Index()方法。

[CustomAuthorize] 
public ActionResult Index() 
{ 
    return View(); 
} 

起初,當你打的Index()方法,然後裏面的CustomAuthorizeAttributeOnAuthorization方法的其他循環被執行,並重新引導您到裏面AccountController一個elogin方法。此方法與Login HttpGet方法類似。雖然指定RedirectToResult,但我指定了當前頁面的redirectUrl路徑,因此當您在elogin方法內成功驗證用戶時,在redirectUrl的幫助下,我們可以回來。

[AllowAnonymous] 
     public ActionResult ELogin(string returnUrl) 
     { 
      ViewBag.ReturnUrl = returnUrl; 
      return View("Login"); 
     } 

     // 
     // POST: /Account/Login 
     [HttpPost] 
     [AllowAnonymous] 
     [ValidateAntiForgeryToken] 
     public async Task<ActionResult> ELogin(LoginViewModel model, string returnUrl) 
     { 
      if (ModelState.IsValid) 
      { 
       var user = await UserManager.FindAsync(model.UserName, model.Password); 
       if (user != null) 
       { 
        await SignInAsync(user, model.RememberMe); 
        var url = String.Format("{0}/?g={1}", returnUrl, "HashCode"); 
        return RedirectToLocal(url); 
       } 
       else 
       { 
        ModelState.AddModelError("", "Invalid username or password."); 
       } 
      } 

      // If we got this far, something failed, redisplay form 
      return View(model); 
     } 

在HttpPost ELogin方法的唯一不同的是,這樣做RedirectToLocal之前我附加/克= HasCode。注意:在這裏你可以附加你自己的邏輯來創建一個時間敏感的散列。當我們被重定向到我們的主頁時,我們可以檢查OnAuthorization方法內部的url是否包含g = HashCode,然後不重定向到Login Page。

這將是非常基本的想法,您可以通過這種方式強制用戶在遇到特定控制器時重新登錄。你將不得不做額外的安全檢查,並小心你通過網址公開的內容。

+0

但是通過裝飾視圖,ELogin方法在輸入任何數據之前被調用。我需要用戶能夠在重定向之前先輸入其有效數據,然後通過簽名確認數據條目,然後如果簽名有效,請將數據寫入數據庫。 – user2165345

+0

如果您在提交後重定向,那麼如果您在用戶重新登錄之前未保留數據,數據將會丟失。 – Mitul

+0

我可以堅持它,然後回滾,如果他們沒有成功簽名。同時考慮使用Bootstrap Modal,以便我不離開頁面,但不知道如何獲取在控制器中使用的模態中輸入的值。 – user2165345