我试图实现假设的[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