由于FormsAuthentication模块在处理OnAuthenticateRequest的自定义http模块之前触发,我很好奇是否可以根据自己的标准取消或使表单身份验证无效。
基本上,我有一个用户登录的进程。在那之后,他们会得到一个令牌。在后续请求触发表单身份验证后,我将得到令牌。然后,我要做的是验证令牌是否在我们的后端服务器上过期。如果它过期了,我需要做些什么,这样他们才能被强制重新登录。我的想法是在我的OnAuthenticateRequest处理程序中做一些事情,稍后将在管道中获得,并强制重定向回登录页面或其他什么。这有可能吗?
发布于 2014-01-02 00:08:13
在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
...
}发布于 2014-01-02 00:40:23
这是可能的吗?
这绝对是可能的。您甚至可以将您的身份验证方案设置为None,这样forms模块就不会出现在管道中,而只有您自己的模块。
但是,即使表单存在,您的自定义模块也可以覆盖为当前请求设置的标识。还要注意,在发出表单cookie之前,表单模块不会设置标识。这在同时使用表单模块和SessionAuthenticationModule时很常见-表单负责重定向到登录页面,会话身份验证模块处理自己的身份验证cookie。
这意味着您可以安全地混合两个模块:表单模块和您自己的自定义模块,用于类似的场景。
Darin提出了另一种方法,这当然也是有效的。
https://stackoverflow.com/questions/20870400
复制相似问题