You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

240 lines
9.6 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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<ContainerBuilder>(builder =>
{
builder.RegisterModule(new AutofacModuleRegister());
builder.RegisterModule<AutofacPropertityModuleReg>();
})
.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<KestrelServerOptions>(x => x.AllowSynchronousIO = true)
.Configure<IISServerOptions>(x => x.AllowSynchronousIO = true);
builder.Services.AddSession();
builder.Services.AddControllers(o =>
{
// 全局异常过滤
o.Filters.Add(typeof(GlobalExceptionsFilter));
o.Filters.Add<ApiUserFilter>(); // 添加用户信息过滤器
// 全局路由权限公约
//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<JsonSerializerSettings>(() =>
{
//日期类型默认格式化处理
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<IControllerActivator, ServiceBasedControllerActivator>());
//支持编码大全 例如:支持 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<ChatHub>("/api2/chatHub");
// 4、运行
app.Run();
}
}