C# ASP。Net Core 2.2与cookie身份验证:如何在未授权仅API控制器时避免页面重定向
我的ASP.Net Core2.2web应用程序有一些返回C# ASP。Net Core 2.2与cookie身份验证:如何在未授权仅API控制器时避免页面重定向,c#,asp.net-mvc,asp.net-core,C#,Asp.net Mvc,Asp.net Core,我的ASP.Net Core2.2web应用程序有一些返回视图的控制器和一些返回json结果的控制器,因为它们只是API控制器 我的网站使用cookie身份验证,声明如下: services .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { options.AccessDeniedPath = "/Pag
视图的控制器和一些返回json结果的控制器,因为它们只是API控制器
我的网站使用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]
属性。当未经授权的用户尝试打开页面时,它会被正确重定向到my publicAccessDenied
页面。一切都很好
但是,我还有一个ApiController
,它继承自Microsoft.AspNetCore.Mvc.ControllerBase
,有一个属性[ApiController]
,还有一个[Authorize(Roles=“Administrator”)]
。我使用这个控制器与页面中的javascript进行通信。问题是,当非授权用户尝试调用此控制器上的方法时,我不希望它以HTTP 200页面(拒绝访问的AccessDenied
one)响应,但我希望它只返回HTTP 401 Unauthorized,因为它是API。
如何在保持cookie身份验证的情况下实现如此不同的行为
谢谢 获得此行为的最简单方法是编写一个自定义类,该类派生并重写and
如果您不熟悉CookieAuthenticationEvents
类,可以从文档中开始。基本上,它是一个为cookie身份验证添加自定义行为的插件
首先,您需要一种识别AJAX请求的方法。最简单的方法是在所有AJAX请求的请求路径中使用公共前缀。例如,您可以决定所有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);
}
}
基本上,当一个未经授权的AJAX调用到达一个API控制器时,HTTP响应是一个原始401状态代码,对吗?(而不是302重定向到登录页面或拒绝访问页面)您是否只使用API控制器进行来自前端页面的AJAX调用?这两个问题都是肯定的!
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>();