StartupExtensions.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. using System.IdentityModel.Tokens.Jwt;
  2. using System.Reflection;
  3. using Exceptionless;
  4. using FluentValidation;
  5. using FluentValidation.AspNetCore;
  6. using Hotline.Api.Realtimes;
  7. using Hotline.Application;
  8. using Hotline.Application.Contracts;
  9. using Hotline.Application.Contracts.Configurations;
  10. using Hotline.CacheManager;
  11. using Hotline.CallCenter.Devices;
  12. using Hotline.Identity.Accounts;
  13. using Hotline.NewRock;
  14. using Hotline.Permissions;
  15. using Hotline.Repository.SqlSugar;
  16. using Hotline.Repository.SqlSugar.Extensions;
  17. using Hotline.Settings;
  18. using Mapster;
  19. using MapsterMapper;
  20. using MediatR;
  21. using Microsoft.AspNetCore.Authentication.JwtBearer;
  22. using Microsoft.AspNetCore.Authorization;
  23. using Microsoft.AspNetCore.Identity;
  24. using Microsoft.IdentityModel.Tokens;
  25. using Microsoft.OpenApi.Models;
  26. using Serilog;
  27. using XF.Domain.Dependency;
  28. using XF.Domain.Filters;
  29. using XF.Domain.Options;
  30. using XF.Domain.Password;
  31. namespace Hotline.Api;
  32. internal static class StartupExtensions
  33. {
  34. const string CorsOrigins = "CorsOrigins";
  35. internal static WebApplication ConfigureServices(this WebApplicationBuilder builder)
  36. {
  37. var services = builder.Services;
  38. var configuration = builder.Configuration;
  39. services.AddHttpContextAccessor();
  40. #if DEBUG
  41. builder.WebHost.UseUrls("http://*:50110");
  42. #endif
  43. services.Configure<DeviceConfigs>(d => configuration.GetSection(nameof(DeviceConfigs)).Bind(d));
  44. services.Configure<WorkTimeSettings>(d => configuration.GetSection(nameof(WorkTimeSettings)).Bind(d));
  45. services.Configure<IdentityConfiguration>(d => configuration.GetSection(nameof(IdentityConfiguration)).Bind(d));
  46. // Add services to the container.
  47. services
  48. .BatchInjectServices()
  49. .AddApplication()
  50. .AddScoped<IPasswordHasher<Account>, PasswordHasher<Account>>()
  51. ;
  52. //Authentication
  53. services.AddAuthenticationService(configuration);
  54. services.AddControllers(options =>
  55. {
  56. options.Filters.Add<UnifyResponseFilter>();
  57. options.Filters.Add<UserFriendlyExceptionFilter>();
  58. })
  59. .AddDapr(d =>
  60. {
  61. #if DEBUG
  62. d.UseHttpEndpoint("http://192.168.100.223:50112");
  63. #endif
  64. });
  65. // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
  66. services.AddEndpointsApiExplorer();
  67. services.AddSwaggerGen(c =>
  68. {
  69. //添加文档
  70. c.SwaggerDoc("v1", new OpenApiInfo() { Title = "Hotline Api", Version = "v1.0", Description = "城市热线api" });
  71. //使用反射获取xml文件,并构造出文件的路径
  72. var xmlFile = "document.xml";
  73. //var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
  74. var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
  75. // 启用xml注释. 该方法第二个参数启用控制器的注释,默认为false.
  76. c.IncludeXmlComments(xmlPath, true);
  77. var scheme = new OpenApiSecurityScheme()
  78. {
  79. Description = "Authorization header. \r\nExample: 'Bearer ***'",
  80. Reference = new OpenApiReference
  81. {
  82. Type = ReferenceType.SecurityScheme,
  83. Id = "Authorization"
  84. },
  85. Scheme = "oauth2",
  86. Name = "Authorization",
  87. In = ParameterLocation.Header,
  88. Type = SecuritySchemeType.ApiKey,
  89. };
  90. c.AddSecurityDefinition("Authorization", scheme);
  91. var requirement = new OpenApiSecurityRequirement();
  92. requirement[scheme] = new List<string>();
  93. c.AddSecurityRequirement(requirement);
  94. });
  95. //signalR
  96. builder.Services.AddSignalR().AddStackExchangeRedis(configuration.GetConnectionString("Redis"), options =>
  97. {
  98. options.Configuration.ChannelPrefix = "callcenter:signalR:";
  99. });
  100. /* CORS */
  101. services.AddCors(options =>
  102. {
  103. options.AddPolicy(name: CorsOrigins,
  104. builder =>
  105. {
  106. var origins = configuration.GetSection("Cors:Origins").Get<string[]>();
  107. builder.SetIsOriginAllowed(a =>
  108. {
  109. return origins.Any(origin => origin.StartsWith("*.", StringComparison.Ordinal)
  110. ? a.EndsWith(origin[1..], StringComparison.Ordinal)
  111. : a.Equals(origin, StringComparison.Ordinal));
  112. })
  113. .AllowAnyHeader()
  114. .AllowAnyMethod()
  115. .AllowCredentials();
  116. });
  117. });
  118. //mapster
  119. var config = TypeAdapterConfig.GlobalSettings;
  120. services.AddSingleton(config);
  121. services.AddScoped<IMapper, ServiceMapper>();
  122. //mediatr
  123. services.AddMediatR(Assembly.GetExecutingAssembly(), typeof(ApplicationStartupExtensions).Assembly);
  124. //迅时IPPBX
  125. var deviceConfigs = configuration.GetSection("DeviceConfigs").Get<DeviceConfigs>();
  126. services.AddNewRock(deviceConfigs.Address);
  127. //sqlsugar
  128. services.AddSqlSugar(configuration, "Hotline");
  129. //cache
  130. services.AddCache(d =>
  131. {
  132. d.ConnectionString = configuration.GetConnectionString("Redis");
  133. d.Prefix = "Hotline";
  134. });
  135. //validator
  136. services.AddFluentValidationAutoValidation(config =>
  137. {
  138. config.DisableDataAnnotationsValidation = true;
  139. })
  140. .AddValidatorsFromAssembly(typeof(AppContractsStartupExtensions).Assembly);
  141. //ex log
  142. services.AddExceptionless(configuration);
  143. services.AddSingleton<IAuthorizationPolicyProvider, AuthorizationPolicyProvider>();
  144. services.AddSingleton<IAuthorizationHandler, PermissionHandler>();
  145. return builder.Build();
  146. }
  147. internal static WebApplication ConfigurePipelines(this WebApplication app)
  148. {
  149. app.UseSerilogRequestLogging();
  150. var useExless = app.Configuration.GetSection("Exceptionless:InUse").Get<bool>();
  151. if (useExless)
  152. {
  153. app.UseExceptionless();
  154. }
  155. var swaggerEnable = app.Configuration.GetSection("Swagger").Get<bool>();
  156. // Configure the HTTP request pipeline.
  157. if (swaggerEnable)
  158. {
  159. app.UseSwagger();
  160. app.UseSwaggerUI();
  161. }
  162. app.UseCors(CorsOrigins);
  163. app.UseAuthentication();
  164. app.UseAuthorization();
  165. app.MapHub<CallCenterHub>("/hubs/callcenter");
  166. //app.UseMiddleware<TempTokenMiddleware>();
  167. app.UseCloudEvents();
  168. app.MapControllers()
  169. .RequireAuthorization();
  170. app.MapSubscribeHandler();
  171. return app;
  172. }
  173. }