Я пытаюсь использовать 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) ответ на неавторизованный запрос, а для более позднего я хочу перенаправление.