Startup.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. using Autofac;
  2. using log4net.Config;
  3. using log4net;
  4. using Microsoft.AspNetCore.Authentication.JwtBearer;
  5. using Microsoft.AspNetCore.Authorization;
  6. using Microsoft.AspNetCore.Builder;
  7. using Microsoft.AspNetCore.Hosting;
  8. using Microsoft.AspNetCore.Http;
  9. using Microsoft.AspNetCore.Mvc;
  10. using Microsoft.EntityFrameworkCore;
  11. using Microsoft.Extensions.Configuration;
  12. using Microsoft.Extensions.DependencyInjection;
  13. using Microsoft.Extensions.Hosting;
  14. using Microsoft.Extensions.Logging;
  15. using Microsoft.IdentityModel.Tokens;
  16. using Microsoft.OpenApi.Models;
  17. using Newtonsoft.Json;
  18. using Ropin.Core.Extensions;
  19. using Ropin.Core.Extensions.Middlewares;
  20. using Ropin.Core.Extensions.ServiceExtensions;
  21. using Ropin.Inspection.Api.Common;
  22. //using Ropin.Inspection.Api.Common.Authorize;
  23. using Ropin.Inspection.Api.Common.Options;
  24. using Ropin.Inspection.Api.Common.Token;
  25. using Ropin.Inspection.Api.Filters;
  26. using Ropin.Inspection.Api.Helper;
  27. using Ropin.Inspection.Common.Accessor;
  28. using Ropin.Inspection.Common.Accessor.Interface;
  29. using Ropin.Inspection.Common.Helper;
  30. using Ropin.Inspection.Model.Entities;
  31. using Ropin.Inspection.Repository;
  32. using Ropin.Inspection.Repository.Interface;
  33. using Ropin.Inspection.Service;
  34. using Ropin.Inspection.Service.Interface;
  35. using Ropin.Inspection.Tasks.QuartzNet;
  36. using System;
  37. using System.Collections.Generic;
  38. using System.IO;
  39. using System.Linq;
  40. using System.Reflection;
  41. using System.Text;
  42. using System.Threading.Tasks;
  43. using Minio;
  44. namespace Ropin.Inspection.Api
  45. {
  46. public class Startup
  47. {
  48. public Startup(IConfiguration configuration, IWebHostEnvironment env)
  49. {
  50. Configuration = configuration;
  51. Env = env;
  52. var logRepo = LogManager.GetRepository(Assembly.GetEntryAssembly());
  53. XmlConfigurator.Configure(logRepo, new FileInfo("log4net.config"));
  54. }
  55. public IConfiguration Configuration { get; }
  56. public IWebHostEnvironment Env { get; }
  57. // This method gets called by the runtime. Use this method to add services to the container.
  58. public void ConfigureServices(IServiceCollection services)
  59. {
  60. services.AddSingleton(new Appsettings(Configuration));
  61. //services.AddSingleton(new LogLock(Env.ContentRootPath));
  62. services.AddControllers();
  63. services.AddHttpClient();
  64. services.Configure<WXOptions>("WXOptions", Configuration.GetSection("WX"));
  65. services.Configure<RabbitMQModel>("RabbitMQModel", Configuration.GetSection("RabbitMQ"));
  66. #region 读取配置信息
  67. services.AddSingleton<ITokenHelper, TokenHelper>();
  68. services.Configure<JWTConfig>(Configuration.GetSection("JWT"));
  69. JWTConfig config = new JWTConfig();
  70. Configuration.GetSection("JWT").Bind(config);
  71. #endregion
  72. services.AddMemoryCache();
  73. #region 启用JWT认证
  74. services.AddAuthentication(options =>
  75. {
  76. options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
  77. options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
  78. options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
  79. }).
  80. AddJwtBearer(options =>
  81. {
  82. options.TokenValidationParameters = new TokenValidationParameters
  83. {
  84. //是否验证发行人
  85. ValidateIssuer = true,
  86. ValidIssuer = config.Issuer,//发行人
  87. //是否验证受众人
  88. ValidateAudience = true,
  89. ValidAudience = config.Audience,//受众人
  90. //是否验证密钥
  91. ValidateIssuerSigningKey = true,
  92. IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(config.IssuerSigningKey)),
  93. ValidateLifetime = true, //验证生命周期
  94. RequireExpirationTime = true, //过期时间
  95. };
  96. options.Events = new JwtBearerEvents
  97. {
  98. OnAuthenticationFailed = context =>
  99. {
  100. //Token expired
  101. if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
  102. {
  103. context.Response.Headers.Add("Token-Expired", "true");
  104. }
  105. return Task.CompletedTask;
  106. },
  107. OnChallenge = async context =>//验证失败自定义返回类
  108. {
  109. // 跳过默认的处理逻辑,返回下面的模型数据
  110. context.HandleResponse();
  111. context.Response.ContentType = "application/json;charset=utf-8";
  112. context.Response.StatusCode = StatusCodes.Status401Unauthorized;
  113. var result = new ApiResult(ReturnCode.TokenError, "Token失效");
  114. //var result = new ServiceResult();//实例化返回类
  115. //result.IsFailed("UnAuthorized");
  116. await context.Response.WriteAsync(JsonConvert.SerializeObject(result));
  117. //await context.Response.WriteAsync("验证失败");
  118. }
  119. };
  120. //options.TokenValidationParameters = new TokenValidationParameters
  121. //{
  122. // ValidIssuer = config.Issuer,
  123. // ValidAudience = config.Audience,
  124. // IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config.IssuerSigningKey)),
  125. // ClockSkew = TimeSpan.FromMinutes(5),
  126. // ValidateLifetime = true,//是否验证失效时间
  127. // //ClockSkew = TimeSpan.FromSeconds(30),
  128. // ValidateAudience = true,//是否验证Audience
  129. // //ValidAudience = Const.GetValidudience(),//Audience
  130. // //这里采用动态验证的方式,在重新登陆时,刷新token,旧token就强制失效了
  131. // AudienceValidator = (m, n, z) =>
  132. // {
  133. // return m != null && m.FirstOrDefault().Equals(config.ValidAudience);
  134. // },
  135. // ValidateIssuer = true,//是否验证Issuer
  136. // ValidateIssuerSigningKey = true,//是否验证SecurityKey
  137. //};
  138. //options.Events = new JwtBearerEvents
  139. //{
  140. // OnAuthenticationFailed = context =>
  141. // {
  142. // //Token expired
  143. // if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
  144. // {
  145. // context.Response.Headers.Add("Token-Expired", "true");
  146. // }
  147. // return Task.CompletedTask;
  148. // }
  149. //};
  150. });
  151. #endregion
  152. #region 自定义授权
  153. //services.AddAuthorization(options => options.AddPolicy("Permission", policy => policy.Requirements.Add(new PermissionRequirement())));
  154. //services.AddScoped<IAuthorizationHandler, PermissionHandler>();
  155. services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
  156. services.AddSingleton<IPrincipalAccessor, PrincipalAccessor>();
  157. services.AddSingleton<IClaimsAccessor, ClaimsAccessor>();
  158. #endregion
  159. //添加对AutoMapper的支持
  160. services.AddAutoMapper(typeof(AutoMapperProfile));
  161. services.AddScoped<AuthorExistFilterAttribute>();
  162. // 添加MinIO服务
  163. var minioSettings = Configuration.GetSection("MinioSettings").Get<MinioSettingsOptions>();
  164. services.Configure<MinioSettingsOptions>(Configuration.GetSection("MinioSettings"));
  165. services.AddMinio(configureClient => configureClient
  166. .WithEndpoint(minioSettings.Endpoint)
  167. .WithCredentials(minioSettings.AccessKey, minioSettings.SecretKey)
  168. .WithSSL(minioSettings.UseSSL)
  169. .Build()
  170. );
  171. // services.AddAutoMapper(typeof(Startup));
  172. //services.AddScoped<ITokenHelper, TokenHelper>();
  173. //services.AddHostedService<Work.HostedService>();
  174. services.AddJobSetup();
  175. services.AddMemoryCacheSetup();
  176. services.AddRedisCacheSetup();
  177. services.AddNodeServices();
  178. //services.AddNodeServices(options => {
  179. // options.ProjectPath = Path.Combine(Directory.GetCurrentDirectory(), "scripts");
  180. //});
  181. // services.AddScoped<IRepositoryWrapper, RepositoryWrapper>();
  182. services.AddSwaggerGen(c =>
  183. {
  184. c.SwaggerDoc("v1", new OpenApiInfo { Title = "Ropin.Inspection.Api", Version = "v1" });
  185. c.DocInclusionPredicate((docName, description) => true);
  186. var baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
  187. //此处为API的项目描述文件名
  188. var commentsFileName = "Ropin.Inspection.Api.xml";
  189. var commentsFile = Path.Combine(baseDirectory, commentsFileName);
  190. c.IncludeXmlComments(commentsFile);
  191. //Bearer 的scheme定义
  192. var securityScheme = new OpenApiSecurityScheme()
  193. {
  194. Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
  195. Name = "Authorization",
  196. //参数添加在头部
  197. In = ParameterLocation.Header,
  198. //使用Authorize头部
  199. Type = SecuritySchemeType.Http,
  200. //内容为以 Bearer开头
  201. Scheme = "Bearer",
  202. BearerFormat = "JWT"
  203. };
  204. //把所有方法配置为增加bearer头部信息
  205. var securityRequirement = new OpenApiSecurityRequirement
  206. {
  207. {
  208. new OpenApiSecurityScheme
  209. {
  210. Reference = new OpenApiReference
  211. {
  212. Type = ReferenceType.SecurityScheme,
  213. Id = "bearerAuth"
  214. }
  215. },
  216. new string[] {}
  217. }
  218. };
  219. ////开启权限小锁
  220. //c.OperationFilter<AddResponseHeadersFilter>();
  221. //c.OperationFilter<AppendAuthorizeToSummaryOperationFilter>();
  222. ////在header中添加token,传递到后台
  223. //c.OperationFilter<SecurityRequirementsOperationFilter>();
  224. //注册到swagger中
  225. c.AddSecurityDefinition("bearerAuth", securityScheme);
  226. c.AddSecurityRequirement(securityRequirement);
  227. // c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
  228. // {
  229. // Description = "Please enter into field the word 'Bearer' followed by a space and the JWT value",
  230. // Name = "Authorization",
  231. // In = ParameterLocation.Header,
  232. // Type = SecuritySchemeType.ApiKey,
  233. // });
  234. // c.AddSecurityRequirement(new OpenApiSecurityRequirement {
  235. //{ new OpenApiSecurityScheme
  236. //{
  237. // Reference = new OpenApiReference()
  238. // {
  239. // Id = "Bearer",
  240. // Type = ReferenceType.SecurityScheme
  241. // }
  242. //}, Array.Empty<string>() }
  243. //});
  244. });
  245. var connectionString = Configuration["ConnectionSetting:MySqlConnection"];
  246. //var connectionString = Configuration.GetConnectionString("MySqlConnection");
  247. ServerVersion serverVersion = ServerVersion.AutoDetect(connectionString);
  248. services.AddDbContext<InspectionDbContext>(options =>
  249. options.UseMySql(connectionString, serverVersion));
  250. //services.AddSingleton<IHostingEnvironment>();
  251. //services.AddDbContext<InspectionDbContext>(options => options.UseMySql(Configuration["ConnectionSetting:MySqlConnection"]));
  252. // 配置跨域处理,允许所有来源
  253. //services.AddCors(options =>
  254. //options.AddPolicy("cors",
  255. //p => p.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod().AllowCredentials()));
  256. services.AddCors(options =>
  257. {
  258. options.AddPolicy("CorsPolicy",
  259. builder => builder.AllowAnyOrigin()
  260. .AllowAnyMethod()
  261. .AllowAnyHeader());
  262. });
  263. services.AddMvc(options =>
  264. {
  265. options.Filters.Add<AuthorExistFilterAttribute>(); // 添加身份验证过滤器 -- 菜单操作权限
  266. });
  267. //services.AddMvc(config =>
  268. //{
  269. // config.Filters.Add<ExceptionFilter>();
  270. // config.ReturnHttpNotAcceptable = true;
  271. // //config.OutputFormatters.Add(new XmlSerializerOutputFormatter());
  272. //}).SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
  273. //.AddXmlSerializerFormatters();
  274. services.AddControllers(o =>
  275. {
  276. // 全局异常过滤
  277. o.Filters.Add(typeof(ExceptionFilter));
  278. })
  279. .AddNewtonsoftJson(options =>
  280. {
  281. //忽略循环引用
  282. options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
  283. //设置时间格式
  284. //options.SerializerSettings.DateFormatString = "yyyy-MM-dd";
  285. //忽略Model中为null的属性
  286. //options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
  287. //设置本地时间而非UTC时间
  288. options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;
  289. });
  290. }
  291. // 注意在Program.CreateHostBuilder,添加Autofac服务工厂
  292. public void ConfigureContainer(ContainerBuilder builder)
  293. {
  294. builder.RegisterModule(new AutofacModuleRegister());
  295. //builder.RegisterModule<AutofacPropertityModuleReg>();
  296. }
  297. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
  298. public void Configure(IApplicationBuilder app, IWebHostEnvironment env, InspectionDbContext dataDBContext)
  299. {
  300. // 允许所有跨域,cors是在ConfigureServices方法中配置的跨域策略名称
  301. //app.UseCors("cors");
  302. app.UseCors("CorsPolicy");
  303. //if (env.IsDevelopment())
  304. //{
  305. app.UseDeveloperExceptionPage();
  306. //启用中间件服务生成Swagger作为JSON终结点
  307. app.UseSwagger();
  308. //启用中间件服务对swagger-ui,指定Swagger JSON终结点/swagger/
  309. app.UseSwaggerUI(c => c.SwaggerEndpoint("v1/swagger.json", "Ropin.Inspection.Api v1"));
  310. //}
  311. app.UseMiddleware<RequestMiddleware>();
  312. //1.先开启认证
  313. app.UseAuthentication();
  314. app.UseRouting();
  315. //2.再开启授权
  316. app.UseAuthorization();
  317. app.UseEndpoints(endpoints =>
  318. {
  319. endpoints.MapControllers();
  320. });
  321. // 开启QuartzNetJob调度服务
  322. //app.UseQuartzJobMildd(tasksQzServices, schedulerCenter);
  323. //app.UseMvc();
  324. //dataDBContext.Database.EnsureCreated();//数据库不存在的话,会自动创建
  325. }
  326. }
  327. }