Files
Yi.Admin/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs

344 lines
14 KiB
C#
Raw Normal View History

2024-02-26 13:42:37 +08:00
using System.Globalization;
using System.Text;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;
2024-02-26 13:42:37 +08:00
using System.Threading.RateLimiting;
2023-12-11 09:55:12 +08:00
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.Extensions.Options;
2023-12-11 09:55:12 +08:00
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Converters;
2023-12-11 09:55:12 +08:00
using Volo.Abp.AspNetCore.Authentication.JwtBearer;
2024-08-13 16:45:56 +08:00
using Volo.Abp.AspNetCore.ExceptionHandling;
2024-01-21 00:26:21 +08:00
using Volo.Abp.AspNetCore.MultiTenancy;
2023-12-11 09:55:12 +08:00
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.AntiForgery;
using Volo.Abp.AspNetCore.Mvc.ExceptionHandling;
2023-12-11 09:55:12 +08:00
using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.Auditing;
using Volo.Abp.Autofac;
using Volo.Abp.Caching;
using Volo.Abp.Json;
using Volo.Abp.Json.SystemTextJson;
2024-01-21 18:11:04 +08:00
using Volo.Abp.MultiTenancy;
2023-12-11 09:55:12 +08:00
using Volo.Abp.Swashbuckle;
using Yi.Abp.Application;
using Yi.Abp.SqlsugarCore;
using Yi.Framework.AspNetCore;
using Yi.Framework.AspNetCore.Authentication.OAuth;
using Yi.Framework.AspNetCore.Authentication.OAuth.Gitee;
using Yi.Framework.AspNetCore.Authentication.OAuth.QQ;
2023-12-11 09:55:12 +08:00
using Yi.Framework.AspNetCore.Microsoft.AspNetCore.Builder;
using Yi.Framework.AspNetCore.Microsoft.Extensions.DependencyInjection;
using Yi.Framework.AspNetCore.UnifyResult;
2023-12-11 21:14:12 +08:00
using Yi.Framework.Bbs.Application;
2024-08-14 12:50:28 +08:00
using Yi.Framework.Bbs.Application.Extensions;
2024-04-04 14:00:32 +08:00
using Yi.Framework.ChatHub.Application;
2024-02-16 21:06:34 +08:00
using Yi.Framework.CodeGen.Application;
2024-10-26 15:40:45 +08:00
using Yi.Framework.Core.Json;
2023-12-11 09:55:12 +08:00
using Yi.Framework.Rbac.Application;
using Yi.Framework.Rbac.Domain.Authorization;
2024-01-24 11:26:44 +08:00
using Yi.Framework.Rbac.Domain.Shared.Consts;
2023-12-11 09:55:12 +08:00
using Yi.Framework.Rbac.Domain.Shared.Options;
2024-02-06 15:25:17 +08:00
using Yi.Framework.TenantManagement.Application;
2023-12-11 09:55:12 +08:00
namespace Yi.Abp.Web
{
[DependsOn(
2023-12-12 17:56:11 +08:00
typeof(YiAbpSqlSugarCoreModule),
2023-12-11 09:55:12 +08:00
typeof(YiAbpApplicationModule),
2024-01-21 00:26:21 +08:00
typeof(AbpAspNetCoreMultiTenancyModule),
2023-12-11 09:55:12 +08:00
typeof(AbpAspNetCoreMvcModule),
typeof(AbpAutofacModule),
typeof(AbpSwashbuckleModule),
typeof(AbpAspNetCoreSerilogModule),
typeof(AbpAuditingModule),
typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
typeof(YiFrameworkAspNetCoreModule),
typeof(YiFrameworkAspNetCoreAuthenticationOAuthModule)
2024-08-14 12:50:28 +08:00
)]
2023-12-11 09:55:12 +08:00
public class YiAbpWebModule : AbpModule
{
private const string DefaultCorsPolicyName = "Default";
2024-08-14 12:50:28 +08:00
2023-12-11 09:55:12 +08:00
public override Task ConfigureServicesAsync(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
2023-12-12 17:16:28 +08:00
var host = context.Services.GetHostingEnvironment();
2023-12-11 09:55:12 +08:00
var service = context.Services;
//请求日志
Configure<AbpAuditingOptions>(optios =>
{
2024-01-23 15:08:01 +08:00
//默认关闭,开启会有大量的审计日志
2024-10-21 23:07:44 +08:00
optios.IsEnabled = true;
2024-01-23 15:08:01 +08:00
//审计日志过滤器
2024-10-21 23:07:44 +08:00
optios.AlwaysLogSelectors.Add(x => Task.FromResult(!x.Url.StartsWith("/api/app/file/")));
2023-12-11 09:55:12 +08:00
});
//采用furion格式的规范化api默认不开启使用abp优雅的方式
//你没看错。。。
//service.AddFurionUnifyResultApi();
2024-08-13 16:45:56 +08:00
//配置错误处理显示详情
2024-08-14 12:50:28 +08:00
Configure<AbpExceptionHandlingOptions>(options => { options.SendExceptionsDetailsToClients = true; });
2023-12-11 09:55:12 +08:00
//动态Api
Configure<AbpAspNetCoreMvcOptions>(options =>
{
2024-08-14 12:50:28 +08:00
options.ConventionalControllers.Create(typeof(YiAbpApplicationModule).Assembly,
options => options.RemoteServiceName = "default");
options.ConventionalControllers.Create(typeof(YiFrameworkRbacApplicationModule).Assembly,
options => options.RemoteServiceName = "rbac");
options.ConventionalControllers.Create(typeof(YiFrameworkBbsApplicationModule).Assembly,
options => options.RemoteServiceName = "bbs");
options.ConventionalControllers.Create(typeof(YiFrameworkChatHubApplicationModule).Assembly,
options => options.RemoteServiceName = "chat-hub");
options.ConventionalControllers.Create(typeof(YiFrameworkTenantManagementApplicationModule).Assembly,
options => options.RemoteServiceName = "tenant-management");
options.ConventionalControllers.Create(typeof(YiFrameworkCodeGenApplicationModule).Assembly,
options => options.RemoteServiceName = "code-gen");
2024-04-19 17:00:50 +08:00
//统一前缀
options.ConventionalControllers.ConventionalControllerSettings.ForEach(x => x.RootPath = "api/app");
2023-12-11 09:55:12 +08:00
});
2024-10-26 15:40:45 +08:00
//【NewtonsoftJson严重问题逆天】设置api格式留给后人铭记
// service.AddControllers().AddNewtonsoftJson(options =>
// {
// options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
// options.SerializerSettings.Converters.Add(new StringEnumConverter());
// });
//请使用微软的注意abp date又包了一层采用DefaultJsonTypeInfoResolver统一覆盖
Configure<JsonOptions>(options =>
{
options.JsonSerializerOptions.TypeInfoResolver = new DefaultJsonTypeInfoResolver();
options.JsonSerializerOptions.Converters.Add(new DatetimeJsonConverter());
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
});
2023-12-12 14:33:32 +08:00
//设置缓存不要过期默认滑动20分钟
2024-02-26 13:42:37 +08:00
Configure<AbpDistributedCacheOptions>(cacheOptions =>
2023-12-11 09:55:12 +08:00
{
2024-08-14 12:50:28 +08:00
cacheOptions.GlobalCacheEntryOptions.SlidingExpiration = null;
//缓存key前缀
cacheOptions.KeyPrefix = "Yi:";
2023-12-11 09:55:12 +08:00
});
2024-08-14 12:50:28 +08:00
Configure<AbpAntiForgeryOptions>(options => { options.AutoValidate = false; });
2023-12-11 09:55:12 +08:00
//Swagger
2023-12-11 22:14:13 +08:00
context.Services.AddYiSwaggerGen<YiAbpWebModule>(options =>
{
2024-08-14 12:50:28 +08:00
options.SwaggerDoc("default",
new OpenApiInfo { Title = "Yi.Framework.Abp", Version = "v1", Description = "集大成者" });
2023-12-11 22:14:13 +08:00
});
2023-12-11 09:55:12 +08:00
//跨域
context.Services.AddCors(options =>
{
options.AddPolicy(DefaultCorsPolicyName, builder =>
{
builder
.WithOrigins(
configuration["App:CorsOrigins"]!
.Split(";", StringSplitOptions.RemoveEmptyEntries)
.Select(o => o.RemovePostFix("/"))
.ToArray()
)
.WithAbpExposedHeaders()
.SetIsOriginAllowedToAllowWildcardSubdomains()
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
2024-01-21 18:11:04 +08:00
//配置多租户
Configure<AbpTenantResolveOptions>(options =>
{
//基于cookie jwt不好用有坑
options.TenantResolvers.Clear();
options.TenantResolvers.Add(new HeaderTenantResolveContributor());
//options.TenantResolvers.Add(new HeaderTenantResolveContributor());
//options.TenantResolvers.Add(new CookieTenantResolveContributor());
//options.TenantResolvers.RemoveAll(x => x.Name == CookieTenantResolveContributor.ContributorName);
2024-01-21 18:11:04 +08:00
});
2024-01-21 00:26:21 +08:00
2024-02-26 13:42:37 +08:00
//速率限制
//每60秒限制100个请求滑块添加分6段
service.AddRateLimiter(_ =>
{
2024-08-14 12:50:28 +08:00
_.RejectionStatusCode = StatusCodes.Status429TooManyRequests;
2024-02-26 13:42:37 +08:00
_.OnRejected = (context, _) =>
{
if (context.Lease.TryGetMetadata(MetadataName.RetryAfter, out var retryAfter))
{
context.HttpContext.Response.Headers.RetryAfter =
((int)retryAfter.TotalSeconds).ToString(NumberFormatInfo.InvariantInfo);
}
2024-08-14 12:50:28 +08:00
2024-02-26 13:42:37 +08:00
context.HttpContext.Response.StatusCode = StatusCodes.Status429TooManyRequests;
context.HttpContext.Response.WriteAsync("Too many requests. Please try again later.");
return new ValueTask();
};
//全局使用,链式表达式
_.GlobalLimiter = PartitionedRateLimiter.CreateChained(
2024-08-14 12:50:28 +08:00
PartitionedRateLimiter.Create<HttpContext, string>(httpContext =>
{
var userAgent = httpContext.Request.Headers.UserAgent.ToString();
return RateLimitPartition.GetSlidingWindowLimiter
(userAgent, _ =>
new SlidingWindowRateLimiterOptions
{
PermitLimit = 1000,
Window = TimeSpan.FromSeconds(60),
SegmentsPerWindow = 6,
QueueProcessingOrder = QueueProcessingOrder.OldestFirst
});
}));
2024-02-26 13:42:37 +08:00
});
2023-12-11 09:55:12 +08:00
//jwt鉴权
2023-12-16 14:10:11 +08:00
var jwtOptions = configuration.GetSection(nameof(JwtOptions)).Get<JwtOptions>();
var refreshJwtOptions = configuration.GetSection(nameof(RefreshJwtOptions)).Get<RefreshJwtOptions>();
2023-12-11 09:55:12 +08:00
context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
2024-02-26 13:42:37 +08:00
.AddJwtBearer(options =>
2024-01-05 23:05:13 +08:00
{
2024-02-26 13:42:37 +08:00
options.TokenValidationParameters = new TokenValidationParameters
{
ClockSkew = TimeSpan.Zero,
ValidateIssuerSigningKey = true,
ValidIssuer = jwtOptions.Issuer,
ValidAudience = jwtOptions.Audience,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtOptions.SecurityKey))
};
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
2023-12-11 09:55:12 +08:00
{
2024-08-14 12:50:28 +08:00
var accessToken = context.Request.Query["access_token"];
if (!string.IsNullOrEmpty(accessToken))
{
context.Token = accessToken;
}
return Task.CompletedTask;
2023-12-11 09:55:12 +08:00
}
2024-02-26 13:42:37 +08:00
};
})
.AddJwtBearer(TokenTypeConst.Refresh, options =>
{
2024-02-26 13:42:37 +08:00
options.TokenValidationParameters = new TokenValidationParameters
{
ClockSkew = TimeSpan.Zero,
ValidateIssuerSigningKey = true,
ValidIssuer = refreshJwtOptions.Issuer,
ValidAudience = refreshJwtOptions.Audience,
2024-08-14 12:50:28 +08:00
IssuerSigningKey =
new SymmetricSecurityKey(Encoding.UTF8.GetBytes(refreshJwtOptions.SecurityKey))
2024-02-26 13:42:37 +08:00
};
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
2024-01-24 11:26:44 +08:00
{
2024-08-14 12:50:28 +08:00
var refresh_token = context.Request.Headers["refresh_token"];
if (!string.IsNullOrEmpty(refresh_token))
{
context.Token = refresh_token;
return Task.CompletedTask;
}
var refreshToken = context.Request.Query["refresh_token"];
if (!string.IsNullOrEmpty(refreshToken))
{
context.Token = refreshToken;
}
return Task.CompletedTask;
2024-01-24 11:26:44 +08:00
}
2024-02-26 13:42:37 +08:00
};
})
2024-08-14 12:50:28 +08:00
.AddQQ(options => { configuration.GetSection("OAuth:QQ").Bind(options); })
.AddGitee(options => { configuration.GetSection("OAuth:Gitee").Bind(options); });
2023-12-11 09:55:12 +08:00
//授权
context.Services.AddAuthorization();
2023-12-11 09:55:12 +08:00
return Task.CompletedTask;
}
2023-12-11 09:55:12 +08:00
public override Task OnApplicationInitializationAsync(ApplicationInitializationContext context)
{
var service = context.ServiceProvider;
var env = context.GetEnvironment();
var app = context.GetApplicationBuilder();
app.UseRouting();
2023-12-11 22:14:13 +08:00
2023-12-11 21:14:12 +08:00
//跨域
2023-12-11 09:55:12 +08:00
app.UseCors(DefaultCorsPolicyName);
2023-12-11 22:14:13 +08:00
if (!env.IsDevelopment())
{
//速率限制
app.UseRateLimiter();
}
2024-02-26 13:42:37 +08:00
//无感token先刷新再鉴权
app.UseRefreshToken();
2023-12-11 21:14:12 +08:00
//鉴权
2023-12-11 09:55:12 +08:00
app.UseAuthentication();
2024-01-21 00:26:21 +08:00
//多租户
app.UseMultiTenancy();
2023-12-11 21:14:12 +08:00
//swagger
2023-12-11 09:55:12 +08:00
app.UseYiSwagger();
2024-01-05 23:05:13 +08:00
2024-08-14 22:23:54 +08:00
//流量访问统计,需redis支持否则不生效
app.UseAccessLog();
2024-08-14 12:50:28 +08:00
2024-01-02 23:26:05 +08:00
//请求处理
app.UseYiApiHandlinge();
2023-12-28 20:24:49 +08:00
//静态资源
app.UseStaticFiles("/api/app/wwwroot");
app.UseDefaultFiles();
app.UseDirectoryBrowser("/api/app/wwwroot");
2023-12-11 21:14:12 +08:00
// app.Properties.Add("_AbpExceptionHandlingMiddleware_Added",false);
2023-12-11 21:14:12 +08:00
//工作单元
2023-12-11 09:55:12 +08:00
app.UseUnitOfWork();
2023-12-11 21:14:12 +08:00
//授权
2023-12-11 09:55:12 +08:00
app.UseAuthorization();
2023-12-11 21:14:12 +08:00
//审计日志
2023-12-11 09:55:12 +08:00
app.UseAuditing();
2023-12-11 21:14:12 +08:00
//日志记录
2023-12-11 09:55:12 +08:00
app.UseAbpSerilogEnrichers();
2023-12-11 21:14:12 +08:00
//终节点
2023-12-11 09:55:12 +08:00
app.UseConfiguredEndpoints();
return Task.CompletedTask;
}
}
2024-08-14 12:50:28 +08:00
}