using System.IdentityModel.Tokens.Jwt; using System.Reflection; using Exceptionless; using FluentValidation; using FluentValidation.AspNetCore; using Hotline.Api.Filters; using Hotline.Api.Realtimes; using Hotline.Application; using Hotline.Application.Contracts; using Hotline.Application.Contracts.Configurations; using Hotline.CacheManager; using Hotline.CallCenter.Devices; using Hotline.NewRock; using Hotline.Permissions; using Hotline.Repository.SqlSugar; using Hotline.Settings; using Identity.Admin.HttpClient; using Mapster; using MapsterMapper; using MediatR; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authorization; using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; using Serilog; using XF.Domain.Dependency; namespace Hotline.Api; internal static class StartupExtensions { const string CorsOrigins = "CorsOrigins"; internal static WebApplication ConfigureServices(this WebApplicationBuilder builder) { var services = builder.Services; var configuration = builder.Configuration; services.AddHttpContextAccessor(); #if DEBUG builder.WebHost.UseUrls("http://192.168.100.36:50110", "http://localhost:50110"); #endif services.Configure(d => configuration.GetSection(nameof(DeviceConfigs)).Bind(d)); services.Configure(d => configuration.GetSection(nameof(WorkTimeSettings)).Bind(d)); // Add services to the container. services .BatchInjectServices() .AddApplication() ; var identityConfigs = configuration.GetSection(nameof(IdentityConfigs)).Get(); services.AddIdentityClient( d => { d.IdentityAddress = identityConfigs.IdentityUrl; d.IdentityApiAddress = identityConfigs.IdentityApiUrl; }, //new IdentityClientConfiguration(identityConfigs.IdentityUrl, identityConfigs.IdentityApiUrl), d => { d.ClientId = identityConfigs.ClientId; d.ClientSecret = identityConfigs.ClientSecret; d.ClientScope = identityConfigs.ClientScope; }); 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.AddControllers(options => { options.Filters.Add(); options.Filters.Add(); }); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle services.AddEndpointsApiExplorer(); services.AddSwaggerGen(c => { //添加文档 c.SwaggerDoc("v1", new OpenApiInfo() { Title = "Hotline Api", Version = "v1.0", Description = "城市热线api" }); //使用反射获取xml文件,并构造出文件的路径 var xmlFile = "document.xml"; //var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); // 启用xml注释. 该方法第二个参数启用控制器的注释,默认为false. c.IncludeXmlComments(xmlPath, 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); }); //signalR builder.Services.AddSignalR().AddStackExchangeRedis(configuration.GetConnectionString("Redis"), options => { options.Configuration.ChannelPrefix = "callcenter:signalR:"; }); /* CORS */ 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(); }); }); //mapster var config = TypeAdapterConfig.GlobalSettings; services.AddSingleton(config); services.AddScoped(); //mediatr services.AddMediatR(Assembly.GetExecutingAssembly(), typeof(ApplicationStartupExtensions).Assembly); //迅时IPPBX var deviceConfigs = configuration.GetSection("DeviceConfigs").Get(); services.AddNewRock(deviceConfigs.Address); //sqlsugar services.AddSqlSugar(configuration, "Hotline"); //cache services.AddCache(d => { d.ConnectionString = configuration.GetConnectionString("Redis"); d.Prefix = "Hotline"; }); //validator services.AddFluentValidationAutoValidation(config => { config.DisableDataAnnotationsValidation = true; }) .AddValidatorsFromAssembly(typeof(AppContractsStartupExtensions).Assembly); //ex log services.AddExceptionless(configuration); services.AddSingleton(); services.AddSingleton(); return builder.Build(); } internal static WebApplication ConfigurePipelines(this WebApplication app) { app.UseSerilogRequestLogging(); var useExless = app.Configuration.GetSection("Exceptionless:InUse").Get(); if (useExless) { app.UseExceptionless(); } var swaggerEnable = app.Configuration.GetSection("Swagger").Get(); // Configure the HTTP request pipeline. if (swaggerEnable) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseCors(CorsOrigins); app.UseAuthentication(); app.UseAuthorization(); app.MapHub("/hubs/callcenter"); //app.UseMiddleware(); app.MapControllers() .RequireAuthorization(); return app; } }