关于asp.net mvc:与IIS的奇怪的AJAX重定向401问题

Weird AJAX redirect 401 issue with IIS

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

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

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

1
2
3
4
5
6
7
8
<rewrite>
    <rules>
        <rule name="Account" stopProcessing="true">
            <match url="^SubApp/Account/(.*)$" />
           
        </rule>
    </rules>
</rewrite>

如果我在配置中使用PermanentTemporary redirectType但是使用HTTP Error 401.0 - Unauthorized IIS错误页面失败,则一切似乎都正常。

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

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

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

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

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

这是怎么回事?

截图

redirectType="Permanent"
Permanent Redirect

redirectType="Found"
Found Redirect

redirectType="Temporary"
Temporary Redirect

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

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


啊,你知道,当你暂时没有想到什么东西时,你会突然受到启发......好吧它发生在昨晚,我发现这个小金块用来"修复"MVC对重定向AJAX请求的坚持 身份验证失败

1
2
3
4
5
6
7
8
9
10
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;
    }
}

并且,毫无疑问,context.Request.IsAuthenticated总是假的,因为它似乎被重定向重置。

在Branislav Abadjimarinov关于这个主题的博客文章的帮助下,对此进行了更新。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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;
        }

    }
}

这一切都按预期工作。

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


看看这个无法处理ajax中的302重定向,为什么? [重复],看起来Web浏览器看到Found-302并对其执行操作。