我試圖實現假設的[ReAuthenticate] -attribute,但發現自己太依賴於反射。把一些思想到一個更易於管理的解決方案後,我終於想出了以下內容:
重新驗證類
public sealed class ReAuth
{
#region Constructor
private ReAuth(Func<System.Web.Mvc.ActionResult> onSuccessAction)
{
this.onSuccessAction = onSuccessAction;
}
#endregion
#region Public static members
public static ReAuth CreateFor(HttpSessionStateBase httpSession, Func<System.Web.Mvc.ActionResult> onSuccessAction)
{
httpSession[sessionKey] = new ReAuth(onSuccessAction);
return GetFor(httpSession);
}
public static ReAuth GetFor(HttpSessionStateBase httpSession)
{
return httpSession[sessionKey] as ReAuth;
}
public static bool ExistsFor(HttpSessionStateBase httpSession)
{
return httpSession[sessionKey] as ReAuth != null;
}
#endregion
#region Public instance members
public bool ReAuthenticated { get; set; }
public System.Web.Mvc.ActionResult Handle()
{
if (ReAuthenticated)
return onSuccessAction();
else
return new System.Web.Mvc.RedirectToRouteResult(
new System.Web.Routing.RouteValueDictionary
{
{ "Controller", "#" }, /* Replace '#' with the name of the controller that implements the re-authentication form... */
{ "Action", "#" } /* Replace '#' with the name of the action on the aforementioned controller. */
});
}
#endregion
#region Private members
private const string sessionKey = "reAuthenticationSessionKey";
private readonly Func<System.Web.Mvc.ActionResult> onSuccessAction;
#endregion
}
實施
假設我們有一個假設的控制器,其中解決方案適用於:
public class AccountInfoController : System.Web.Mvc.Controller
{
/* snip... */
[HttpPost]
public ActionResult EditAccountInfo(AccountInfo model)
{
if (ModelState.IsValid)
return ReAuth.CreateFor(Session,() => { return Success(); }).Handle();
else
return View(model);
}
}
...和,我們需要一個控制器(從本質上講,真正的AccountController不與窗體身份驗證用戶的會話狀態篡改的「啞巴」副本),其中重認證發生:
public class ReAuthController : System.Web.Mvc.Controller
{
/* Snip... */
[HttpPost]
public ActionResult LogOn(LogOnModel model)
{
if (ModelState.IsValid)
{
ReAuth.GetFor(Session).ReAuthenticated = Membership.ValidateUser(model.User, model.Password);
return ReAuth.Handle();
}
return View(model);
}
}
據據我所知,這是一個可管理的解決方案。它確實依賴於將對象存儲到會話狀態。 (特別是實現ReAuth類的控制器的對象狀態)如果有人有其他建議,請告訴我!
讓某人*重新認證*看起來很奇怪,當他們已經通過認證時,您是否正在尋找類似於UAC的東西?我猜想它增加了另一層安全性,但我想可能會讓用戶感到有點沮喪。你不能用角色來代替嗎? – James
你好詹姆斯。您對某個解決方案是否適合_user friendly很有幫助;我真的懷疑我是否會自己決定這樣的事情。不幸的是,這些規範決定了這個功能,客戶想要它,所以沒有辦法解決這個問題。另外,不幸的是,角色的使用不會產生影響,因爲沒有任何影響。不過謝謝你的想法! –
這絕對是可行的,我認爲棘手的部分將不會影響當前的身份驗證狀態。您是否只需重新認證一次,或者每次都需要重新認證? – James