gpt4 book ai didi

c# - 带有 cookie 身份验证的 ASP.Net Core 2.2 : how to avoid page redirect when not authorized for API only controllers

转载 作者:行者123 更新时间:2023-12-05 03:44:53 25 4
gpt4 key购买 nike

我的 ASP .Net Core 2.2 Web 应用程序有一些返回 View(s) 的 Controller 和一些返回 json 结果的 Controller ,因为它们只是 API Controller 。

我的网站使用 cookie 身份验证,声明如下:

services
.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.AccessDeniedPath = "/Pages/AccessDenied";
options.Cookie.HttpOnly = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
options.Cookie.SameSite = SameSiteMode.Strict;
});

配置部分:

// ...
app.UseAuthentication();
app.UseDefaultFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Pages}/{action=Index}/{id?}");
});

我的 PagesController 只是继承自 Microsoft.AspNetCore.Mvc.Controller 并且对于一些页面我放置了 [Authorize] 属性。当非授权用户尝试打开该页面时,它会被正确地重定向到我的公共(public) AccessDenied 页面。一切都很好。

但是,我还有一个 ApiController,它继承自 Microsoft.AspNetCore.Mvc.ControllerBase,具有属性 [ApiController] 和还有一个 [Authorize(Roles = "Administrator")]。我使用此 Controller 与我页面中的 javascript 进行通信。问题是,当非授权用户尝试调用此 Controller 上的方法时,我不希望它以 HTTP 200 页面(AccessDenied 页面)响应,但我想要它仅返回 HTTP 401 Unauthorized,因为它是一个 API。

我怎样才能实现这种不同的行为来保持 cookie 身份验证?

谢谢!

最佳答案

获得此行为的最简单方法是编写一个派生自 CookieAuthenticationEvents 的自定义类并覆盖 RedirectToLoginRedirectToAccessDenied .

如果您不熟悉 CookieAuthenticationEvents 类,您可以从 this example 开始在文档中。基本上,它是为 cookie 身份验证添加自定义行为的插件点。

首先,您需要一种方法来识别您的 AJAX 请求。最简单的方法是在所有 AJAX 请求的请求路径中使用一个公共(public)前缀。例如,您可以决定所有 AJAX 请求路径都将以 /api 开头。

您可以编写以下自定义 CookieAuthenticationEvents 类:

public sealed class CustomCookieAuthenticationEvents : CookieAuthenticationEvents 
{
public override Task RedirectToAccessDenied(
RedirectContext<CookieAuthenticationOptions> context)
{
if (context is null)
{
throw new ArgumentNullException(nameof(context));
}

if (IsAjaxRequest(context.HttpContext))
{
context.Response.StatusCode = StatusCodes.Status403Forbidden;
return Task.CompletedTask;
}
else
{
// non AJAX requests behave as usual
return base.RedirectToAccessDenied(context);
}
}

public override Task RedirectToLogin(RedirectContext<CookieAuthenticationOptions> context)
{
if (context is null)
{
throw new ArgumentNullException(nameof(context));
}

if (IsAjaxRequest(context.HttpContext))
{
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
return Task.CompletedTask;
}
else
{
// non AJAX requests behave as usual
return base.RedirectToLogin(context);
}
}

private static bool IsAjaxRequest(HttpContext httpContext)
{
var requestPath = httpContext.Request.Path;
return requestPath.StartsWithSegments(new PathString("/api"), StringComparison.OrdinalIgnoreCase);
}
}

现在您可以使用 Startup.ConfigureServices 方法中的身份验证服务注册您的自定义 CookieAuthenticationEvents:

services
.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.AccessDeniedPath = "/Pages/AccessDenied";
options.Cookie.HttpOnly = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
options.Cookie.SameSite = SameSiteMode.Strict;
options.EventsType = typeof(CustomCookieAuthenticationEvents);
});

services.AddSingleton<CustomCookieAuthenticationEvents>();

关于c# - 带有 cookie 身份验证的 ASP.Net Core 2.2 : how to avoid page redirect when not authorized for API only controllers,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66193901/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com