我有一个使用cookie身份验证的ASP.NET Core网站,大部分页面都是这样。对于那些页面,服务器默认响应为向未经授权的客户端提供302重定向是理想的。但是,该网站还接受API请求;它们使用API密钥,不需要cookie。
理想情况下,我希望完全关闭API URL的cookie处理,但至少需要确保如果API客户端未经授权,则服务器不会响应302重定向。
理想情况下,我希望完全关闭API URL的cookie处理,但至少需要确保如果API客户端未经授权,则服务器不会响应302重定向。
如果路径不是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。ASP.NET Core 1的代码有所不同。
针对 .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);
};
其他简单方法
.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;
},
};
})
services.AddIdentity()
)之后,应该调用services.ConfigureApplicationCookie()
,否则这些设置将被覆盖。 - SabreConfigureApplicationCookie
的操作委托参数从未被调用;我在其第一行上设置了断点,但它从未被触发。当我的测试API控制器调用Forbid
时,我的测试客户端应用程序仍然收到HTTP状态码500而不是403。有什么想法吗? - Bart Hofland