5

我在 Authorize 后面有一些操作方法,例如:

[AcceptVerbs(HttpVerbs.Post), Authorize]
public ActionResult Create(int siteId, Comment comment) {

我遇到的问题是我正在通过 AJAX 发送一个请求来评论/创建

X-Requested-With=XMLHttpRequest

这有助于将请求识别为 AJAX。当用户未登录并点击授权墙时,它会被重定向到

/Account/LogOn?ReturnUrl=Comment%2fCreate

这打破了 AJAX 工作流程。我需要被重定向到

/Account/LogOn?X-Requested-With=XMLHttpRequest

有什么想法可以实现吗?有什么方法可以更好地控制请求授权时发生的事情?

4

4 回答 4

5

感谢 Lewis 的评论,我能够找到这个解决方案(这远非完美,附有我自己的评论,如果你有修复,请随时编辑和删除这个短语),但它有效:

public class AjaxAuthorizeAttribute : AuthorizeAttribute {
    override public void OnAuthorization(AuthorizationContext filterContext) {
        base.OnAuthorization(filterContext);
        // Only do something if we are about to give a HttpUnauthorizedResult and we are in AJAX mode.
        if (filterContext.Result is HttpUnauthorizedResult && filterContext.HttpContext.Request.IsAjaxRequest()) {
            // TODO: fix the URL building:
            // 1- Use some class to build URLs just in case LoginUrl actually has some query already.
            // 2- When leaving Result as a HttpUnauthorizedResult, ASP.Net actually does some nice automatic stuff, like adding a ReturnURL, when hardcodding the URL here, that is lost.
            String url = System.Web.Security.FormsAuthentication.LoginUrl + "?X-Requested-With=XMLHttpRequest";
            filterContext.Result = new RedirectResult(url);
        }
    }
}
于 2009-06-03T21:54:29.020 回答
3

最近我遇到了完全相同的问题,并使用 J. Pablo Fernández 发布的代码进行了修改以解释返回 URL。这里是:

public class AuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute
{
    override public void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);
        // Only do something if we are about to give a HttpUnauthorizedResult and we are in AJAX mode. 
        if (filterContext.Result is HttpUnauthorizedResult && filterContext.HttpContext.Request.IsAjaxRequest())
        {
            // TODO: fix the URL building: 
            // 1- Use some class to build URLs just in case LoginUrl actually has some query already. 
            HttpRequestBase request = filterContext.HttpContext.Request;
            string returnUrl = request.Path;
            bool queryStringPresent = request.QueryString.Count > 0;
            if (queryStringPresent || request.Form.Count > 0)
                returnUrl += '?' + request.QueryString.ToString();
            if (queryStringPresent)
                returnUrl += '&';
            returnUrl += request.Form;
            String url = System.Web.Security.FormsAuthentication.LoginUrl +
                         "?X-Requested-With=XMLHttpRequest&ReturnUrl=" +
                         HttpUtility.UrlEncode(returnUrl);
            filterContext.Result = new RedirectResult(url);
        }
    }
}
于 2010-07-13T13:38:59.153 回答
1

而不是使用授权属性,我一直在做类似下面的事情。

public ActionResult SomeCall(string someData)
{
    if (Request.IsAjaxRequest() == false)
    {
        // TODO: do the intended thing.
    }
    else
    {
        // This should only work with AJAX requests, so redirect
        // the user to an appropriate location.
        return RedirectToAction("Action", "Controller", new { id = ?? });
    }
}
于 2009-06-03T15:50:15.130 回答
0

我认为处理这个问题的正确方法是在你的 Javascript 中进行 AJAX 调用。

如果用户需要被授权(或如您的代码所暗示的那样进行身份验证)并且不需要,您应该通知他们并且可能不允许他们首先尝试和评论。

但是,如果这不符合您的需求。您可以尝试编写自己的授权操作过滤器,可能继承自 MVC 框架附带的过滤器,但会重定向您想要的方式。这很简单。

于 2009-06-03T16:16:37.430 回答