禁止重定向ASP.NET Core中的API URL

Edw*_*rey 13 authentication cookies http-redirect asp.net-identity-2 asp.net-core

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

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

Edw*_*rey 24

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

services.ConfigureApplicationCookie(options => {
    options.Events.OnRedirectToAccessDenied = ReplaceRedirector(HttpStatusCode.Forbidden, options.Events.OnRedirectToAccessDenied);
    options.Events.OnRedirectToLogin = ReplaceRedirector(HttpStatusCode.Unauthorized, options.Events.OnRedirectToLogin);
});
Run Code Online (Sandbox Code Playgroud)

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

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);
    };
Run Code Online (Sandbox Code Playgroud)

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

更新:以上是针对ASP.NET Core 2. ASP.NET Core 1代码是不同的.

  • +1。应该注意的是,`services.ConfigureApplicationCookie()` 调用应该在设置您的身份验证的调用之后*(在我的例子中是 `services.AddIdentity()`),否则这些设置将被覆盖 (2认同)
  • 我尝试在我的 .NET Core 3.0 Web API 项目中实现您的解决方案,但没有成功。似乎从未调用传递给“ConfigureApplicationCookie”的操作委托参数;我在它的第一行设置了一个断点,但它从未被击中。当我的测试 API 的控制器调用“Forbid”时,我的测试客户端应用程序不断获取 HTTP 状态代码 500 而不是 403。有任何想法吗? (2认同)

daf*_*key 5

对于 .net core 2.x,这里有一个修复(基于爱德华的答案):

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))
            };
        });
Run Code Online (Sandbox Code Playgroud)

在哪里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);
};
Run Code Online (Sandbox Code Playgroud)