Estoy tratando de implementar la autenticación basada en JWT en mi aplicación que tiene un frontend angular 8 y un backend .Net Core. Yo he añadido
app.UseAuthentication(); app.UseAuthorization();y
services.AddAuthentication(opt => en la clase de inicio. He decorado el método del controlador usando el atributo [Authorize] . Pero cuando trato de presionar el método del controlador sin ningún token, permite la entrada al método del controlador.
Puesta en marcha
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"); } }); } }Controlador
[Authorize] public async Task UploadFile(IFormFile file) { // Do Stuff }De acuerdo con su esquema de autenticación, debe especificar el atributo de esta manera: [Authorize(AuthenticationSchemes = "Bearer")] y esto debería funcionar como espera
Bueno, ha configurado la parte de autenticación de su API, ahora necesita configurar la autorización de la misma manera...
Puedes configurar así:
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()); });Entonces podrá usar el atributo como
[Authorize("User")] [Authorize("Admin")]en sus controladores o puntos finales específicos.
Si desea poner esta política predeterminada en todos sus puntos finales/controladores y controlar solo la parte "AllowAnonymous" de if, puede hacer esto:
services.AddMvc() .AddMvcOptions(options => { // Mark all endpoints with the default policy options.Filters.Add(new AuthorizeFilter("Default")); })Normalmente agrego DefaultSchema .
services.AddAuthentication(opt => { opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; opt.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; //...y autorización.
services.AddAuthorization(opts => { opts.DefaultPolicy = new AuthorizationPolicyBuilder(opts.DefaultPolicy) .RequireAuthenticatedUser() //...