#c# #asp.net-core #.net-core #jwt #asp.net-core-webapi
Вопрос:
Я пытаюсь реализовать аутентификацию на основе JWT в своем приложении, которое имеет интерфейс Angular 8 и серверную часть .Net Core. Я добавил
app.UseAuthentication();
app.UseAuthorization();
и
services.AddAuthentication(opt =>
в классе запуска.Я оформил метод контроллера с помощью [Authorize]
атрибута. Но когда я пытаюсь попасть в метод контроллера без каких-либо маркеров, он позволяет войти в метод контроллера.
запуск
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
var jwtSettings = Configuration.GetSection("JwtSettings");
services.AddAuthentication(opt =>
{
opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = jwtSettings.GetSection("validIssuer").Value,
ValidAudience = jwtSettings.GetSection("validAudience").Value,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.GetSection("securityKey").Value))
};
});
services.AddSignalR();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
// requires using Microsoft.Extensions.Options
services.Configure<DatabaseSettings>(
Configuration.GetSection(nameof(DatabaseSettings)));
services.AddSingleton<IDatabaseSettings>(sp =>
sp.GetRequiredService<IOptions<DatabaseSettings>>().Value);
services.AddSingleton<FileService>();
services.AddSingleton<InternalReportService>();
services.AddTransient<MailService>();
services.AddMvc(option => option.EnableEndpointRouting = false);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseRouting();
app.UseMvc();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<CoreHub>("/corehub");
endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}");
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseProxyToSpaDevelopmentServer("http://localhost:4200");
}
});
}
}
Контроллер
[Authorize]
public async Task UploadFile(IFormFile file)
{
// Do Stuff
}
Комментарии:
1. попробуйте воспользоваться этими услугами. Добавьте функцию AddMvcCore() вместо служб. AddMvc()
2. Вы не предоставили общий доступ к коду, который создает JWT или сохраняет токен.
3.
https://code-maze.com/authentication-aspnetcore-jwt-1/
Ответ №1:
Что ж, вы настроили часть аутентификации своего API, теперь вам нужно настроить авторизацию таким же образом…
Вы можете настроить следующим образом:
services.AddAuthorization(options =>
{
options.AddPolicy("Default", new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser()
.Build());
options.AddPolicy("Admin", new AuthorizationPolicyBuilder()
.RequireRole("Admin")
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser()
.Build());
});
Тогда вы сможете использовать атрибут как
[Authorize("User")]
[Authorize("Admin")]
на ваших контроллерах или определенных конечных точках.
Если вы хотите применить эту политику по умолчанию ко всем своим конечным точкам/контроллерам и управлять только частью if «AllowAnonymous», вы можете сделать это:
services.AddMvc()
.AddMvcOptions(options =>
{
// Mark all endpoints with the default policy
options.Filters.Add(new AuthorizeFilter("Default"));
})
Комментарии:
1. Должен быть правильный ответ.
2. Почему обязательно определять роли? Моему приложению нужен только действительный токен для работы,нет необходимости в ролях.
3. Вам не нужна роль, просто определите политику по умолчанию без имени, как уже показал @
opts.DefaultPolicy = new AuthorizationPolicyBuilder(opts.DefaultPolicy).RequireAuthenticatedUser()
GibbOne , на самом деле вы можете использовать и то, и другое, если хотите, то же самое применяется к глобальному фильтру4. На самом деле политика по умолчанию статична, просто вызов
services.AddAuthorization()
должен работать, я думаю, иначе вам придется ее настраивать
Ответ №2:
В соответствии с Вашей схемой аутентификации Вы должны указать атрибут следующим образом: [Authorize(AuthenticationSchemes = "Bearer")]
и это должно работать так, как Вы ожидаете
Комментарии:
1. Спасибо… но это не работает.
2. @techno можете ли вы предоставить полный код вашего контроллера?
3. Проблема решена. Я выбрал неправильный метод.
4. @techno Вы имеете в виду, что некоторые ответы были правильными? Или Ты имеешь в виду, что весь этот вопрос был не о проблеме?
5. Добавление предъявителя фактически устранило проблему. Но настоящая проблема заключалась в другом.
Ответ №3:
Я обычно добавляю DefaultSchema
.
services.AddAuthentication(opt =>
{
opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
opt.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
//...
и разрешение.
services.AddAuthorization(opts =>
{
opts.DefaultPolicy = new AuthorizationPolicyBuilder(opts.DefaultPolicy)
.RequireAuthenticatedUser()
//...