ASP.NET Core Web与API Cookie认证分离配置咨询
问题背景
项目同时包含Web页面和API接口,需求如下:
- Web页面:未登录访问权限页面时,保持重定向到登录页的原有逻辑。
- API接口:未认证时返回
401 Unauthorized或403 Forbidden状态码,而非登录页面的HTML内容。
当前问题:调用/api/Batch等接口时,未认证状态下返回登录页面HTML,不符合API预期。
解决方案
核心思路是在Cookie认证的事件处理中,根据请求类型区分响应方式:API请求返回状态码,Web请求保持重定向。
步骤1:修改Cookie认证事件配置
更新服务配置中的ConfigureApplicationCookie部分,添加请求类型判断逻辑:
services.ConfigureApplicationCookie(options => { options.Cookie.Name = ".AspNetCore.Cookies"; options.Cookie.HttpOnly = true; options.LoginPath = "/Account/SignIn"; options.LogoutPath = "/Account/SignOut"; options.AccessDeniedPath = "/Account/SignIn"; options.SlidingExpiration = true; options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter; // 处理未登录请求:区分API与Web options.Events.OnRedirectToLogin = context => { bool isApiRequest = context.Request.Path.StartsWithSegments("/api") || context.Request.Headers.TryGetValue("Accept", out var accept) && accept.Contains("application/json"); if (isApiRequest) { context.Response.StatusCode = StatusCodes.Status401Unauthorized; return Task.CompletedTask; } // Web请求维持原有重定向逻辑 context.Response.Redirect(context.RedirectUri); return Task.CompletedTask; }; // 处理权限不足请求:区分API与Web options.Events.OnRedirectToAccessDenied = context => { bool isApiRequest = context.Request.Path.StartsWithSegments("/api") || context.Request.Headers.TryGetValue("Accept", out var accept) && accept.Contains("application/json"); if (isApiRequest) { context.Response.StatusCode = StatusCodes.Status403Forbidden; return Task.CompletedTask; } // Web请求维持原有重定向逻辑 context.Response.Redirect(context.RedirectUri); return Task.CompletedTask; }; });
步骤2:保留API控制器原有配置
API控制器(如BatchController)的[Authorize]特性无需修改,保持原有配置即可:
[Authorize] [Route("api/[controller]")] [ApiController] public class BatchController : ControllerBase { private readonly ScanLinkContext _scanlinkContext; public BatchController(ScanLinkContext scanLinkContext) { _scanlinkContext = scanLinkContext; } // 原有接口方法不变 }
关键说明
- 登录接口
/api/Authentication/Login无需调整,API与Web共用同一个Cookie认证会话。 - 判断逻辑采用路径前缀+Accept头的组合,既覆盖了以
/api开头的API请求,也兼容了可能跨域或路径不固定但明确要求JSON响应的API请求。
内容的提问来源于stack exchange,提问作者Almaran
相关产品推荐
相关产品推荐

