using Autofac; using log4net.Config; using log4net; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; using Newtonsoft.Json; using Ropin.Core.Extensions; using Ropin.Core.Extensions.Middlewares; using Ropin.Core.Extensions.ServiceExtensions; using Ropin.Inspection.Api.Common; //using Ropin.Inspection.Api.Common.Authorize; using Ropin.Inspection.Api.Common.Options; using Ropin.Inspection.Api.Common.Token; using Ropin.Inspection.Api.Filters; using Ropin.Inspection.Api.Helper; using Ropin.Inspection.Common.Accessor; using Ropin.Inspection.Common.Accessor.Interface; using Ropin.Inspection.Common.Helper; using Ropin.Inspection.Model.Entities; using Ropin.Inspection.Repository; using Ropin.Inspection.Repository.Interface; using Ropin.Inspection.Service; using Ropin.Inspection.Service.Interface; using Ropin.Inspection.Tasks.QuartzNet; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace Ropin.Inspection.Api { public class Startup { public Startup(IConfiguration configuration, IWebHostEnvironment env) { Configuration = configuration; Env = env; var logRepo = LogManager.GetRepository(Assembly.GetEntryAssembly()); XmlConfigurator.Configure(logRepo, new FileInfo("log4net.config")); } public IConfiguration Configuration { get; } public IWebHostEnvironment Env { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddSingleton(new Appsettings(Configuration)); //services.AddSingleton(new LogLock(Env.ContentRootPath)); services.AddControllers(); services.AddHttpClient(); services.Configure("WXOptions", Configuration.GetSection("WX")); services.Configure("RabbitMQModel", Configuration.GetSection("RabbitMQ")); #region 读取配置信息 services.AddSingleton(); services.Configure(Configuration.GetSection("JWT")); JWTConfig config = new JWTConfig(); Configuration.GetSection("JWT").Bind(config); #endregion #region 启用JWT认证 services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }). AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { //是否验证发行人 ValidateIssuer = true, ValidIssuer = config.Issuer,//发行人 //是否验证受众人 ValidateAudience = true, ValidAudience = config.Audience,//受众人 //是否验证密钥 ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(config.IssuerSigningKey)), ValidateLifetime = true, //验证生命周期 RequireExpirationTime = true, //过期时间 }; options.Events = new JwtBearerEvents { OnAuthenticationFailed = context => { //Token expired if (context.Exception.GetType() == typeof(SecurityTokenExpiredException)) { context.Response.Headers.Add("Token-Expired", "true"); } return Task.CompletedTask; }, OnChallenge = async context =>//验证失败自定义返回类 { // 跳过默认的处理逻辑,返回下面的模型数据 context.HandleResponse(); context.Response.ContentType = "application/json;charset=utf-8"; context.Response.StatusCode = StatusCodes.Status401Unauthorized; var result = new ApiResult(ReturnCode.TokenError, "Token失效"); //var result = new ServiceResult();//实例化返回类 //result.IsFailed("UnAuthorized"); await context.Response.WriteAsync(JsonConvert.SerializeObject(result)); //await context.Response.WriteAsync("验证失败"); } }; //options.TokenValidationParameters = new TokenValidationParameters //{ // ValidIssuer = config.Issuer, // ValidAudience = config.Audience, // IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config.IssuerSigningKey)), // ClockSkew = TimeSpan.FromMinutes(5), // ValidateLifetime = true,//是否验证失效时间 // //ClockSkew = TimeSpan.FromSeconds(30), // ValidateAudience = true,//是否验证Audience // //ValidAudience = Const.GetValidudience(),//Audience // //这里采用动态验证的方式,在重新登陆时,刷新token,旧token就强制失效了 // AudienceValidator = (m, n, z) => // { // return m != null && m.FirstOrDefault().Equals(config.ValidAudience); // }, // ValidateIssuer = true,//是否验证Issuer // ValidateIssuerSigningKey = true,//是否验证SecurityKey //}; //options.Events = new JwtBearerEvents //{ // OnAuthenticationFailed = context => // { // //Token expired // if (context.Exception.GetType() == typeof(SecurityTokenExpiredException)) // { // context.Response.Headers.Add("Token-Expired", "true"); // } // return Task.CompletedTask; // } //}; }); #endregion #region 自定义授权 //services.AddAuthorization(options => options.AddPolicy("Permission", policy => policy.Requirements.Add(new PermissionRequirement()))); //services.AddScoped(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); #endregion //添加对AutoMapper的支持 services.AddAutoMapper(typeof(AutoMapperProfile)); services.AddScoped(); // services.AddAutoMapper(typeof(Startup)); //services.AddScoped(); //services.AddHostedService(); services.AddJobSetup(); services.AddMemoryCacheSetup(); services.AddRedisCacheSetup(); services.AddNodeServices(); //services.AddNodeServices(options => { // options.ProjectPath = Path.Combine(Directory.GetCurrentDirectory(), "scripts"); //}); // services.AddScoped(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "Ropin.Inspection.Api", Version = "v1" }); c.DocInclusionPredicate((docName, description) => true); var baseDirectory = AppDomain.CurrentDomain.BaseDirectory; //此处为API的项目描述文件名 var commentsFileName = "Ropin.Inspection.Api.xml"; var commentsFile = Path.Combine(baseDirectory, commentsFileName); c.IncludeXmlComments(commentsFile); //Bearer 的scheme定义 var securityScheme = new OpenApiSecurityScheme() { Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"", Name = "Authorization", //参数添加在头部 In = ParameterLocation.Header, //使用Authorize头部 Type = SecuritySchemeType.Http, //内容为以 Bearer开头 Scheme = "Bearer", BearerFormat = "JWT" }; //把所有方法配置为增加bearer头部信息 var securityRequirement = new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "bearerAuth" } }, new string[] {} } }; ////开启权限小锁 //c.OperationFilter(); //c.OperationFilter(); ////在header中添加token,传递到后台 //c.OperationFilter(); //注册到swagger中 c.AddSecurityDefinition("bearerAuth", securityScheme); c.AddSecurityRequirement(securityRequirement); // c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme() // { // Description = "Please enter into field the word 'Bearer' followed by a space and the JWT value", // Name = "Authorization", // In = ParameterLocation.Header, // Type = SecuritySchemeType.ApiKey, // }); // c.AddSecurityRequirement(new OpenApiSecurityRequirement { //{ new OpenApiSecurityScheme //{ // Reference = new OpenApiReference() // { // Id = "Bearer", // Type = ReferenceType.SecurityScheme // } //}, Array.Empty() } //}); }); var connectionString = Configuration["ConnectionSetting:MySqlConnection"]; //var connectionString = Configuration.GetConnectionString("MySqlConnection"); ServerVersion serverVersion = ServerVersion.AutoDetect(connectionString); services.AddDbContext(options => options.UseMySql(connectionString, serverVersion)); //services.AddSingleton(); //services.AddDbContext(options => options.UseMySql(Configuration["ConnectionSetting:MySqlConnection"])); // 配置跨域处理,允许所有来源 //services.AddCors(options => //options.AddPolicy("cors", //p => p.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod().AllowCredentials())); services.AddCors(options => { options.AddPolicy("CorsPolicy", builder => builder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader()); }); services.AddMvc(options => { options.Filters.Add(); // 添加身份验证过滤器 -- 菜单操作权限 }); //services.AddMvc(config => //{ // config.Filters.Add(); // config.ReturnHttpNotAcceptable = true; // //config.OutputFormatters.Add(new XmlSerializerOutputFormatter()); //}).SetCompatibilityVersion(CompatibilityVersion.Version_2_2) //.AddXmlSerializerFormatters(); services.AddControllers(o => { // 全局异常过滤 o.Filters.Add(typeof(ExceptionFilter)); }) .AddNewtonsoftJson(options => { //忽略循环引用 options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; //设置时间格式 //options.SerializerSettings.DateFormatString = "yyyy-MM-dd"; //忽略Model中为null的属性 //options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; //设置本地时间而非UTC时间 options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local; }); } // 注意在Program.CreateHostBuilder,添加Autofac服务工厂 public void ConfigureContainer(ContainerBuilder builder) { builder.RegisterModule(new AutofacModuleRegister()); //builder.RegisterModule(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env, InspectionDbContext dataDBContext) { // 允许所有跨域,cors是在ConfigureServices方法中配置的跨域策略名称 //app.UseCors("cors"); app.UseCors("CorsPolicy"); //if (env.IsDevelopment()) //{ app.UseDeveloperExceptionPage(); //启用中间件服务生成Swagger作为JSON终结点 app.UseSwagger(); //启用中间件服务对swagger-ui,指定Swagger JSON终结点/swagger/ app.UseSwaggerUI(c => c.SwaggerEndpoint("v1/swagger.json", "Ropin.Inspection.Api v1")); //} //1.先开启认证 app.UseAuthentication(); app.UseRouting(); //2.再开启授权 app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); // 开启QuartzNetJob调度服务 //app.UseQuartzJobMildd(tasksQzServices, schedulerCenter); //app.UseMvc(); //dataDBContext.Database.EnsureCreated();//数据库不存在的话,会自动创建 } } }