我的MVC Web应用程序提供两种类型的用户。
此外,
当用户访问应用程序时,如果他们未登录,则应用程序的反应应该不同。
我习惯使用WCF REST服务,在那里我可以引发这样的异常:
throw new WebProtocolException(System.Net.HttpStatusCode.Unauthorized, exc.Message, exc);
并收到401消息。当我把statusCode
放在这样的时候,在MVC中使用相同方法的问题:
HttpContext.Response.StatusCode = (Int32)HttpStatusCode.Unauthorized
它总是重定向到LogIn页面。
我该怎么做?
我尝试覆盖AuthorizeAttribute
并处理OnAuthorization
函数,但是一旦我将statusCode
设置为401,它就会被重定向到LogIn页面。
答案 0 :(得分:25)
要防止登录页面重定向,您必须将SuppressFormsAuthenticationRedirect
的{{1}}属性设置为true;
HttpContext.Response
答案 1 :(得分:3)
您遇到的是ASP.NET MVC中的漏洞(我希望有一天能解决这个问题)。
ASP.NET的标准操作模型是,如果检测到401 Http Status代码,那么当您遇到时,它会自动重定向到登录页面,即使您通过Ajax调用进入也会发生这种情况。不幸的是,我也没有找到任何改变这种行为的方法。
我所做的是返回一个替代的,否则未使用的Http状态代码,我可以在客户端检测并以适当的方式处理。
因此,在我的身份验证过滤器中,如果是Ajax请求,则返回449,否则返回标准401.然后在客户端上,我可以检查XMLHttpRequest.status并在检测到449时采取适当的操作。
答案 2 :(得分:2)
您可以创建一个简单的授权属性过滤器(扩展AuthorizeAttribute类)并将其用于访问控制。然后尝试这样的事情:
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest() || string.Compare("GET", filterContext.HttpContext.Request.HttpMethod, true) != 0)
{
// Returns 403.
filterContext.Result = new HttpStatusCodeResult((int)HttpStatusCode.Forbidden);
}
else
{
// Returns 401.
filterContext.Result = new HttpUnauthorizedResult();
}
}
结果是,POST和AJAX请求将始终收到403响应,这使您更容易在javascript中处理您的ajax提交。至于非ajax帖子,响应是什么并不重要,因为你的用户不应该首先抓住提交表单:)
对于其他请求,该方法返回401表示FormsAuthentiction模块将接收,然后将您的响应重定向到登录页面。
答案 3 :(得分:1)
这是我设法阻止重定向到登录页面的方式。
在我的情况下,我想收到状态代码,以便在javascript中处理它:
protected void Application_EndRequest()
{
if (Context.Response.StatusCode == 302 && Context.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
{
Context.Response.Clear();
Context.Response.StatusCode = 401;
}
}
答案 4 :(得分:0)
我正在开发一个Web应用程序,它也暴露了一个web api,我没有看到这种行为。
当您使用REST时,您需要一种机制来对发出非公开端点/资源请求的用户进行身份验证。
这种机制可以是:
如果你想要第二种选择,那么从简单到复杂的替代品会使你的解决方案或多或少变得强大。 Amazon's way众所周知且记录正确。但是,如果您的数据不是 敏感,有时只使用https将标记作为标题发送回来就足够了。
无论您使用的是基本HTTP身份验证还是世界上最安全的身份验证机制,您都需要某些来验证您在每个请求中发送的内容,并在上下文中填充Principal。请求。
这个某些东西可以在Asp.net Web Api中使用Message Handler aka DelegatingHandler来实现,它将处理并处理您的api控制器的每个请求并填充您的Principal,基于它找到的身份验证信息。
您可以找到DelegatingHandler实现here
的示例在您拥有此基础架构之后,您应该能够在api控制器级别或操作级别使用 Syste.Web.HttpizeAttributeizeAttribute 又名[授权],根据您的需要。
如果DelegatingHandler无法根据手头的身份验证信息填充主体,那么您应该获得 401 Unauthorized w / o重定向。
不要忘记在App_Start上注册DelegatingHandler。
答案 5 :(得分:0)
您可以在配置身份时使用OnRedirectToLogin方法。