网页版推演服务器
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

279 lines
9.0 KiB

3 years ago
using AX.WebDrillServer.Data;
using AX.WebDrillServer.EntityMappers;
using AX.WebDrillServer.Errors;
using AX.WebDrillServer.Extensions;
using AX.WebDrillServer.Hubs;
using AX.WebDrillServer.Middlewares;
using AX.WebDrillServer.Middlewares.Jwts;
using AX.WebDrillServer.Services.FireDeductionHub;
3 years ago
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System.IdentityModel.Tokens.Jwt;
using System.Reflection;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
const string ProductName = "沙盘推演";
3 years ago
const string ProductVersion = "v1.0";
const string ApiVersion = "v1";
#region Banner
var banners = "Banners";
if (Directory.Exists(banners))
{
var files = Directory.GetFiles(banners);
var random = new Random();
var file = files[random.Next(0, files.Length)];
var banner = File.ReadAllText(file);
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Write(banner);
Console.WriteLine("\n\n");
}
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("按 CTRL+C 键退出程序...\n\n");
Console.ForegroundColor = ConsoleColor.White;
Console.Title = $"{ProductName} {ProductVersion}";
#endregion Banner
#region ServerLicense
if (!ServerLicense.Initialize())
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(GlobalErrorCodes.Messages[GlobalErrorCodes.E600]);
Console.WriteLine("\n\n");
}
#endregion ServerLicense
var builder = WebApplication.CreateBuilder(args);
#region Identities
builder.Services.Configure<JwtOptions>(builder.Configuration.GetSection("JwtSettings"));
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
var secret = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["JwtSettings:Secret"]));
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = JwtClaimTypes.Name,
RoleClaimType = JwtClaimTypes.Role,
ValidateIssuer = true,
ValidIssuer = builder.Configuration["JwtSettings:Issuer"],
ValidateIssuerSigningKey = true,
IssuerSigningKey = secret,
ValidateAudience = true,
ValidAudience = builder.Configuration["JwtSettings:Audience"],
RequireExpirationTime = true,
ValidateLifetime = true,
ClockSkew = TimeSpan.FromSeconds(30)
};
// SignalR Jwt
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
var path = context.HttpContext.Request.Path;
if (accessToken.HasValue() &&
path.StartsWithSegments("/hubs"))
context.Token = accessToken;
return Task.CompletedTask;
}
};
});
builder.Services.AddSingleton<IJwtService, JwtService>();
builder.Services.AddSingleton<IUserIdProvider, NameUserIdProvider>();
builder.Services.AddAuthorization();
#endregion Identities
// Email Service
//builder.Services.AddSingleton<IEmailService, EmailService>();
builder.Services.AddSingleton<RoomManager>();
3 years ago
builder.Services.AddMemoryCache();
builder.Services
.AddSignalR(options =>
{
#if !RELEASE
options.EnableDetailedErrors = true;
#endif
})
.AddJsonProtocol(options =>
{
options.PayloadSerializerOptions.PropertyNameCaseInsensitive = true;
options.PayloadSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
options.PayloadSerializerOptions.DictionaryKeyPolicy = JsonNamingPolicy.CamelCase;
//全局配置signalr json 转枚举使用stringName还是intValue
options.PayloadSerializerOptions.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase));
3 years ago
});
//#region Custom Services
//builder.Services.AddTransient<INotificationService, NotificationService>();
//#endregion Custom Services
builder.Services
.AddControllers(options =>
{
options.InputFormatters.Insert(0, new RawJsonInputFormatter());
options.OutputFormatters.Insert(0, new RawJsonOutputFormatter());
//options.Filters.Add(new AuthorizeFilter());
})
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
options.JsonSerializerOptions.DictionaryKeyPolicy = JsonNamingPolicy.CamelCase;
//全局配置Controller json 转枚举使用stringName还是intValue
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase));
3 years ago
});
builder.Services.AddEndpointsApiExplorer();
#region Swagger
if (builder.Environment.IsDevelopment() || builder.Environment.IsStaging())
{
builder.Services.AddSwaggerGen(options =>
{
options.CustomSchemaIds(type => type.ToString());
options.SwaggerDoc(ApiVersion, new OpenApiInfo { Title = $"{ProductName} API", Version = ApiVersion });
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
options.IncludeXmlComments(xmlPath, true);
options.IgnoreObsoleteActions();
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Description = "使用 JWT Bearer 模式进行授权。示例: \"Bearer {token}\"",
Name = "Authorization", //Jwt default param name
In = ParameterLocation.Header, //Jwt store address
Type = SecuritySchemeType.ApiKey, //Security scheme type
Scheme = "Bearer",
BearerFormat = "JWT"
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
},
},
Array.Empty<string>()
}
});
// File Filter
options.OperationFilter<FileUploadOperationFilter>();
});
}
#endregion Swagger
#region Database Context
builder.Services.AddDbContextPool<ApplicationDbContext>((provider, options) =>
{
if (builder.Environment.IsDevelopment() || builder.Environment.IsStaging())
options.EnableSensitiveDataLogging();
options.UseNpgsql(builder.Configuration.GetConnectionString("PostgreSQL"),
// 全局启用拆分查询, 详见: https://docs.microsoft.com/zh-cn/ef/core/querying/single-split-queries;
opts => opts.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery));
});
#endregion Database Context
#region Mapper
EntityMapperConfig.Initialize();
#endregion Mapper
var app = builder.Build();
#region Setup Database
app.SetupDatabase();
#endregion Setup Database
#region Development
if (app.Environment.IsDevelopment() || app.Environment.IsStaging())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint($"/swagger/{ApiVersion}/swagger.json", $"{ProductName} API {ApiVersion}");
options.EnablePersistAuthorization();
});
app.UseReDoc(options =>
{
options.RoutePrefix = "docs";
options.DocumentTitle = $"{ProductName} API {ApiVersion}";
options.SpecUrl($"/swagger/{ApiVersion}/swagger.json");
options.EnableUntrustedSpec();
options.ScrollYOffset(10);
options.HideHostname();
options.HideDownloadButton();
options.ExpandResponses("200,201");
options.RequiredPropsFirst();
//c.NoAutoAuth();
//c.PathInMiddlePanel();
//c.HideLoading();
//c.NativeScrollbars();
//c.DisableSearch();
//c.OnlyRequiredInSamples();
//c.SortPropsAlphabetically();
});
app.UseHttpLogging();
}
#endregion Development
//app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
//app.MapHub<NotificationHub>("/hubs/notification");
//app.MapHub<TaskChatHub>("/hubs/taskchat");
app.MapHub<FireDeductionHub>("/hubs/FireDeductionHub");
3 years ago
app.Run();