Sha*_*run 5 c# asp.net asp.net-mvc asp.net-ajax asp.net-mvc-5
我正在一个MVC项目中工作,其中每个操作方法的用户角色和权限都存储在数据库中.我想要实现的是通过重写AuthorizeAttribute在mvc中使用授权过滤器功能.这样我就可以全局注册我的自定义授权过滤器.
这是我想要做的,遵循这个方法.我正在关注这篇文章来处理ajax请求.
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
//Custom permission checking logic
return false;//no permission for all methods-Just for testing
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
CheckIfUserIsAuthenticated(filterContext);}
}
private void CheckIfUserIsAuthenticated(AuthorizationContext filterContext)
{
// If Result is null, we’re OK: the user is authenticated and authorized.
if (filterContext.Result == null)
return;
var httpContext = filterContext.HttpContext;
var request = httpContext.Request;
var response = httpContext.Response;
var user = httpContext.User;
// If here, you’re getting an HTTP 401 status code. In particular,
// filterContext.Result is of HttpUnauthorizedResult type. Check Ajax here.
if (request.IsAjaxRequest())
{
if (user.Identity.IsAuthenticated == false)
response.StatusCode = (int)HttpStatusCode.Unauthorized;//401
else
response.StatusCode = (int)HttpStatusCode.Forbidden;//403
response.SuppressFormsAuthenticationRedirect = true;
response.End();// This line is causing the problems
return;
}
if (user.Identity.IsAuthenticated)
{
//Redirect to customerror page
}
}
Run Code Online (Sandbox Code Playgroud)
问题是当我使用ajax post调用方法时,我的自定义异常过滤器正在捕获错误说"Server cannot set status after HTTP headers have been sent "
如果我删除response.End(),我在ajax错误处理程序方法而不是403中得到401响应.我试过
HttpContext.Current.ApplicationInstance.CompleteRequest()
Run Code Online (Sandbox Code Playgroud)
而不是response.end,但后来我也得到401错误
反正有没有避免这种例外?
更新 我在javascript中使用这个通用错误处理程序方法来捕获所有ajax请求错误(我需要正确的响应状态代码):
function ajaxFailed(xhr, textstatus, errorthrown) {
debugger;
if (textstatus == "error") {
if (xhr.status == 401) {
window.location = "/Account/Login";
}
if (xhr.status == 403) {
$("#divoutput").html("you don't have permission.");
}
}
if (xhr.status == 500) {
$("#divoutput").append("<br/> internal servererror." + xhr.responseText);
}
}
Run Code Online (Sandbox Code Playgroud)
更新2: 我当前的解决方案: 检查我的自定义异常处理程序过滤器中引发的异常的Exception.Message属性,如果消息是:"服务器无法在发送HTTP标头后设置状态",则忽略它.
我知道这是一种效率低下的方法,但我还没有其他解决方案.等待一个好的解决方案:)
尝试更改处理请求的顺序:
public override void OnAuthorization(AuthorizationContext filterContext)
{
CheckIfUserIsAuthenticated(filterContext);}
base.OnAuthorization(filterContext);
}
Run Code Online (Sandbox Code Playgroud)
更新:
您链接的文章说您必须处理其他事件处理程序方法 HandleUnauthorizedRequest:
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
Run Code Online (Sandbox Code Playgroud)
不是OnAuthorization像你那样。
更新#2:
尝试使用缓冲输出
Response.BufferOutput = true;
Run Code Online (Sandbox Code Playgroud)
因此您的服务器无法将标头发送回客户端。
| 归档时间: |
|
| 查看次数: |
1169 次 |
| 最近记录: |