拦截请求中的加密登录令牌

时间:2013-11-19 15:01:57

标签: asp.net-mvc-4 authorize-attribute

我正在开发一个MVC网站,其中有一些页面需要身份验证,而另一些则不需要身份验证。这是使用AuthorizeAllowAnonymous属性以非常标准的方式确定的。如果他们试图访问受限制的内容,他们会被重定向到登录页面。

我现在想要添加使用查询字符串中传递的加密令牌自动登录的功能(链接将在发送的电子邮件中)。所以我现在想要的工作流是,如果请求进入受限制的页面并且查询字符串中有登录令牌,我希望它使用该令牌登录。如果它成功登录,那么我希望它运行使用新登录的上下文请求原始页面。如果登录失败,则会重定向到自定义错误页面。

我的问题是我需要将此逻辑插入网站?

我已经看到了关于子类化Authorize属性并覆盖一些方法的一些建议,但我不是百分之百确定如何解决这个问题(例如我将覆盖的内容以及我在那些重写方法中要做的事情。< / p>

我还看过将逻辑置于控制器级别,但我了解到,在控制器本身的任何代码运行之前,authorize属性会将其重定向远离控制器。

1 个答案:

答案 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");
}