244 lines
11 KiB
C#
244 lines
11 KiB
C#
using Autofac;
|
||
using log4net;
|
||
using log4net.Config;
|
||
using Microsoft.AspNetCore.Http.Features;
|
||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||
using Microsoft.OpenApi.Models;
|
||
using System.Text.Encodings.Web;
|
||
using System.Text.Unicode;
|
||
using Competition.BLL;
|
||
using Competition.DAL;
|
||
using Competition.Model;
|
||
using Microsoft.EntityFrameworkCore;
|
||
using Microsoft.Extensions.Configuration;
|
||
using Microsoft.Extensions.DependencyInjection;
|
||
using Microsoft.Extensions.Hosting;
|
||
using Microsoft.Extensions.Logging;
|
||
using Microsoft.AspNetCore.Builder;
|
||
using Microsoft.AspNetCore.Hosting;
|
||
using System.Linq;
|
||
using System.IO;
|
||
using Microsoft.AspNetCore.Mvc;
|
||
using Autofac.Core;
|
||
using Newtonsoft.Json.Serialization;
|
||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||
using Microsoft.IdentityModel.Tokens;
|
||
using System.Text;
|
||
using Newtonsoft.Json;
|
||
using Competition.Common.Util;
|
||
using static System.Net.WebRequestMethods;
|
||
using Newtonsoft.Json.Linq;
|
||
using System.Security.Claims;
|
||
|
||
namespace CompetitionAPI
|
||
{
|
||
public class Startup
|
||
{
|
||
public static log4net.Repository.ILoggerRepository repository;
|
||
|
||
public Startup(IConfiguration configuration)
|
||
{
|
||
Configuration = configuration;
|
||
repository = LogManager.CreateRepository("NETCoreRepository");
|
||
XmlConfigurator.Configure(repository, new FileInfo("Log4net.config"));
|
||
}
|
||
|
||
public IConfiguration Configuration { get; }
|
||
|
||
// This method gets called by the runtime. Use this method to add services to the container.
|
||
public void ConfigureServices(IServiceCollection services)
|
||
{
|
||
//配置跨域访问问题
|
||
services.AddCors(
|
||
options => options.AddPolicy("CorsTest",
|
||
p => p.AllowAnyOrigin()
|
||
.AllowAnyHeader()
|
||
.AllowAnyMethod()
|
||
)
|
||
);
|
||
services.Configure<FormOptions>(options =>
|
||
{
|
||
options.KeyLengthLimit = int.MaxValue;
|
||
options.ValueLengthLimit = int.MaxValue;
|
||
options.MultipartBodyLengthLimit = int.MaxValue;
|
||
options.MultipartHeadersLengthLimit = int.MaxValue;
|
||
});
|
||
services.Configure<KestrelServerOptions>(options =>
|
||
{
|
||
options.Limits.MaxRequestBodySize = int.MaxValue;
|
||
options.Limits.MaxRequestBufferSize = int.MaxValue;
|
||
});
|
||
//禁用自动模型验证
|
||
services.Configure<ApiBehaviorOptions>(options =>
|
||
{
|
||
options.SuppressModelStateInvalidFilter = true;
|
||
});
|
||
services.AddDbContext<competition_dbContext>(options => options.UseMySql(Configuration.GetConnectionString("MySQL")));
|
||
services.AddControllers().AddJsonOptions(options =>
|
||
{
|
||
options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);
|
||
});
|
||
////注册Swagger生成器,定义一个和多个Swagger 文档
|
||
//services.AddSwaggerGen(c =>
|
||
//{
|
||
// c.SwaggerDoc("v1", new OpenApiInfo { Title = "CompetitionAPI" });
|
||
// // 为 Swagger JSON and UI设置xml文档注释路径
|
||
// var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);//获取应用程序所在目录(绝对,不受工作目录影响,建议采用此方法获取路径)
|
||
// var xmlPath = Path.Combine(basePath, "CompetitionAPI.xml");
|
||
// c.IncludeXmlComments(xmlPath);
|
||
//});
|
||
|
||
services.AddControllers().AddNewtonsoftJson(options =>
|
||
{
|
||
//配置返回Json大小写格式与Model一致
|
||
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
|
||
});
|
||
|
||
//添加MVC组件
|
||
services.AddMvc().AddNewtonsoftJson(options =>
|
||
{
|
||
options.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" });
|
||
});
|
||
|
||
//注入Http
|
||
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||
|
||
// 确保 TokenService 类被正确注册
|
||
services.AddSingleton<TokenService>(new TokenService(Configuration["Jwt:SecretKey"], Configuration["Jwt:Issuer"]));
|
||
|
||
// 添加身份验证服务
|
||
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
||
.AddJwtBearer(options =>
|
||
{
|
||
options.TokenValidationParameters = new TokenValidationParameters
|
||
{
|
||
ValidateIssuer = true,
|
||
ValidIssuer = Configuration["Jwt:Issuer"],
|
||
ValidateIssuerSigningKey = true,
|
||
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:SecretKey"])),
|
||
ValidateAudience = false,
|
||
ValidateLifetime = true,
|
||
ClockSkew = TimeSpan.Zero
|
||
};
|
||
options.Events = new JwtBearerEvents
|
||
{
|
||
// 添加自定义的Token验证后的处理逻辑
|
||
OnTokenValidated = async context =>
|
||
{
|
||
try
|
||
{
|
||
// 获取请求头中的Authorization值
|
||
string authorizationHeader = context.HttpContext.Request.Headers["Authorization"];
|
||
|
||
// 确保Authorization头存在且以Bearer开头
|
||
if (!string.IsNullOrEmpty(authorizationHeader) && authorizationHeader.StartsWith("Bearer "))
|
||
{
|
||
// 提取Token值
|
||
//var token = authorizationHeader.Substring("Bearer ".Length).Trim();
|
||
var token = "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiIyMDIxMTAxMzEzNTczOTIwMDczOTE0Iiwicm9sZSI6IjAiLCJuYmYiOjE3MzEyOTM5OTYsImV4cCI6MTczMTM4MDM5NiwiaWF0IjoxNzMxMjkzOTk2LCJpc3MiOiJ5b3VyX2lzc3VlciJ9.d7ymDYzNgCrwz1KVMlIbM_tZRY7E4MFEvZfeesAAeUM";
|
||
|
||
// 在这里可以访问验证后的Principal(包含用户信息)
|
||
var claimsPrincipal = context.Principal.Claims;
|
||
var userId = claimsPrincipal.First(claim => claim.Type == ClaimTypes.NameIdentifier).Value;
|
||
var roleId = claimsPrincipal.First(claim => claim.Type == ClaimTypes.Role).Value;
|
||
if (roleId == "2")
|
||
{
|
||
Competition.Mysql.BLL.admin_user bll = new Competition.Mysql.BLL.admin_user();
|
||
var user_model = bll.GetModel(userId);
|
||
if (user_model != null)
|
||
{
|
||
if (user_model.r4 != token)
|
||
{
|
||
context.Fail("");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
context.Fail("");
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
context.Fail("");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
// 记录日志或处理异常
|
||
context.Fail(ex);
|
||
}
|
||
},
|
||
//此处为权限验证失败后触发的事件
|
||
OnChallenge = context =>
|
||
{
|
||
//此处代码为终止.Net Core默认的返回类型和数据结果,这个很重要哦,必须
|
||
context.HandleResponse();
|
||
var response = Tool.GetJsonWithCode(APICode.TokenFail, "Authentication failed");
|
||
//自定义自己想要返回的数据结果,我这里要返回的是Json对象,通过引用Newtonsoft.Json库进行转换
|
||
var payload = JsonConvert.SerializeObject(response);
|
||
//自定义返回的数据类型
|
||
context.Response.ContentType = "application/json";
|
||
//自定义返回状态码,默认为401 我这里改成 200
|
||
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
|
||
//输出Json数据结果
|
||
context.Response.WriteAsync(payload);
|
||
return Task.FromResult(0);
|
||
}
|
||
};
|
||
});
|
||
}
|
||
|
||
public void ConfigureContainer(ContainerBuilder builder)
|
||
{
|
||
//AUTOFAC注入
|
||
builder.RegisterAssemblyTypes(typeof(BaseRepository<,>).Assembly)
|
||
.Where(t => t.Name.EndsWith("Repository"))
|
||
.AsImplementedInterfaces();
|
||
builder.RegisterAssemblyTypes(typeof(BaseService<,>).Assembly)
|
||
.Where(t => t.Name.EndsWith("Service"))
|
||
.AsImplementedInterfaces();
|
||
|
||
}
|
||
|
||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||
{
|
||
//DefaultFilesOptions defaultFilesOptions = new DefaultFilesOptions();
|
||
//defaultFilesOptions.DefaultFileNames.Clear();
|
||
//defaultFilesOptions.DefaultFileNames.Add("index.html");
|
||
//app.UseDefaultFiles(defaultFilesOptions);
|
||
|
||
|
||
app.UseDefaultFiles();
|
||
app.UseStaticFiles();
|
||
|
||
if (env.IsDevelopment())
|
||
{
|
||
app.UseDeveloperExceptionPage();
|
||
}
|
||
|
||
// 启用身份验证中间件
|
||
app.UseAuthentication();
|
||
app.UseRouting();
|
||
app.UseCors("CorsTest");//其中app.UseCors()必须放在app.UseRouting()和app.UseEndpoints之间,不然还是解决不了问题。
|
||
app.UseAuthorization();
|
||
|
||
app.UseEndpoints(endpoints =>
|
||
{
|
||
endpoints.MapControllers();
|
||
});
|
||
|
||
////启用中间件服务生成Swagger作为JSON终结点
|
||
//app.UseSwagger();
|
||
////启用中间件服务对swagger-ui,指定Swagger JSON终结点
|
||
//app.UseSwaggerUI(c =>
|
||
//{
|
||
// c.SwaggerEndpoint("/swagger/v1/swagger.json", "CompetitionAPI");
|
||
//});
|
||
|
||
|
||
}
|
||
}
|
||
}
|