JWT не имеет срока действия

Я использую Identity Server 4 для аутентификации и для создания JWT с efCore, у меня есть API и запрос на получение, который должен получить список данных, поэтому, когда я «вхожу» с помощью Postman, генерируется токен, если я снова войду в систему и используйте первый токен, запрос на получение возвращает 401 и список данных, хотя у меня есть AllowAnonymous для этого конкретного действия, кто-нибудь знает причину такого поведения

Получить конечную точку

[HttpGet]
        [AllowAnonymous]
        public override Task<ActionResult<List<DataVM>>> Get()
        {
            return base.Get();
        }

Скелет CRUD

[HttpGet]
        public virtual async Task<ActionResult<List<TValueModel>>> Get()
        {
            var userClaim = User.Claims.FirstOrDefault(c => c.Type == JwtClaimTypes.Subject);
            List<TValueModel> records;
            if (userClaim != null)
            {
                records = await Mediator.Send(new GetAll<TModel, TValueModel>
                {
                    UserId = Guid.Parse(userClaim.Value)
                });
                return records;
            }
            records = await Mediator.Send(new GetAll<TModel, TValueModel>());
            return records;
        }

Запустить

services.AddIdentity<User, Role>(options =>
                {
                    options.User.RequireUniqueEmail = true;


                })
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();

            services.Configure<SecurityStampValidatorOptions>(options => options.ValidationInterval = TimeSpan.FromSeconds(10));

            var builder = services.AddIdentityServer(options =>
            {
                options.Events.RaiseErrorEvents = true;
                options.Events.RaiseInformationEvents = true;
                options.Events.RaiseFailureEvents = true;
                options.Events.RaiseSuccessEvents = true;

            })
                .AddInMemoryIdentityResources(IdentityConfig.Ids)
                .AddInMemoryApiResources(IdentityConfig.Apis)
                .AddInMemoryClients(IdentityConfig.Clients)
                .AddAspNetIdentity<User>();


            builder.AddDeveloperSigningCredential();

            services.AddTransient<IProfileService, ProfileService>();

            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
                options.DefaultForbidScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
            })
            .AddIdentityServerAuthentication(options =>
            {
                options.Authority = Configuration.GetValue<string>("Host");
                options.RequireHttpsMetadata = false;
                options.JwtBearerEvents.OnAuthenticationFailed =
                    C =>
                    {
                        C.Response.StatusCode = StatusCodes.Status401Unauthorized;
                        return Task.CompletedTask;
                    };
                options.ApiName = "api1";
            });

person Asker    schedule 24.04.2020    source источник
comment
Покажите соответствующие коды, пожалуйста.   -  person Nan Yu    schedule 27.04.2020
comment
Является ли этот вопрос специфичным для IdentityServer4 или он больше связан с маршрутизацией ASP.NET Core? Похоже, вы спрашиваете, почему конечная точка, отмеченная [AllowAnonymous], возвращает 401 с вашим списком. Это правильно?   -  person Randy    schedule 29.04.2020
comment
@ Рэнди, да, я именно то, о чем спрашивал, я попытался объяснить, что я сделал, чтобы пролить свет на то, что происходит, конечная точка помечена как allowanonymous, если я вхожу в систему с двумя разными пользователями, 1 после другого на почтальоне, а затем попробуйте чтобы попасть в конечную точку, разрешив анонимность, используя первый jwt, я получаю 401 и список данных, которые возвращаются этой конечной точкой   -  person Asker    schedule 29.04.2020
comment
Можете ли вы опубликовать код, связанный с вашим методом контроллера?   -  person Randy    schedule 29.04.2020
comment
Я отредактировал пост, чтобы показать контроллер и запуск, надеюсь, это поможет.   -  person Asker    schedule 29.04.2020
comment
Используете ли вы «UseAuthorization» в своем методе «Configure»? Если это так, я могу объяснить поведение, которое вы видите   -  person Randy    schedule 07.05.2020
comment
@ Рэнди, да, я использую useAuthorization   -  person Asker    schedule 11.05.2020


Ответы (1)


Я думаю, что здесь происходит то, что AuthorizationMiddleware (добавленный в конвейер в вашем вызове «UseAuthorization») устанавливает код состояния ответа на 401 еще до того, как он достигнет ваших контроллеров.

Если бы вы использовали MVC для маршрутизации, авторизация выполнялась бы с помощью AuthorizationFilter, полученный из вашего маршрута. Если вы используете маршрутизацию конечной точки, что кажется более вероятным, поскольку вы упомянули, что это был API, AuthorizationMiddleware обрабатывает авторизацию маршрута (который добавляется в конвейер вызовом UseAuthorization).

И AuthorizeFilter, и AuthorizationMiddleware имеют зеркальную логику для авторизации, и независимо от того, какой из них вы в конечном итоге используете, поведение, скорее всего, будет одинаковым.

Проблемной областью в логике авторизации, предполагающей, что у вас установлен атрибут Authorize на контроллере или настроены некоторые другие данные авторизации, является часть в AuthorizationMiddleware, где выполняется аутентификация. Это происходит перед атрибутом AllowAnonymous. даже ищется на маршруте. Это приведет к применению любых сбоев, связанных с проверкой подлинности, даже если маршрут помечен атрибутом AllowAnonymous.

Поскольку для вашей схемы аутентификации настроено следующее:

options.JwtBearerEvents.OnAuthenticationFailed =
    C =>
    {
        C.Response.StatusCode = StatusCodes.Status401Unauthorized;
        return Task.CompletedTask;
    };

Когда схема аутентификации JwtBearer пытается аутентифицировать пользователя на основе токена, кажется, что аутентификация завершается ошибкой, и код состояния устанавливается равным 401 в соответствии с настроенным выше событием OnAuthenticationFailed. Тем не менее, этот сбой проверки подлинности не приводит к сбою запроса, и веб-приложение по-прежнему может выполнять действие конечной точки, в результате чего возвращается список и код состояния Неавторизованный.

Что касается другого вопроса о том, почему токен не проходит аутентификацию, это потребует дальнейшего изучения вашей конфигурации IdentityServer и значений, используемых в вашей конфигурации.

Это поведение запросов проверки подлинности ASP.NET Core на маршрутах с AllowAnonymous также обсуждается здесь для дополнительного контекста: https://github.com/aspnet/Security/issues/1577

person Randy    schedule 17.05.2020