MVC管道中的身份验证失败

时间:2014-01-01 16:01:34

标签: asp.net-mvc authentication

鉴于FormsAuthentication模块在处理OnAuthenticateRequest的自定义http模块之前触发,我很好奇是否可以根据我自己的标准取消或使表单身份验证无效。

基本上我有一个用户登录的过程。之后他们会获得一个令牌。在表单身份验证触发后续请求后,我得到令牌。我想要做的是验证令牌未对我们的后端服务器过期。如果它已经过期,我需要做一些事情,以便他们被迫重新登录。我的想法是在我的OnAuthenticateRequest处理程序中做一些事情,这个处理程序稍后会在管道中被拾取并强制重定向回登录页面或其他东西。这可能吗?

2 个答案:

答案 0 :(得分:3)

在ASP.NET MVC应用程序中,为了处理自定义身份验证和授权,人们通常会编写自定义Authorize属性。他们不处理任何OnAuthenticateRequest事件。那是老派。顺便说一句,如果你要做一些自定义令牌认证,为什么甚至关心表单身份验证?为什么不替换它?

所以:

public class MyAuthorizeAttribute: AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        string token = GetTokenFromHttpContext(httpContext);
        if (IsTokenValid(token))
        {
            // The user has provided a valid token => you need to set the User property
            // Obviously here based on the token value you already know which is the
            // associated user and potential roles, so you could do additional checks

            var identity = new GenericIdentity("john.smith");
            var user = new GenericPrincipal(identity, new string[0]);
            httpContext.User = user;

            return true;
        }

        // Notice that here we are never calling the base AuthorizeCore method
        // but you could call it if needed 

        return false;
    }

    private string GetTokenFromHttpContext(HttpContextBase httpContext)
    {
        // TODO: you know what to do here: get the token from the current HTTP Context
        // depending on how the client passed it in: HTTP request header, query string parameter, cookie, ...
        throw new NotImplementedException();
    }

    private bool IsTokenValid(string token)
    {
        // TODO: You know what to do here: go validate the token
        throw new NotImplementedException();
    }
}

现在剩下的就是用这个自定义属性装饰你的控制器/动作而不是使用默认属性:

[MyAuthorize]
public ActionResult SomeAction()
{
    // if you get that far you could use the this.User property
    // to access the currently authenticated user
    ...
}

答案 1 :(得分:0)

  

这可能吗?

这绝对是可能的。您甚至可以将您的autehtication方案设置为None,以便表单模块不在管道中并且只有您自己的模块。

但是,即使表单存在,您的自定义模块也可以覆盖当前请求的标识集。另请注意,在发布表单cookie之前,表单模块不会设置标识。使用表单模块和SessionAuthenticationModule这是很常见的 - 表单可以重定向到登录页面,会话auth模块可以处理自己的身份验证cookie。

这意味着您可以安全地将两者混合使用:表单模块和您自己的自定义模块,用于类似的场景。

达林提出了另一种方法,这当然也是有效的。身份验证模块(与身份验证过滤器相比)的一个优点是身份验证模块可以支持其他ASP.NET子系统(Web表单/ wcf / webapi)。

相关问题