在我的 ASP.NET Core 项目中,我有一些具有 jwt 授权的 API 控制器,如下所示:
[Route("api/v1/[controller]")]
public class MyController : Controller
{
[HttpGet("[action]")]
[Authorize(Policy = MyPolicy)]
public JsonResult FetchAll()
{
}
}
当访问操作 FetchAll() 的授权失败时,我希望 HttpStatusCode.Forbidden 作为响应。相反,Mvc 会重新路由到 Account/Login?ReturnUrl=[...]
我尝试捕获重定向事件并返回禁止/未经授权覆盖 Cookie 事件,但无济于事:
app.UseIdentity();
var tokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = TokenController.DummyKey,
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = true,
ClockSkew = TimeSpan.FromMinutes(0)
};
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
TokenValidationParameters = tokenValidationParameters,
});
app.UseCookieAuthentication(new CookieAuthenticationOptions()
{
AutomaticAuthenticate = false,
AutomaticChallenge = false,
AuthenticationScheme = "BsCookie",
CookieName = "access_token",
TicketDataFormat = new CustomJwtDataFormat(SecurityAlgorithms.HmacSha256, tokenValidationParameters),
Events = new CookieAuthenticationEvents
{
OnRedirectToLogin = context =>
{
if (context.Request.Path.StartsWithSegments("/api") && context.Response.StatusCode == (int)HttpStatusCode.OK)
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
else
context.Response.Redirect(context.RedirectUri);
return Task.FromResult(0);
},
OnRedirectToAccessDenied = context =>
{
if (context.Request.Path.StartsWithSegments("/api") && context.Response.StatusCode == (int)HttpStatusCode.OK)
context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
else
context.Response.Redirect(context.RedirectUri);
return Task.FromResult(0);
}
},
});
这两个事件都不会被调用,并且 Visual Studio 输出显示 fetchall 失败并且将返回帐户/登录:
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:6460/api/v1/Lehrer/GetAll application/json
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware:Information: Successfully validated the token.
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware:Information: HttpContext.User merged via AutomaticAuthentication from authenticationScheme: Bearer.
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Information: Authorization failed for user: (null).
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
Microsoft.AspNetCore.Mvc.ChallengeResult:Information: Executing ChallengeResult with authentication schemes ().
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware:Information: AuthenticationScheme: Bearer was forbidden.
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware:Information: AuthenticationScheme: Identity.Application was challenged.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action Sam.Learning2.Controllers.LehrerController.GetAll (Sam.Learning2) in 49.7114ms
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 121.6106ms 302
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:6460/Account/Login?ReturnUrl=%2Fapi%2Fv1%2FLehrer%2FGetAll
我希望我的 API 返回 401/403,而不是重定向到登录 - 当上述代码不起作用时,如何实现此目的?