2012-08-31 70 views
1

我有一个自定义属性,用于Ajax请求以防止默认的FormsAuthentication工作流发生(因为它对Ajax请求没有意义)。授权属性让ActionResult代码执行

这是自定义授权属性:

public class AjaxAuthorize : AuthorizeAttribute { 
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { 
     UrlHelper urlHelper; 

     if (filterContext.HttpContext.Request.IsAjaxRequest()) { 
      urlHelper = new UrlHelper(filterContext.RequestContext); 

      filterContext.HttpContext.Response.StatusCode = 401; 
      //Don't let IIS7 be mean. 
      filterContext.HttpContext.Response.TrySkipIisCustomErrors = true; 
      //Return JSON which tells the client where the login page exists if the user wants to authenticate. 
      filterContext.HttpContext.Response.Write(new JavaScriptSerializer().Serialize(
       new { 
        LoginUrl = string.Format("{0}?ReturnURL={1}", FormsAuthentication.LoginUrl, urlHelper.Encode(filterContext.HttpContext.Request.Url.PathAndQuery)) 
       } 
      )); 
      filterContext.HttpContext.Response.End(); 
     } else { 
      base.HandleUnauthorizedRequest(filterContext); 
     } 
    } 
} 

我有我的ActionResult饰以自定义授权属性,像这样:

[HttpPut] 
[ValidateInput(false)] 
[AjaxAuthorize] 
public ActionResult Comment(string id, string comment) { 
    //stuff happens here. 
} 

一个例外是我行动的结果里面扔,因为我尝试访问有关用户的信息,只有当您登录时才会存在。但是,我不明白为什么此代码甚至被执行,因为我的授权属性保护了该操作。

回答

1

我最终返回了一个HTTP 418(我一直想使用它一段时间),以便Forms Authentication模块不会拦截请求。然后在我的脚本中查找状态码,并将其作为未经授权的请求处理,并进行适当的重定向。

+0

我使用了419身份验证超时(不在RFC 2616中)。这有助于我走上正轨。 – GameSalutes

0

尝试在IF块内调用base.HandleUnauthorizedRequest(filterContext);。或者只是删除ELSE块并始终呼叫base.HandleUnauthorizedRequest(filterContext);

+0

这没有办法。 –

+0

这不是您可能要查找的答案,但我会尝试再次启动此方法,只调用基本方法,然后逐步调试并添加代码以确定哪个命令导致其失败。 – AndreCruz

1

这是HandleUnauthorizedRequest的默认实现。可能你需要分配包含你需要的JSON的自定义ActionResult和有效的状态码。我不确定HTTP上下文中的直接处理请求对象是否有效。

+0

由于用户未经过身份验证,现有的'AuthorizeCore'已经返回false。 –

+0

对不起,答案已编辑。以前的答案版本包含假设AuthorizeCode方法返回true。 – STO

+0

如何停止表单身份验证模块踢入?我只想返回JSON,而不是重定向到登录页面。 –