|
|
|
|
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));
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
builder.Services.AddRabbitMQSetup();
|
|
|
|
|
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.UseIpLogMiddle(); // IP记录
|
|
|
|
|
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();
|
|
|
|
|
|
|
|
|
|
// 测试用户,用来通过鉴权
|
|
|
|
|
//if (builder.Configuration.GetValue<bool>("AppSettings:UseLoadTest"))
|
|
|
|
|
//{
|
|
|
|
|
// app.UseMiddleware<ByPassAuthMiddleware>();
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app.UseAuthentication(); // 认证中间件
|
|
|
|
|
app.UseAuthorization(); // 授权中间件
|
|
|
|
|
|
|
|
|
|
// 大简云的ids4返回的token里只有用户id,没有Name、公司名称等信息,所以这里手动赋值一下
|
|
|
|
|
app.UseSetAppUserMiddleware();
|
|
|
|
|
|
|
|
|
|
app.MapControllers();
|
|
|
|
|
//app.MapHub<ChatHub>("/api2/chatHub");
|
|
|
|
|
|
|
|
|
|
// 4、运行
|
|
|
|
|
app.Run();
|
|
|
|
|
}
|
|
|
|
|
}
|