У меня проблема с тем, как .NET Core обрабатывает аутентификацию JSON Web Token (JWT) в моей производственной среде. Я тестирую с помощью Почтальона. Если я вызываю мой API с действительным токеном, он работает нормально и возвращает ожидаемый ответ от конечной точки API. Однако, если срок действия токена истек, я не получаю ожидаемый HTTP 401. На самом деле я не получаю никакого ответа, он просто тихо терпит неудачу. Кажется, что-то в моей производственной конфигурации не работает. Если я проверю это в своей локальной среде разработки, у меня не возникнет проблем, и токены с истекшим сроком действия получат не авторизованный HTTP-ответ 401, как ожидалось.
Мое веб-приложение использует как аутентификацию куки-файлов для тех, кто выполняет вход через веб-сайт, так и аутентификацию JWT для тех, кто подключается к API. Вот конфигурация для аутентификации JWT. Это в Startup.cs. Это часть конфигурации JWT сервисов. Аутентификация. Проверка подлинности с помощью cookie-файлов устанавливается первой и является схемой проверки подлинности по умолчанию.
.AddJwtBearer(options =>{
options.RequireHttpsMetadata = !_hostingEnvironment.IsDevelopment();
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Settings.Api.JwtBearer.TokenValidation.ValidIssuer,
ValidAudience = Settings.Api.JwtBearer.TokenValidation.ValidAudience,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Settings.Api.JwtBearer.TokenValidation.IssuerSigningKey))
};
options.Events = new JwtBearerEvents()
{
OnAuthenticationFailed = context =>
{
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
context.Response.ContentType = "application/json; charset=utf-8";
var message = _hostingEnvironment.IsDevelopment() ? context.Exception.ToString() : "An error occurred processing your authentication.";
var result = JsonConvert.SerializeObject(new { message });
return context.Response.WriteAsync(result);
}
};});
А вот другая соответствующая конфигурация в Startup.cs:
public void Configure(IApplicationBuilder app, IHostingEnvironment env){
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error/Exception");
app.UseStatusCodePagesWithReExecute("/Error/{0}");
app.UseHsts();
app.UseHttpsRedirection();
}
app.UseStaticFiles();
app.UseCors(Constants.Security.Cors.PolicyName);
app.UseAuthentication();
app.UseMvc(ConfigureRoutes);}
`
Я много играл с настройкой Configure и тестировал ее на производстве, но я всегда получаю ответ, когда аутентификация токена заканчивается неудачей. Так как он хорошо работает в моей локальной среде разработки, это должно означать, что с моей производственной конфигурацией что-то не так, но я в замешательстве и без идей. Для получения дополнительной информации вот пример ошибки из журналов ошибок:
информация:
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler [1]
Не удалось проверить токен. Microsoft.IdentityModel.Tokens.SecurityTokenExpiredException:
IDX10223: Проверка продолжительности жизни не удалась. Срок действия токена истек. Действителен до:
'[PII скрыт]', Текущее время: '[PII скрыт]'. в
Microsoft.IdentityModel.Tokens.Validators.ValidateLifetime (Nullable 1
notBefore, Nullable
1 истекает, SecurityToken securityToken,
TokenValidationParameters validationParameters) в
System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateLifetime (Nullable 1
notBefore, Nullable
1 истекает, JwtSecurityToken jwtToken,
TokenValidationParameters validationParameters) в
System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateTokenPayload (JwtSecurityToken
jwtToken, TokenValidationParameters validationParameters) в
System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken (String
токен, TokenValidationParameters validationParameters, SecurityToken &
validatedToken) в
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.d__6.MoveNext ()
Информация:
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler [7]
Носитель не был аутентифицирован. Сообщение об ошибке: IDX10223: проверка срока службы не удалась. Срок действия токена истек. ValidTo: '[PII является
скрытый] ', Текущее время:' [PII скрыт] '. Информация:
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService [2]
Авторизация не удалась. информация: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker [3]
Авторизация не выполнена для запроса в фильтре «Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter». Информация:
Microsoft.AspNetCore.Mvc.ChallengeResult [1]
Выполнение ChallengeResult со схемами аутентификации (Bearer). информация: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker [2]
Выполнено действие Web.Controllers.ApiController.Users (Web) в 109.4625ms информация: Microsoft.AspNetCore.Routing.EndpointMiddleware [1]
Ошибка выполнения конечной точки «Web.Controllers.ApiController.Users (Web)»: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware [1]
Произошло необработанное исключение при выполнении запроса. System.InvalidOperationException: StatusCode не может быть установлен, потому что
ответ уже начался. в
Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.set_StatusCode (Int32
значение) вMicrosoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.set_StatusCode (Int32
значение) в
Microsoft.AspNetCore.Http.Internal.DefaultHttpResponse.set_StatusCode (Int32
значение) в
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.d__7.MoveNext ()
Заранее спасибо за любые идеи о том, как это исправить.