ASP Core 2.0 JwtBearerAuthentication не работает

Я пытаюсь использовать JwtBearerAuthentication в ядре Asp 2.0 и столкнулся с двумя основными проблемами.

Метод запуска Configure выглядит следующим образом:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
            {
                HotModuleReplacement = true
            });
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseTestSensitiveConfiguration(null);

        app.UseStaticFiles();

        app.UseAuthentication();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");

            routes.MapSpaFallbackRoute(
                name: "spa-fallback",
                defaults: new { controller = "Home", action = "Index" });
        });
    }

и ConfigureServices, как показано ниже:

public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc()
            .AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver())
            .AddJsonOptions(options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);

        services.AddDbContext<FGWAContext>(options => options.UseSqlServer(connection));

        services.AddIdentity<User, Role>()
            .AddEntityFrameworkStores<FGWAContext>()
            .AddDefaultTokenProviders();

        services.Configure<IdentityOptions>(options =>
        {
            // Password settings
            options.Password.RequireDigit = false;
            options.Password.RequiredLength = 4;
            options.Password.RequireNonAlphanumeric = false;
            options.Password.RequireUppercase = false;
            options.Password.RequireLowercase = false;

            // Lockout settings
            options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
            options.Lockout.MaxFailedAccessAttempts = 10;

            // User settings
            options.User.RequireUniqueEmail = true;
        });



        //// If you want to tweak Identity cookies, they're no longer part of IdentityOptions.
        //services.ConfigureApplicationCookie(options => options.LoginPath = "/Account/LogIn");
        //services.AddAuthentication();
        //// If you don't want the cookie to be automatically authenticated and assigned to HttpContext.User, 
        //// remove the CookieAuthenticationDefaults.AuthenticationScheme parameter passed to AddAuthentication.
        //services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        //    .AddCookie(options =>
        //    {
        //        options.LoginPath = "/Account/LogIn";
        //        options.LogoutPath = "/Account/LogOff";
        //    });
        //services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        //    .AddJwtBearer(jwtBearerOptions =>
        //    {
        //        //jwtBearerOptions.Events.OnChallenge = context =>
        //        //{
        //        //    context.Response.Headers["Location"] = context.Request.Path.Value;
        //        //    context.Response.StatusCode = 401;
        //        //    return Task.CompletedTask;
        //        //};
        //        jwtBearerOptions.TokenValidationParameters = new TokenValidationParameters
        //        {
        //            ValidateIssuerSigningKey = true,
        //            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your secret goes here")),

        //            ValidateIssuer = true,
        //            ValidIssuer = "The name of the issuer",

        //            ValidateAudience = true,
        //            ValidAudience = "The name of the audience",

        //            ValidateLifetime = true, //validate the expiration and not before values in the token

        //            ClockSkew = TimeSpan.FromMinutes(5) //5 minute tolerance for the expiration date
        //        };
        //    });

        // Enable Dual Authentication 
        services.AddAuthentication()
          .AddCookie(cfg => cfg.SlidingExpiration = true)
          .AddJwtBearer(cfg =>
          {
              cfg.RequireHttpsMetadata = false;
              cfg.SaveToken = true;

              cfg.TokenValidationParameters = new TokenValidationParameters()
              {
                  ValidIssuer = Configuration["Tokens:Issuer"],
                  ValidAudience = Configuration["Tokens:Issuer"],
                  IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"]))
              };

          });

        services.AddTransient<IModelsService, ModelsService>();
        services.AddTransient<IRestaurantService, RestaurantService>();
    }

и два основных вопроса:

1- Не работает! Я вызываю метод для генерации токена http://localhost:59699/api/accountapi/login, ответ примерно такой:

{"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJmb29kdGVzdGdldHVzckBnbWFpbC5jb20iLCJqdGkiOiIyZGQ0MDhkNy02NDE4LTQ2MGItYTUxYi1hNTYzN2Q0YWYyYzgiLCJpYXQiOiIxMC8xMi8yMDE3IDM6NDA6MDYgQU0iLCJuYmYiOjE1MDc3Nzk2MDYsImV4cCI6MTUwNzc3OTkwNiwiaXNzIjoiRXhhbXBsZUlzc3VlciIsImF1ZCI6IkV4YW1wbGVBdWRpZW5jZSJ9.of-kTEIG8bOoPfyCQjuP7s6Zm32yFFPlW_T61OT8Hqs","expires_in":300}

затем я вызываю защищенный ресурс следующим образом:

отправка конфигурации

но защищенный ресурс недоступен.

2- После неудачной аутентификации он перенаправляет запрос на страницу входа. Как я могу отключить это поведение автоматического вызова?

прежде чем вы начнете отвечать, я должен сказать, что я пробовал https://wildermuth.com/2017/08/19/Two-AuthorizationSchemes-in-ASP-NET-Core-2 для создания аутентификации и этого https://docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x тоже; а также этот ASP.NET Core 2.0 отключает автоматический вызов для отключить автоматический вызов, но ни один из них не сработал.

Обновлять

Желаемая конфигурация - использовать jwtbearerauthentication для вызовов webapi, а для остальных использовать cookie. Затем, используя первый, я хочу вернуть неавторизованный (401) ответ на неавторизованный запрос, а для более позднего я хочу перенаправление.


person ConductedClever    schedule 12.10.2017    source источник


Ответы (1)


Я вижу как минимум одну ошибку. Ваш заголовок авторизации должен быть "Bearer TOKEN", а не "bearer". Так что используйте Bearer с большой буквы.

Затем для перенаправления вызова API. Поместите атрибут Authorize со схемой JwtBearer в действия API:

[Route("api/method")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[HttpGet]
public IActionResult MyApiCall()
{
 .....
}
person Bogdan S    schedule 30.11.2017