禁止在 ASP.NET Core 中对 API URL 进行重定向

Posted

技术标签:

【中文标题】禁止在 ASP.NET Core 中对 API URL 进行重定向【英文标题】:Suppress redirect on API URLs in ASP.NET Core 【发布时间】:2017-06-21 04:08:27 【问题描述】:

我有一个 ASP.NET Core 站点,它对大多数页面使用 cookie 身份验证。对于这些页面,需要为未经授权的客户端提供 302 重定向的默认服务器响应。但是,该站点也接受 API 请求;他们使用 API 密钥,不使用 cookie。

理想情况下,我想完全关闭 API URL 的 cookie 处理,但至少,我需要确保如果 API 客户端未经授权,服务器不会以 302 重定向响应。

【问题讨论】:

【参考方案1】:

仅当路径不是 API 时,将重定向事件处理程序替换为使用默认行为的处理程序。在Startup.ConfigureServices 中添加:

services.ConfigureApplicationCookie(options => 
    options.Events.OnRedirectToAccessDenied = ReplaceRedirector(HttpStatusCode.Forbidden, options.Events.OnRedirectToAccessDenied);
    options.Events.OnRedirectToLogin = ReplaceRedirector(HttpStatusCode.Unauthorized, options.Events.OnRedirectToLogin);
);

使用此辅助方法替换重定向方法:

static Func<RedirectContext<CookieAuthenticationOptions>, Task> ReplaceRedirector(HttpStatusCode statusCode, Func<RedirectContext<CookieAuthenticationOptions>, Task> existingRedirector) =>
    context => 
        if (context.Request.Path.StartsWithSegments("/api")) 
            context.Response.StatusCode = (int)statusCode;
            return Task.CompletedTask;
        
        return existingRedirector(context);
    ;

有了这个,API 控制器方法可以调用 Unauthorized()Forbid() 而不会导致重定向。

更新:以上是针对 ASP.NET Core 2 的。code for ASP.NET Core 1 不同。

【讨论】:

+1。应该注意的是,services.ConfigureApplicationCookie() 调用应该在 设置您的身份验证的调用之后(在我的情况下为 services.AddIdentity()),否则这些设置将被覆盖 与 spa 一起使用时,这似乎是一种非常干净的方式。 我尝试在我的 .NET Core 3.0 Web API 项目中实现您的解决方案,但没有成功。似乎从未调用过传递给ConfigureApplicationCookie 的动作委托参数;我在它的第一行设置了一个断点,但它从未被命中。当我的测试 API 的控制器调用 Forbid 时,我的测试客户端应用程序不断收到 HTTP 状态代码 500 而不是 403。有什么想法吗? .NET Core 3.1 也有同样的问题。这段代码似乎根本不起作用。有什么想法吗? 这是一个绝妙的解决方案,可以确认它适用于 .NET Core 5.0【参考方案2】:

对于 .net core 2.x,这里有一个修复(基于 Edward 的回答):

services.ConfigureApplicationCookie(options =>
        
            options.Events = new CookieAuthenticationEvents
            
                OnRedirectToAccessDenied = ReplaceRedirector(HttpStatusCode.Forbidden, context => options.Events.RedirectToAccessDenied(context)),
                OnRedirectToLogin = ReplaceRedirector(HttpStatusCode.Unauthorized, context => options.Events.RedirectToLogin(context))
            ;
        );

ReplaceRedirector:

Func<RedirectContext<CookieAuthenticationOptions>, Task> ReplaceRedirector(HttpStatusCode statusCode, Func<RedirectContext<CookieAuthenticationOptions>, Task> existingRedirector) =>
context =>

    if (context.Request.Path.StartsWithSegments("/api"))
    
        context.Response.StatusCode = (int)statusCode;
        return Task.CompletedTask;
    
    return existingRedirector(context);
;

【讨论】:

我更新了我的答案以包含 ASP.NET Core 2。在我的更新中,我没有替换 Events,而只是设置了它的相关属性。【参考方案3】:

其他简单的方法

 .AddCookie(options =>
            
                options.AccessDeniedPath = "/Home/401";
                options.Events = new CookieAuthenticationEvents
                
                    OnRedirectToAccessDenied = context => 
                    
                        if (context.Request.Path.StartsWithSegments("/api"))
                        
                            context.Response.StatusCode = (int)(HttpStatusCode.Unauthorized);
                        
                        return Task.CompletedTask;
                    ,
                ;
            )

【讨论】:

以上是关于禁止在 ASP.NET Core 中对 API URL 进行重定向的主要内容,如果未能解决你的问题,请参考以下文章

.NET Core 3.0 Preview 6中对ASP.NET Core和Blazor的更新

Linq 查询在 ASP.NET-Core 3.0 及更高版本中对数字等字符串进行排序

ASP.NET Core2.2 和2.1 版本中对cookie的设置和存储

ASP.NET Core 搭载 Envoy 实现微服务身份认证(JWT)

ASP.NET Core 搭载 Envoy 实现微服务身份认证(JWT)

asp.net web.config的设置问题