Аутентификация JWT .Атрибут Net core [Авторизация] Игнорируется контроллером

#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()
//...