Startup.cs 15 KB

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