IIS的奇怪的AJAX重定向401问题

phu*_*uzi 13 iis ajax asp.net-mvc

我应该删除这个问题吗? 我弄清楚问题是什么,而不是IIS ......请参阅下面的答案,了解结果.

原始问题 我正在开发一个ASP.Net MVC应用程序,并遇到一个奇怪的问题,即URL Rewrite重定向和AJAX请求.

我已将以下重写规则添加到根网站中的Web.config中.

<rewrite>
    <rules>
        <rule name="Account" stopProcessing="true">
            <match url="^SubApp/Account/(.*)$" />
            <action type="Redirect" url="Account/{R:1}" redirectType="Found" />
        </rule>
    </rules>
</rewrite>
Run Code Online (Sandbox Code Playgroud)

如果我使用PermanentTemporary redirectType在配置中但是失败并出现HTTP Error 401.0 - UnauthorizedIIS错误页面,那么一切似乎都可以正常工作.

当我通过浏览器向触发此规则的操作发出正常的GET请求时,例如,https://some-site/SubApp/Account/Settings我得到302 Found,并将location头设置为预期的URL https://some-site/Account/Settings并呈现相应的页面.

但是,当我通过JQuery的AJAX发出GET请求时,即$.get('https://some-site/SubApp/Account/Settings')返回的响应状态代码是,401 Unauthorized但它仍然具有适当的位置标头.

响应的内容是标准的IIS HTTP Error 401.0 - Unauthorized错误页面.

奇怪的是,如果我在配置中使用PermanentTemporary重定向类型但是只有失败,一切似乎都能正常工作Found.

/SubApp是位于根网站下方的单独应用程序/.

这是怎么回事?

截图

redirectType="Permanent" 永久重定向

redirectType="Found" 找到重定向

redirectType="Temporary" 临时重定向

从截图中可以看出,唯一的区别是redirectType指定的Web.config.

正如您所看到的那样,重定向正在按预期发生,但Found重定向类型除外,我希望它能够将302 - Found响应重定向到与其他重定向相同的URL.

phu*_*uzi 5

啊啊,您知道当您暂时不考虑某件事时,会突然受到启发...好吧,昨晚发生了,我发现这个小块可以适当地解决MVC对重定向AJAX请求的坚持验证失败...

protected void Application_EndRequest()
{
    var context = new HttpContextWrapper(Context);
    // MVC retuns a 302 for unauthorized ajax requests so alter to request status to be a 401
    if (context.Response.StatusCode == 302 && context.Request.IsAjaxRequest() && !context.Request.IsAuthenticated)
    {   
        context.Response.Clear();
        context.Response.StatusCode = 401;
    }
}
Run Code Online (Sandbox Code Playgroud)

而且,毫无疑问,context.Request.IsAuthenticated它总是假的,因为它似乎被redirect重置了。

Branislav Abadjimarinov的有关该主题的博客文章中提供了一些帮助,对此进行了更新。

protected void Application_EndRequest()
{
    var context = new HttpContextWrapper(Context);
    // MVC returns a 302 for unauthorized ajax requests so alter to request status to be a 401

    if (context.Response.StatusCode == 302 && context.Request.IsAjaxRequest())
    {
        //Unfortunately the redirect also clears the results of any authentication
        //Try to manually authenticate the user...
        var authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
        if (authCookie != null)
        {
            var authTicket = FormsAuthentication.Decrypt(authCookie.Value);
            if (authTicket != null && !authTicket.Expired)
            {
                var roles = authTicket.UserData.Split(',');
                HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(new FormsIdentity(authTicket), roles);
            }
        }

        if (!context.Request.IsAuthenticated)
        {
            context.Response.Clear();
            context.Response.StatusCode = 401;
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

一切都按预期进行。

唯一的问题是我应该删除这个问题吗?

  • 不要删除它,这可能对将来的访问者有所帮助 (4认同)