using System.Collections.Generic; using System.Text; using CleanArchitecture.Application.Extensions; using CleanArchitecture.Domain.Extensions; using CleanArchitecture.Domain.Settings; using CleanArchitecture.gRPC; using CleanArchitecture.Infrastructure.Database; using CleanArchitecture.Infrastructure.Extensions; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); builder.Services.AddGrpc(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(c => { c.EnableAnnotations(); c.SwaggerDoc("v1", new OpenApiInfo { Title = "CleanArchitecture", Version = "v1", Description = "A clean architecture API" }); c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { Description = "JWT Authorization header using the Bearer scheme. " + "Use the /api/v1/user/login endpoint to generate a token", Name = "Authorization", In = ParameterLocation.Header, Type = SecuritySchemeType.Http, Scheme = "bearer" }); c.AddSecurityRequirement(new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" }, Scheme = "oauth2", Name = "Bearer", In = ParameterLocation.Header }, new List() } }); }); builder.Services.AddHealthChecks(); builder.Services.AddHttpContextAccessor(); builder.Services.AddDbContext(options => { options.UseLazyLoadingProxies(); options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"), b => b.MigrationsAssembly("CleanArchitecture.Infrastructure")); }); builder.Services.AddAuthentication( options => { options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer( jwtOptions => { jwtOptions.TokenValidationParameters = CreateTokenValidationParameters(); }); builder.Services.AddInfrastructure(); builder.Services.AddQueryHandlers(); builder.Services.AddServices(); builder.Services.AddCommandHandlers(); builder.Services.AddNotificationHandlers(); builder.Services.AddApiUser(); builder.Services .AddOptions() .Bind(builder.Configuration.GetSection("Auth")) .ValidateOnStart(); builder.Services.AddMediatR(cfg => { cfg.RegisterServicesFromAssemblies(typeof(Program).Assembly); }); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.MapHealthChecks("/health"); app.MapGrpcService(); using (var scope = app.Services.CreateScope()) { var services = scope.ServiceProvider; var appDbContext = services.GetRequiredService(); appDbContext.EnsureMigrationsApplied(); } app.Run(); TokenValidationParameters CreateTokenValidationParameters() { var result = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = builder.Configuration["Auth:Issuer"], ValidAudience = builder.Configuration["Auth:Audience"], IssuerSigningKey = new SymmetricSecurityKey( Encoding.UTF8.GetBytes( builder.Configuration["Auth:Secret"]!)), RequireSignedTokens = false }; return result; } // Needed for integration tests webapplication factory public partial class Program { }