Ошибка AspNetCore.Authentication.JwtBearer из-за отсутствия SecurityTokenValidator, доступного для токена с ядром .net RC2

Я пытаюсь заставить работать простую конечную точку, которая выдает и потребляет токены JWT с помощью AspNew.Security.OpenIdConnect.Server для выдачи токена и проверки с помощью Microsoft.AspNetCore.Authentication.JwtBearer.

Я могу сгенерировать штраф для токена, но попытка аутентификации токена завершается ошибкой Bearer was not authenticated. Failure message: No SecurityTokenValidator available for token: {token}

На данный момент я удалил все и получил следующее:

project.json

{
  "dependencies": {
    "Microsoft.AspNetCore.Mvc": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.0-rc2-final",
    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0-rc2-final",
    "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0-rc2-final",
    "Microsoft.Extensions.Configuration.Json": "1.0.0-rc2-final",
    "Microsoft.Extensions.Logging": "1.0.0-rc2-final",
    "Microsoft.Extensions.Logging.Console": "1.0.0-rc2-final",
    "Microsoft.Extensions.Logging.Debug": "1.0.0-rc2-final",
    "AspNet.Security.OAuth.Validation": "1.0.0-alpha1-final",
    "AspNet.Security.OpenIdConnect.Server": "1.0.0-beta5-final",
    "Microsoft.AspNetCore.Authentication": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Authentication.JwtBearer": "1.0.0-rc2-final"
  },

  "tools": {
    "Microsoft.AspNetCore.Server.IISIntegration.Tools": {
      "version": "1.0.0-preview1-final",
      "imports": "portable-net45+win8+dnxcore50"
    }
  },

  "frameworks": {
    "net461": { }
  },

  "buildOptions": {
    "emitEntryPoint": true,
    "preserveCompilationContext": true
  },

  "publishOptions": {
    "include": [
      "wwwroot",
      "Views",
      "appsettings.json",
      "web.config"
    ]
  },

  "scripts": {
    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
  }
}

Методы Startup.cs:

// This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddAuthorization(options =>
                {
                    options.AddPolicy(JwtBearerDefaults.AuthenticationScheme,
                        builder =>
                        {
                            builder.
                            AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme).
                            RequireAuthenticatedUser().
                            Build();
                        }
                    );
                }
            );

            services.AddAuthentication();
            services.AddDistributedMemoryCache();
            services.AddMvc();
            services.AddOptions();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            var jwtOptions = new JwtBearerOptions()
            {
                AuthenticationScheme = JwtBearerDefaults.AuthenticationScheme,
                AutomaticAuthenticate = true,
                Authority = "http://localhost:5000/",
                Audience = "http://localhost:5000/",
                RequireHttpsMetadata = false
            };

            jwtOptions.ConfigurationManager = new ConfigurationManager<OpenIdConnectConfiguration>
                (
                    metadataAddress: jwtOptions.Authority + ".well-known/openid-configuration",
                    configRetriever: new OpenIdConnectConfigurationRetriever(),
                    docRetriever: new HttpDocumentRetriever { RequireHttps = false }
                );


            app.UseJwtBearerAuthentication(jwtOptions);

            app.UseOpenIdConnectServer(options =>
            {
                options.AllowInsecureHttp = true;
                options.AuthorizationEndpointPath = Microsoft.AspNetCore.Http.PathString.Empty;
                options.Provider = new OpenIdConnectServerProvider
                {
                    OnValidateTokenRequest = context =>
                    {
                        context.Skip();
                        return Task.FromResult(0);
                    },

                    OnGrantResourceOwnerCredentials = context =>
                    {
                        var identity = new ClaimsIdentity(context.Options.AuthenticationScheme);
                        identity.AddClaim(ClaimTypes.NameIdentifier, "[unique id]");

                        identity.AddClaim("urn:customclaim", "value", OpenIdConnectConstants.Destinations.AccessToken, OpenIdConnectConstants.Destinations.IdentityToken);

                        var ticket = new AuthenticationTicket(
                            new ClaimsPrincipal(identity),
                            new Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties(),
                            context.Options.AuthenticationScheme);

                        ticket.SetScopes("profile", "offline_access");

                        context.Validate(ticket);

                        return Task.FromResult(0);
                    }
                };
            });            

            app.UseMvc();
        }

отправка POST в кодировке x-url на http://localhost:5000 с grant_type = password, username = foo, password = bar генерирует ожидаемый access_token.

Я добавил атрибут [Authorize("Bearer")] в ValuesController, и он работает должным образом при вызове JwtBearerMiddlewear, но я не могу получить токен для проверки.

У кого-нибудь это работает с .net core RC2? У меня то же самое работает над RC1, но я не могу это запустить.

Спасибо.


person koocbor    schedule 19.05.2016    source источник


Ответы (2)


Начиная с beta5 (для ASP.NET Core RC2), OpenID Connect промежуточное ПО сервера больше не использует JWT в качестве формата по умолчанию для токенов доступа. Вместо этого он использует непрозрачные токены, зашифрованные надежным стеком защиты данных ASP.NET Core (точно так же, как файлы cookie проверки подлинности).

У вас есть 3 варианта исправить ошибку, которую вы видите:

  • Используйте новую проверку OAuth2 промежуточное ПО, разработанное для поддержки непрозрачных токенов (рекомендуемый вариант, если ваш API и сервер авторизации являются частью одного и того же приложения). Для этого оставьте ссылку AspNet.Security.OAuth.Validation в project.json и замените app.UseJwtBearerAuthentication(...) просто app.UseOAuthValidation(). Вы также можете удалить Microsoft.AspNetCore.Authentication.JwtBearer из project.json.

  • Заставьте промежуточное ПО сервера OpenID Connect использовать токены JWT, вызвав options.AccessTokenHandler = new JwtSecurityTokenHandler(); в параметрах. Обратите внимание, что вам также придется вызвать ticket.SetResources(...), чтобы прикрепить соответствующую аудиторию с токенами JWT (см. Другой сообщение SO для больше информации).

  • Используйте новое промежуточное ПО для интроспекции . Этот вариант более сложен и требует реализации события ValidateIntrospectionRequest для проверки учетных данных клиента. Используйте его, только если знаете, что делаете.
person Kévin Chalet    schedule 19.05.2016
comment
Если вы решите использовать интроспекцию, вам нужен пакет здесь . Не AspNet.Security.OAuth.Extensions - person paulio; 21.09.2016
comment
это кажется очень специфичным для версии - person DanielV; 02.12.2019

Боковое примечание, если у кого-то такая же ошибка (Нет SecurityTokenValidator для токена):

Дважды проверьте, что заголовок аутентификации, отправленный клиентом, действительно имеет правильный формат:

Authorize: Bearer [ey....]

Нет SecurityTokenValidator, доступного для ошибки токена, указывает, что не зарегистрирован обработчик для формата заголовка авторизации, найденного в запросе. Например, у вас будет эта ошибка, если полученный запрос содержит значение заголовка Bearer Bearer ey82383 ..., или если ключевое слово Bearer пропущено или написано с ошибкой.

person Efrain    schedule 21.06.2021