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
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; |
|
//}); |
|
}); |
|
} |
|
} |
|
}
|
|
|