ASP Core 2.0 JwtBearerAuthentication无法正常工作

时间:2017-10-12 03:55:07

标签: authentication jwt asp.net-core-2.0 challenge-response

我正在尝试在Asp core 2.0中使用JwtBearerAuthentication,但我遇到了两个主要问题。

启动的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" });
        });
    }

和下面的配置服务:

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}

然后我用这种方式调用受保护的资源:

sending config

但无法访问受保护资源。

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 disable automatic challenge来禁用自动挑战,但是没有它们起作用。

更新

所需的配置是在webapi调用上使用jwtbearerauthentication,而其他人使用cookie。然后在使用前者时,我希望在未授权的请求中返回未授权的(401)响应,而对于后者我想要重定向。

1 个答案:

答案 0 :(得分:2)

我发现至少有一个错误。您的授权标题应为“Bearer TOKEN”,而不是“bearer”。所以资本化持票人。

然后重定向api调用。将Authorize属性与JwtBearer架构放在api操作上:

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