消防培训系统服务器
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.

251 lines
9.2 KiB

//using AX.CloudDrive.Hubs;
using AX.FireTrainingSys.Middlewares;
using AX.FireTrainingSys.Services;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http.Connections;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.IdentityModel.Tokens;
using Microsoft.IO;
using Microsoft.OpenApi.Models;
using Minio.AspNetCore;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.IO;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace AX.FireTrainingSys
{
public class Startup
{
private const string SandboxHub = "/hubs/sandbox";
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
#region JWT 相关
services.Configure<JwtOptions>(Configuration.GetSection("JWT"));
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services
.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
var secret = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JWT:Secret"]));
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = JwtClaimTypes.Name,
RoleClaimType = JwtClaimTypes.Role,
ValidateIssuer = true,
ValidIssuer = Configuration["JWT:Issuer"],
ValidateAudience = true,
ValidAudience = Configuration["JWT:Audience"],
ValidateIssuerSigningKey = true,
IssuerSigningKey = secret,
RequireExpirationTime = true,
ValidateLifetime = true,
ClockSkew = TimeSpan.FromSeconds(30),
};
//支持 SignalR 非常规认证
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
// 校验 Hub 路径
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) &&
path.StartsWithSegments(SandboxHub))
context.Token = accessToken;
return Task.CompletedTask;
}
};
});
#endregion
services.Configure<KestrelServerOptions>(options =>
{
options.AllowSynchronousIO = true;
});
services.AddControllers(options =>
{
options.InputFormatters.Insert(0, new RawJsonInputFormatter());
options.OutputFormatters.Insert(0, new RawJsonOutputFormatter());
});
services.AddMemoryCache();
services.AddDbContextPool<DriveDbContext>(options =>
{
var connectionString = Configuration.GetConnectionString("SQLite");
options.UseSqlite(connectionString);
});
#if DEBUG
services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo { Title = $"{Program.ProductName} API", Version = "v1" });
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
options.IncludeXmlComments(xmlPath);
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"
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference{Type = ReferenceType.SecurityScheme, Id = "Bearer"},
},
new string[] { }
}
});
});
#endif
services.AddApiVersioning(options =>
{
options.DefaultApiVersion = new ApiVersion(1, 0);
options.ReportApiVersions = true;
options.AssumeDefaultVersionWhenUnspecified = true;
});
services.AddSignalR(hubOptions =>
{
var ping = int.Parse(Configuration["SignalR:KeepAliveInterval"]);
var maxSize = long.Parse(Configuration["SignalR:MaximumReceiveMessageSize"]);
hubOptions.KeepAliveInterval = TimeSpan.FromSeconds(ping);
hubOptions.ClientTimeoutInterval = TimeSpan.FromSeconds(ping * 2);
hubOptions.MaximumReceiveMessageSize = maxSize == 0 ? null : maxSize;
hubOptions.MaximumParallelInvocationsPerClient = 500;
#if DEBUG
hubOptions.EnableDetailedErrors = true;
#endif
})
.AddJsonProtocol(options =>
{
options.PayloadSerializerOptions.PropertyNameCaseInsensitive = true;
options.PayloadSerializerOptions.IncludeFields = true;
});
services.AddGroupManager();
services.AddMinio(options =>
{
var section = Configuration.GetSection("Minio");
options.Endpoint = section.GetValue<string>("EndPoint");
options.AccessKey = section.GetValue<string>("AccessKey");
options.SecretKey = section.GetValue<string>("SecretKey");
options.Region = section.GetValue<string>("Region");
var enableHttps = section.GetValue<bool>("EnableHttps");
options.OnClientConfiguration = client =>
{
if (enableHttps)
client.WithSSL();
};
});
services.TryAddSingleton<IJwtService, JwtService>();
services.AddSingleton<IUserIdProvider, SubjectUserIdProvider>();
services.AddSingleton<RecyclableMemoryStreamManager>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseLicence();
#if DEBUG
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", $"{Program.ProductName} API v1");
});
app.UseReDoc(c =>
{
c.RoutePrefix = "docs";
c.DocumentTitle = $"{Program.ProductName} API v1";
c.SpecUrl("/swagger/v1/swagger.json");
c.EnableUntrustedSpec();
c.ScrollYOffset(10);
c.HideHostname();
c.HideDownloadButton();
c.ExpandResponses("200,201");
c.RequiredPropsFirst();
//c.NoAutoAuth();
//c.PathInMiddlePanel();
//c.HideLoading();
//c.NativeScrollbars();
//c.DisableSearch();
//c.OnlyRequiredInSamples();
//c.SortPropsAlphabetically();
});
#endif
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
//endpoints.MapHub<SandboxHub>(SandboxHub, options =>
//{
// options.Transports = HttpTransportType.WebSockets;
// options.ApplicationMaxBufferSize = 0;
// options.TransportMaxBufferSize = 0;
//});
});
}
}
}