using System.Text; using DataSharing.Repository; using DataSharing.SendTask; using Mapster; using MapsterMapper; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; using Quartz; using Quartz.AspNetCore; using XF.Domain.Entities; using XF.Domain.Exceptions; using XF.Domain.Options; using XF.Domain.Repository; namespace DataSharing.Host { public static class StartupHelper { /// /// Authentication /// /// /// /// public static IServiceCollection RegisterAuthentication(this IServiceCollection services, ConfigurationManager configuration) { //JwtSecurityTokenHandler.DefaultMapInboundClaims = false; //services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) // .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, d => // { // d.Authority = identityConfigs.IdentityUrl; // d.RequireHttpsMetadata = false; // d.TokenValidationParameters = new TokenValidationParameters // { // ValidateAudience = false // }; // //d.Audience = "hotline_api"; // d.Events = new JwtBearerEvents // { // OnMessageReceived = context => // { // var accessToken = context.Request.Query["access_token"]; // // If the request is for our hub... // var path = context.HttpContext.Request.Path; // if (!string.IsNullOrEmpty(accessToken) && // (path.StartsWithSegments("/hubs/callcenter"))) // { // // Read the token out of the query string // context.Token = accessToken; // } // return Task.CompletedTask; // } // }; // }); services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(d => { var jwtOptions = configuration.GetSection("IdentityConfiguration").Get().Jwt; byte[] bytes = Encoding.UTF8.GetBytes(jwtOptions.SecretKey); var secKey = new SymmetricSecurityKey(bytes); d.TokenValidationParameters = new() { ValidateIssuer = false, ValidateAudience = false, ValidateLifetime = true, ValidateIssuerSigningKey = true, IssuerSigningKey = secKey, }; //d.Audience = "hotline_api"; d.Events = new JwtBearerEvents { OnMessageReceived = context => { var accessToken = context.Request.Query["access_token"]; // If the request is for our hub... var path = context.HttpContext.Request.Path; if (!string.IsNullOrEmpty(accessToken) && (path.StartsWithSegments("/hubs/hotline"))) { // Read the token out of the query string context.Token = accessToken; } return Task.CompletedTask; } }; }) ; return services; } /// /// Swagger /// /// /// public static IServiceCollection RegisterSwagger(this IServiceCollection services) { services.AddSwaggerGen(c => { //添加文档 c.SwaggerDoc("v1", new OpenApiInfo() { Title = "Hotline Api", Version = "v1.0", Description = "城市热线api" }); var files = Directory.GetFiles(AppContext.BaseDirectory).Where(d => d.EndsWith(".xml")); foreach (var file in files) { c.IncludeXmlComments(file, true); } var scheme = new OpenApiSecurityScheme() { Description = "Authorization header. \r\nExample: 'Bearer ***'", Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Authorization" }, Scheme = "oauth2", Name = "Authorization", In = ParameterLocation.Header, Type = SecuritySchemeType.ApiKey, }; c.AddSecurityDefinition("Authorization", scheme); var requirement = new OpenApiSecurityRequirement(); requirement[scheme] = new List(); c.AddSecurityRequirement(requirement); }); return services; } /// /// Cors /// /// /// /// /// public static IServiceCollection RegisterCors(this IServiceCollection services, ConfigurationManager configuration, string corsOrigins) { services.AddCors(options => { options.AddPolicy(name: corsOrigins, builder => { var origins = configuration.GetSection("Cors:Origins").Get(); builder.SetIsOriginAllowed(a => { return origins.Any(origin => origin.StartsWith("*.", StringComparison.Ordinal) ? a.EndsWith(origin[1..], StringComparison.Ordinal) : a.Equals(origin, StringComparison.Ordinal)); }) .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); }); }); return services; } /// /// Mapper /// /// /// public static IServiceCollection RegisterMapper(this IServiceCollection services) { var config = TypeAdapterConfig.GlobalSettings; config.ForDestinationType() .Ignore(d => d.CreatorId) .Ignore(d => d.CreatorOrgId) //.Ignore(d => d.CreatorOrgCode) .Ignore(d => d.AreaId); config.ForDestinationType() .Ignore(d => d.ExpiredTimeConfigId); config.ForDestinationType() .Ignore(d => d.CreationTime); config.ForDestinationType().Ignore(d => d.DeletionTime); config.ForDestinationType().Ignore(d => d.IsDeleted); config.ForDestinationType().Ignore(d => d.LastModificationTime); config.ForDestinationType().Ignore(d => d.Id); services.AddSingleton(config); services.AddScoped(); return services; } /// /// SignalR /// /// /// /// public static IServiceCollection RegisterSignalR(this IServiceCollection services, ConfigurationManager configuration) { var connectionString = configuration.GetConnectionString("Redis"); if (string.IsNullOrEmpty(connectionString)) throw new UserFriendlyException("未配置signalR的redis连接"); services.AddSignalR().AddStackExchangeRedis(connectionString, options => { options.Configuration.ChannelPrefix = "Hotline:signalr:"; }); return services; } public static IServiceCollection RegisterRepository(this IServiceCollection services) { services.AddScoped(typeof(IRepository<>), typeof(BaseRepository<>)); return services; } public static IServiceCollection RegisterJob(this IServiceCollection services) { services.AddQuartz(d => { d.SchedulerId = "scheduler1"; d.InterruptJobsOnShutdown = true; d.InterruptJobsOnShutdownWithWait = true; d.MaxBatchSize = 3; //load send task var taskLoadJobKey = new JobKey("task-load-job", "load task"); d.AddJob(taskLoadJobKey); d.AddTrigger(t => t .WithIdentity("task-load-trigger") .ForJob(taskLoadJobKey) .StartNow() .WithCronSchedule("0 0/1 * * * ? ") ); //execute send task var taskExecuteJobKey = new JobKey("task-execute-job", "send task"); d.AddJob(taskExecuteJobKey); d.AddTrigger(t => t .WithIdentity("task-execute-trigger") .ForJob(taskExecuteJobKey) .StartNow() .WithCronSchedule("0/1 * * * * ? ") ); }); services.AddQuartzServer(d => { d.WaitForJobsToComplete = true; d.StartDelay = TimeSpan.FromSeconds(5); }); return services; } } }