using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption; using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using Microsoft.OpenApi.Models; using OAuthServer; var builder = WebApplication.CreateBuilder(args); // Add logging to console builder.Logging.AddConsole(); // Add services to the container. builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(options => { // Create a authentication schema for JWT tokens options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"", Name = "Authorization", In = ParameterLocation.Header, Type = SecuritySchemeType.Http, Scheme = "bearer", Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } }); }); builder.Services.AddDbContext(options => { options.UseSqlite("DataSource=db.sqlite3"); }); builder.Services.AddIdentity(options => { options.Stores.MaxLengthForKeys = 128; }) .AddEntityFrameworkStores() .AddDefaultTokenProviders(); builder.Services.AddAuthentication().AddJwtBearer("OAuthToken", options => { // options.RequireHttpsMetadata = false; // options.SaveToken = true; // options.TokenValidationParameters = new TokenValidationParameters() // { // ValidateIssuer = true, // ValidateAudience = true, // RequireSignedTokens = true, // ValidIssuer = builder.Configuration["Jwt:Issuer"], // ValidAudience = builder.Configuration["Jwt:Audience"], // IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Environment.GetEnvironmentVariable("JWT_KEY"))) // }; }); builder.Services.Configure(options => { // SignIn settings. options.SignIn.RequireConfirmedAccount = false; options.SignIn.RequireConfirmedEmail = false; options.SignIn.RequireConfirmedPhoneNumber = false; // Lockout settings. options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5); options.Lockout.MaxFailedAccessAttempts = 5; options.Lockout.AllowedForNewUsers = true; // Password settings. options.Password.RequireDigit = false; options.Password.RequireLowercase = false; options.Password.RequireNonAlphanumeric = false; options.Password.RequireUppercase = false; options.Password.RequiredLength = 1; options.Password.RequiredUniqueChars = 1; }); builder.Services.ConfigureApplicationCookie(options => { // Cookie options options.Cookie.Name = "AuthCookie"; options.Cookie.HttpOnly = true; options.ExpireTimeSpan = TimeSpan.FromHours(24); options.SlidingExpiration = true; options.LoginPath = "/login"; options.LogoutPath = "/logout"; }); // Force Identity's security stamp to be validated every minute. builder.Services.Configure(options => { options.ValidationInterval = TimeSpan.FromMinutes(10); }); // Set a more secure password hashing iteration count builder.Services.Configure(option => { option.IterationCount = 100_000; }); builder.Services.AddDataProtection().UseCryptographicAlgorithms(new AuthenticatedEncryptorConfiguration() { EncryptionAlgorithm = EncryptionAlgorithm.AES_256_CBC, ValidationAlgorithm = ValidationAlgorithm.HMACSHA256 }); // Add policy-based authorization builder.Services.AddAuthorization(options => { // Require either role to authenticate as Contestant options.AddPolicy("User", policy => policy .RequireRole("User") .AddAuthenticationSchemes(IdentityConstants.ApplicationScheme) ); // Require the External role to authenticate with a different authentication method options.AddPolicy("External", policy => policy .RequireRole("External") .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme) ); }); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.MapControllers(); // Automatically apply migrations to database on startup var scopeFactory = app.Services.GetRequiredService(); using (var scope = scopeFactory.CreateScope()) { using (var databaseContext = scope.ServiceProvider.GetRequiredService()) { // Migrate the database databaseContext.Database.Migrate(); } } app.Run();