我正在开发一个MVC网站,其中有一些页面需要身份验证,而另一些则不需要身份验证。这是使用Authorize
和AllowAnonymous
属性以非常标准的方式确定的。如果他们试图访问受限制的内容,他们会被重定向到登录页面。
我现在想要添加使用查询字符串中传递的加密令牌自动登录的功能(链接将在发送的电子邮件中)。所以我现在想要的工作流是,如果请求进入受限制的页面并且查询字符串中有登录令牌,我希望它使用该令牌登录。如果它成功登录,那么我希望它运行使用新登录的上下文请求原始页面。如果登录失败,则会重定向到自定义错误页面。
我的问题是我需要将此逻辑插入网站?
我已经看到了关于子类化Authorize属性并覆盖一些方法的一些建议,但我不是百分之百确定如何解决这个问题(例如我将覆盖的内容以及我在那些重写方法中要做的事情。< / p>
我还看过将逻辑置于控制器级别,但我了解到,在控制器本身的任何代码运行之前,authorize属性会将其重定向远离控制器。
答案 0 :(得分:1)
最好编写一个自定义授权属性,该属性将完全替换默认功能并检查查询字符串参数,如果存在,则对其进行解密并对用户进行身份验证。如果您正在使用FormsAuthentication,那将调用FormsAuthentication.SetAuthCookie方法。有点像:
public class TokenAuthorizeAttribute : FilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
string token = filterContext.HttpContext.Request["token"];
IPrincipal user = this.GetUserFromToken(token);
if (user == null)
{
this.HandleUnAuthorizedRequest(filterContext);
}
else
{
FormsAuthentication.SetAuthCookie(user.Identity.Name, false);
filterContext.HttpContext.User = user;
}
}
private IPrincipal GetUserFromToken(string token)
{
// Here you could put your custom logic to decrypt the token and
// extract the associated user from it
throw new NotImplementedException();
}
private void HandleUnAuthorizedRequest(AuthorizationContext filterContext)
{
filterContext.Result = new ViewResult
{
ViewName = "~/Views/Shared/CustomError.cshtml",
};
}
}
然后您可以使用此属性修饰您的操作:
[TokenAuthorize]
public ActionResult ProcessEmail(string returnUrl)
{
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
return RedirectToAction("Index", "Home");
}