using Autofac; using Autofac.Extensions.DependencyInjection; using EntrustSettle; using EntrustSettle.Common; using EntrustSettle.Common.Core; using EntrustSettle.Common.LogHelper; using EntrustSettle.Extensions; using EntrustSettle.Extensions.Middlewares; using EntrustSettle.Extensions.ServiceExtensions; using EntrustSettle.Filter; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.IdentityModel.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using NLog.Web; using System.IdentityModel.Tokens.Jwt; using System.Reflection; using System.Text; using Yitter.IdGenerator; internal class Program { private static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); // 1、配置host与容器 builder.Host .UseServiceProviderFactory(new AutofacServiceProviderFactory()) .ConfigureContainer(builder => { builder.RegisterModule(new AutofacModuleRegister()); builder.RegisterModule(); }) .ConfigureAppConfiguration((hostingContext, config) => { hostingContext.Configuration.ConfigureApplication(); config.Sources.Clear(); config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); if (hostingContext.HostingEnvironment.IsProduction()) { config.AddJsonFile("appsettings.production.json", optional: true, reloadOnChange: true); } }).ConfigureLogging(logging => { logging.ClearProviders(); //logging.AddConsole(); //表示程序启动后在弹出的黑框里记录日志 logging.AddDebug(); //表示程序启动后在VS中输出中显示日志 }) .UseNLog(); builder.ConfigureApplication(); // 2、配置服务 builder.Services.AddSingleton(new AppSettings(builder.Configuration)); builder.Services.AddSingleton(new LogLock(AppContext.BaseDirectory)); builder.Services.AddAllOptionRegister(); // 设置雪花id的workerId,确保每个实例workerId都应不同 var workerId = ushort.Parse(AppSettings.app(["Startup", "WorkerId"])); YitIdHelper.SetIdGenerator(new IdGeneratorOptions { WorkerId = workerId }); Permissions.IsUseIds4 = AppSettings.app(["Startup", "IdentityServer4", "Enabled"]).ObjToBool(); RoutePrefix.Name = AppSettings.app(["AppSettings", "RoutePrefix"]).ObjToString(); /* 清除默认的声明映射关系,使得JWT中的声明名称原封不动地传递到应用程序中,而不进行任何转换。这样,你就可以按照自己的需求来处理JWT中的声明了。*/ JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); builder.Services.AddCacheSetup(); builder.Services.AddSqlsugarSetup(); builder.Services.AddDbSetup(); builder.Services.AddInitializationHostServiceSetup(); builder.Services.AddMapsterSetup(); builder.Services.AddCorsSetup(); builder.Services.AddJobSetup(); if (builder.Environment.IsDevelopment()) { builder.Services.AddSwaggerSetup(); } builder.Services.AddHttpContextSetup(); builder.Services.AddAppTableConfigSetup(builder.Environment); builder.Services.AddHttpClientSetup(); builder.Services.AddRedisInitMqSetup(); builder.Services.AddIpPolicyRateLimitSetup(builder.Configuration); builder.Services.AddSignalR().AddNewtonsoftJsonProtocol(); builder.Services.AddAuthorizationSetup(); if (Permissions.IsUseIds4) { // 使用 Ids4权限 认证服务 builder.Services.AddAuthentication_Ids4Setup(); } else { // 使用 JWT权限 认证服务 builder.Services.AddAuthentication_JWTSetup(); } builder.Services.Configure(x => x.AllowSynchronousIO = true) .Configure(x => x.AllowSynchronousIO = true); builder.Services.AddSession(); builder.Services.AddControllers(o => { // 全局异常过滤 o.Filters.Add(typeof(GlobalExceptionsFilter)); o.Filters.Add(); // 添加用户信息过滤器 // 全局路由权限公约 //o.Conventions.Insert(0, new GlobalRouteAuthorizeConvention()); // 全局路由前缀,统一修改路由 o.Conventions.Insert(0, new GlobalRoutePrefixFilter(new RouteAttribute(RoutePrefix.Name))); }) //MVC全局配置Json序列化处理 .AddNewtonsoftJson(options => { //忽略循环引用 options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; //不使用驼峰样式的key options.SerializerSettings.ContractResolver = new DefaultContractResolver(); //设置时间格式 options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; //options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; //设置本地时间而非UTC时间 options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local; //添加Enum转string //options.SerializerSettings.Converters.Add(new StringEnumConverter()); //将long类型转为string //options.SerializerSettings.Converters.Add(new NumberConverter(NumberConverterShip.Int64)); }); JsonSerializerSettings setting = new JsonSerializerSettings(); JsonConvert.DefaultSettings = new Func(() => { //日期类型默认格式化处理 setting.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat; setting.DateFormatString = "yyyy-MM-dd HH:mm:ss"; //空值处理 //setting.NullValueHandling = NullValueHandling.Ignore; return setting; }); //builder.Services.AddRabbitMQSetup(); 未采用注入的方式,而是直接在需要的地方new builder.Services.AddKafkaSetup(builder.Configuration); builder.Services.AddEventBusSetup(); // 替换控制器激活器 builder.Services.Replace(ServiceDescriptor.Transient()); //支持编码大全 例如:支持 System.Text.Encoding.GetEncoding("GB2312") System.Text.Encoding.GetEncoding("GB18030") Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); // 3、配置中间件 var app = builder.Build(); IdentityModelEventSource.ShowPII = true; // 显示身份验证错误详细信息 app.ConfigureApplication(); app.UseApplicationSetup(); app.UseResponseBodyRead(); if (app.Environment.IsDevelopment()) { // 在开发环境中,使用异常页面,这样可以暴露错误堆栈信息,所以不要放在生产环境。 app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); // 在非开发环境中,使用HTTP严格安全传输(or HSTS) 对于保护web安全是非常重要的。 // 强制实施 HTTPS 在 ASP.NET Core,配合 app.UseHttpsRedirection //app.UseHsts(); } app.UseEncryptionRequest(); app.UseEncryptionResponse(); app.UseExceptionHandlerMiddle(); // 异常处理 app.UseIpLimitMiddle(); // ip限流 app.UseRequestResponseLogMiddle(); // 请求响应日志 app.UseRecordAccessLogsMiddle(); // 记录访问日志 app.UseSignalRSendMiddle(); // SignalR发送消息 app.UseAllServicesMiddle(builder.Services); // 查看所有注入的服务 app.UseSession(); // Swagger // app.UseSwaggerAuthorized(); if (builder.Environment.IsDevelopment()) { app.UseSwaggerMiddle(() => Assembly.GetExecutingAssembly().GetManifestResourceStream("EntrustSettle.Api.swagger_index.html")); } // ↓↓↓↓↓↓ 注意下边这些中间件的顺序,很重要 ↓↓↓↓↓↓ // CORS跨域 app.UseCors(AppSettings.app(new string[] { "Startup", "Cors", "PolicyName" })); // 跳转https 可能顺序:UseRouting之后 //app.UseHttpsRedirection(); // 使用静态文件 DefaultFilesOptions defaultFilesOptions = new DefaultFilesOptions(); defaultFilesOptions.DefaultFileNames.Clear(); //defaultFilesOptions.DefaultFileNames.Add("swagger_index.html"); defaultFilesOptions.DefaultFileNames.Add("index.html"); app.UseDefaultFiles(defaultFilesOptions); app.UseStaticFiles(); app.UseCookiePolicy(); // 返回错误码 app.UseStatusCodePages(); app.UseRouting(); // 这种自定义授权中间件,可以尝试,但不推荐 // app.UseJwtTokenAuth(); app.UseAuthentication(); // 认证中间件 app.UseAuthorization(); // 授权中间件 // Ids4服务返回的token里只有用户id,没有Name、公司名称等信息,所以这里手动赋值一下 app.UseSetAppUserMiddleware(); app.MapControllers(); //app.MapHub("/api2/chatHub"); // 4、运行 app.Run(); } }