using Microsoft.AspNetCore.HttpOverrides; using Microsoft.EntityFrameworkCore; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using System.Text; using agologumApi.Models; using agologumApi.Services; var builder = WebApplication.CreateBuilder(args); var key = builder.Configuration["Jwt:Key"]; if(key == null) return; builder.Services.AddDbContext(options => options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection"))); builder.Services.AddControllers(); // services builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); // configuration for jwt authentication builder.Services.AddIdentity() .AddEntityFrameworkStores() .AddDefaultTokenProviders() .AddRoles(); builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = "agologum", ValidAudience = "agologum", IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key)), ClockSkew = TimeSpan.Zero }; }); builder.Services.AddAuthorization(options => { options.AddPolicy("RequireAdmin", policy => { policy.RequireRole("Admin", "Superuser"); }); options.AddPolicy("RequireSuperuser", policy => { policy.RequireRole("Superuser"); }); }); // configuration for behind my nginx proxy builder.Services.Configure(options => { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; options.KnownIPNetworks.Clear(); options.KnownProxies.Clear(); }); // Add services to the container. // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi builder.Services.AddOpenApi(); builder.Services.AddCors(options => { options.AddPolicy("dev", policy => { policy.AllowAnyOrigin() .AllowAnyHeader() .AllowAnyMethod(); }); }); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); // https://www.reddit.com/r/dotnet/comments/1h7vzbs/how_do_you_guys_handle_authorization_on_a_web_api/ // add authorization here // controllers will have endpoints based on authorization // frontend is a different story var app = builder.Build(); app.UseForwardedHeaders(); app.UseCors("dev"); app.UseAuthentication(); app.UseAuthorization(); // Configure the HTTP request pipeline. if (app.Environment.IsEnvironment("Development")) { app.MapOpenApi(); app.UseSwagger(); app.UseSwaggerUI(); } else { app.UseHttpsRedirection(); } app.MapControllers(); // attempt enitity-framework migrations at startup. love you stack overflow using (var scope = app.Services.CreateScope()) { var db = scope.ServiceProvider.GetRequiredService(); var retries = 10; while (retries-- > 0) { try { db.Database.Migrate(); break; } catch { Thread.Sleep(5000); } } } app.Run();