You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
544 lines
19 KiB
544 lines
19 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.AspNetCore.Cors;
|
|
using Microsoft.AspNetCore.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Hosting;
|
|
using Shentun.Peis.EntityFrameworkCore;
|
|
using Shentun.Peis.MultiTenancy;
|
|
using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite;
|
|
using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite.Bundling;
|
|
using Microsoft.OpenApi.Models;
|
|
using OpenIddict.Validation.AspNetCore;
|
|
using Volo.Abp;
|
|
using Volo.Abp.Account;
|
|
using Volo.Abp.Account.Web;
|
|
using Volo.Abp.AspNetCore.MultiTenancy;
|
|
using Volo.Abp.AspNetCore.Mvc;
|
|
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
|
|
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared;
|
|
using Volo.Abp.AspNetCore.Serilog;
|
|
using Volo.Abp.Autofac;
|
|
using Volo.Abp.Localization;
|
|
using Volo.Abp.Modularity;
|
|
using Volo.Abp.Swashbuckle;
|
|
using Volo.Abp.UI.Navigation.Urls;
|
|
using Volo.Abp.VirtualFileSystem;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Options;
|
|
using System.Reflection;
|
|
using Swashbuckle.AspNetCore.SwaggerGen;
|
|
using Microsoft.AspNetCore.Mvc.Filters;
|
|
using Volo.Abp.AspNetCore.Mvc.Validation;
|
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
|
using Volo.Abp.Identity;
|
|
using Microsoft.Extensions.FileProviders;
|
|
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
|
using Volo.Abp.Settings;
|
|
using Volo.Abp.Identity.Settings;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using Volo.Abp.AspNetCore.Mvc.AntiForgery;
|
|
using Microsoft.AspNetCore.Authentication;
|
|
using Nito.Disposables.Internals;
|
|
using Volo.Abp.AspNetCore.Mvc.ExceptionHandling;
|
|
using static IdentityModel.ClaimComparer;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Diagnostics;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Shentun.Peis.Filter;
|
|
using Shentun.Peis.VirtualPath;
|
|
using System.Text.Encodings.Web;
|
|
using System.Text.Unicode;
|
|
using Volo.Abp.Json;
|
|
using Shentun.Utilities;
|
|
using Volo.Abp.SecurityLog;
|
|
using Volo.Abp.Auditing;
|
|
|
|
namespace Shentun.Peis;
|
|
[DependsOn(
|
|
typeof(PeisHttpApiModule),
|
|
typeof(AbpAutofacModule),
|
|
typeof(AbpAspNetCoreMultiTenancyModule),
|
|
typeof(PeisApplicationModule),
|
|
typeof(PeisEntityFrameworkCoreModule),
|
|
typeof(AbpAspNetCoreMvcUiLeptonXLiteThemeModule),
|
|
typeof(AbpAccountWebOpenIddictModule),
|
|
typeof(AbpAspNetCoreSerilogModule),
|
|
typeof(AbpSwashbuckleModule)
|
|
)]
|
|
public class PeisHttpApiHostModule : AbpModule
|
|
{
|
|
|
|
public override void PreConfigureServices(ServiceConfigurationContext context)
|
|
{
|
|
PreConfigure<OpenIddictBuilder>(builder =>
|
|
{
|
|
builder.AddValidation(options =>
|
|
{
|
|
options.AddAudiences("Peis");
|
|
options.UseLocalServer();
|
|
options.UseAspNetCore();
|
|
});
|
|
});
|
|
|
|
//重写定义token失效时间 接口返回的是秒
|
|
PreConfigure<OpenIddictServerBuilder>(builder =>
|
|
{
|
|
//builder.SetAccessTokenLifetime(TimeSpan.FromHours(8)).SetRefreshTokenLifetime(TimeSpan.FromDays(15));
|
|
builder.SetAccessTokenLifetime(TimeSpan.FromDays(30)).SetRefreshTokenLifetime(TimeSpan.FromDays(60));
|
|
});
|
|
|
|
|
|
}
|
|
|
|
public override void ConfigureServices(ServiceConfigurationContext context)
|
|
{
|
|
var configuration = context.Services.GetConfiguration();
|
|
var hostingEnvironment = context.Services.GetHostingEnvironment();
|
|
|
|
ConfigureAuthentication(context);
|
|
ConfigureBundles();
|
|
ConfigureUrls(configuration);
|
|
ConfigureConventionalControllers();
|
|
ConfigureLocalization();
|
|
ConfigureVirtualFileSystem(context);
|
|
ConfigureCors(context, configuration);
|
|
ConfigureSwaggerServices(context, configuration);
|
|
|
|
ConfigureJsonOptions(); //全局配置api返回值中的日期默认格式
|
|
|
|
//密码策略配置
|
|
context.Services.Configure<IdentityOptions>(opt =>
|
|
{
|
|
opt.Password.RequireDigit = false;
|
|
opt.Password.RequireLowercase = false;
|
|
opt.Password.RequireUppercase = false;
|
|
opt.Password.RequireNonAlphanumeric = false;
|
|
opt.Password.RequiredLength = 1;
|
|
});
|
|
|
|
//密码策略配置
|
|
context.Services.Configure<IdentityOptions>(opt =>
|
|
{
|
|
opt.Password.RequireDigit = false;
|
|
opt.Password.RequireLowercase = false;
|
|
opt.Password.RequireUppercase = false;
|
|
opt.Password.RequireNonAlphanumeric = false;
|
|
opt.Password.RequiredLength = 1;
|
|
});
|
|
|
|
#region 临时去掉日志
|
|
//关闭审计日志
|
|
Configure<AbpAuditingOptions>(options =>
|
|
{
|
|
options.IsEnabled = false;
|
|
});
|
|
//关闭安全日志
|
|
Configure<AbpSecurityLogOptions>(options =>
|
|
{
|
|
options.IsEnabled = false;
|
|
});
|
|
#endregion
|
|
|
|
//防伪令牌
|
|
//context.Services.Configure<AbpAntiForgeryOptions>(opt =>
|
|
//{
|
|
// opt.AutoValidate = false;
|
|
//});
|
|
|
|
context.Services.AddMvc(options =>
|
|
{
|
|
var filterMetadata = options.Filters.FirstOrDefault(x => x is ServiceFilterAttribute attribute && attribute.ServiceType.Equals(typeof(AbpValidationActionFilter)));
|
|
options.Filters.Remove(filterMetadata);
|
|
|
|
options.Filters.Add(typeof(ValidateFilter));
|
|
|
|
|
|
options.Filters.Add(typeof(CustomerExceptionFilterAttribute));
|
|
options.Filters.Add(typeof(CustomerActionFilterAttribute));
|
|
|
|
|
|
|
|
// options.Filters.ReplaceOne(x => (x as ServiceFilterAttribute)?.ServiceType?.Name == nameof(ExceptionFilterAttribute), new ServiceFilterAttribute(typeof(ABCExceptionFilterAttribute)));
|
|
|
|
// options.Filters.ReplaceOne(x => (x as ServiceFilterAttribute)?.ServiceType?.Name == nameof(AbpExceptionFilter), new ServiceFilterAttribute(typeof(MyExceptionFilter)));
|
|
|
|
});
|
|
|
|
//context.Services.TryAddTransient<IAuthorizationMiddlewareResultHandler, AuthorizationMiddlewareResultHandler>();
|
|
|
|
///解除https限制
|
|
context.Services.AddOpenIddict()
|
|
.AddServer(option =>
|
|
{
|
|
option.UseAspNetCore().DisableTransportSecurityRequirement();
|
|
});
|
|
|
|
|
|
//虚拟目录
|
|
context.Services.AddSingleton(new MyFileProvider(configuration["VirtualPath:RealPath"], configuration["VirtualPath:Alias"]));
|
|
|
|
/*
|
|
Configure<AbpAspNetCoreMvcOptions>(options =>
|
|
{
|
|
options.ConventionalControllers
|
|
.Create(typeof(PeisApplicationModule).Assembly, opts =>
|
|
{
|
|
opts.RootPath = "api/app";
|
|
opts.UrlControllerNameNormalizer = (controller) =>
|
|
{
|
|
return controller.ControllerName;
|
|
};
|
|
|
|
opts.UrlActionNameNormalizer = (action) =>
|
|
{
|
|
|
|
return action.Action.ActionName;
|
|
};
|
|
|
|
});
|
|
});
|
|
*/
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 全局转换日期格式
|
|
/// </summary>
|
|
private void ConfigureJsonOptions()
|
|
{
|
|
//context.Services.AddControllers().AddJsonOptions(options =>
|
|
//{
|
|
// options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);
|
|
// options.JsonSerializerOptions.PropertyNamingPolicy = null;
|
|
//});
|
|
Configure<JsonOptions>(x =>
|
|
{
|
|
//x.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);
|
|
x.JsonSerializerOptions.Converters.Add(new DateTimeJsonConverter());
|
|
x.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
|
|
|
|
});
|
|
|
|
//Configure<AbpJsonOptions>(x =>
|
|
//{
|
|
// x.DefaultDateTimeFormat = "yyyy-MM-dd HH:mm:ss";
|
|
//});
|
|
}
|
|
|
|
|
|
|
|
private void ConfigureAuthentication(ServiceConfigurationContext context)
|
|
{
|
|
context.Services.ForwardIdentityAuthenticationForBearer(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme);
|
|
}
|
|
|
|
private void ConfigureBundles()
|
|
{
|
|
Configure<AbpBundlingOptions>(options =>
|
|
{
|
|
options.StyleBundles.Configure(
|
|
LeptonXLiteThemeBundles.Styles.Global,
|
|
bundle =>
|
|
{
|
|
bundle.AddFiles("/global-styles.css");
|
|
}
|
|
);
|
|
});
|
|
}
|
|
|
|
private void ConfigureUrls(IConfiguration configuration)
|
|
{
|
|
Configure<AppUrlOptions>(options =>
|
|
{
|
|
options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"];
|
|
options.RedirectAllowedUrls.AddRange(configuration["App:RedirectAllowedUrls"].Split(','));
|
|
|
|
options.Applications["Angular"].RootUrl = configuration["App:ClientUrl"];
|
|
options.Applications["Angular"].Urls[AccountUrlNames.PasswordReset] = "account/reset-password";
|
|
});
|
|
}
|
|
|
|
private void ConfigureVirtualFileSystem(ServiceConfigurationContext context)
|
|
{
|
|
var hostingEnvironment = context.Services.GetHostingEnvironment();
|
|
|
|
if (hostingEnvironment.IsDevelopment())
|
|
{
|
|
Configure<AbpVirtualFileSystemOptions>(options =>
|
|
{
|
|
options.FileSets.ReplaceEmbeddedByPhysical<PeisDomainSharedModule>(
|
|
Path.Combine(hostingEnvironment.ContentRootPath,
|
|
$"..{Path.DirectorySeparatorChar}Shentun.Peis.Domain.Shared"));
|
|
options.FileSets.ReplaceEmbeddedByPhysical<PeisDomainModule>(
|
|
Path.Combine(hostingEnvironment.ContentRootPath,
|
|
$"..{Path.DirectorySeparatorChar}Shentun.Peis.Domain"));
|
|
options.FileSets.ReplaceEmbeddedByPhysical<PeisApplicationContractsModule>(
|
|
Path.Combine(hostingEnvironment.ContentRootPath,
|
|
$"..{Path.DirectorySeparatorChar}Shentun.Peis.Application.Contracts"));
|
|
options.FileSets.ReplaceEmbeddedByPhysical<PeisApplicationModule>(
|
|
Path.Combine(hostingEnvironment.ContentRootPath,
|
|
$"..{Path.DirectorySeparatorChar}Shentun.Peis.Application"));
|
|
});
|
|
}
|
|
}
|
|
|
|
private void ConfigureConventionalControllers()
|
|
{
|
|
|
|
#region 配置隐藏api
|
|
Configure<MvcOptions>(options =>
|
|
{
|
|
options.Conventions.Add(new ApplicationDescription());
|
|
});
|
|
#endregion
|
|
|
|
Configure<AbpAspNetCoreMvcOptions>(options =>
|
|
{
|
|
options.ConventionalControllers.Create(typeof(PeisApplicationModule).Assembly);
|
|
});
|
|
}
|
|
|
|
private static void ConfigureSwaggerServices(ServiceConfigurationContext context, IConfiguration configuration)
|
|
{
|
|
context.Services.AddAbpSwaggerGenWithOAuth(
|
|
configuration["AuthServer:Authority"],
|
|
new Dictionary<string, string>
|
|
{
|
|
{"Peis", "Peis API"}
|
|
},
|
|
options =>
|
|
{
|
|
//options.SwaggerDoc("v1", new OpenApiInfo { Title = "Peis API", Version = "v1" });
|
|
//options.DocInclusionPredicate((docName, description) => true);
|
|
//options.CustomSchemaIds(type => type.FullName);
|
|
|
|
options.SwaggerDoc("Work", new OpenApiInfo { Title = "业务API", Version = "V1", Description = "业务API" });
|
|
options.SwaggerDoc("Sys", new OpenApiInfo { Title = "底层API", Version = "V1", Description = "底层API" });
|
|
|
|
|
|
options.DocInclusionPredicate((docName, description) =>
|
|
{
|
|
if (!description.TryGetMethodInfo(out MethodInfo method))
|
|
{
|
|
return false;
|
|
}
|
|
/*使用ApiExplorerSettingsAttribute里面的GroupName进行特性标识
|
|
* DeclaringType只能获取controller上的特性
|
|
* 我们这里是想以action的特性为主
|
|
* */
|
|
var version = method.DeclaringType.GetCustomAttributes(true).OfType<ApiExplorerSettingsAttribute>().Select(m => m.GroupName);
|
|
if (version.Any())
|
|
{
|
|
if (version.Any(v => v == docName))
|
|
//选择了sys,并且分组不为User
|
|
return true;
|
|
|
|
}
|
|
else
|
|
{
|
|
if (docName == "Sys")
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
//这里获取action的特性
|
|
var actionVersion = method.GetCustomAttributes(true).OfType<ApiExplorerSettingsAttribute>().Select(m => m.GroupName);
|
|
if (actionVersion.Any())
|
|
{
|
|
return actionVersion.Any(v => v == docName);
|
|
}
|
|
|
|
return false;
|
|
|
|
});
|
|
});
|
|
}
|
|
|
|
private void ConfigureLocalization()
|
|
{
|
|
Configure<AbpLocalizationOptions>(options =>
|
|
{
|
|
options.Languages.Add(new LanguageInfo("ar", "ar", "العربية"));
|
|
options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština"));
|
|
options.Languages.Add(new LanguageInfo("en", "en", "English"));
|
|
options.Languages.Add(new LanguageInfo("en-GB", "en-GB", "English (UK)"));
|
|
options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish"));
|
|
options.Languages.Add(new LanguageInfo("fr", "fr", "Français"));
|
|
options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in"));
|
|
options.Languages.Add(new LanguageInfo("is", "is", "Icelandic", "is"));
|
|
options.Languages.Add(new LanguageInfo("it", "it", "Italiano", "it"));
|
|
options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar"));
|
|
options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português"));
|
|
options.Languages.Add(new LanguageInfo("ro-RO", "ro-RO", "Română"));
|
|
options.Languages.Add(new LanguageInfo("ru", "ru", "Русский"));
|
|
options.Languages.Add(new LanguageInfo("sk", "sk", "Slovak"));
|
|
options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe"));
|
|
options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文"));
|
|
options.Languages.Add(new LanguageInfo("zh-Hant", "zh-Hant", "繁體中文"));
|
|
options.Languages.Add(new LanguageInfo("de-DE", "de-DE", "Deutsch", "de"));
|
|
options.Languages.Add(new LanguageInfo("es", "es", "Español", "es"));
|
|
options.Languages.Add(new LanguageInfo("el", "el", "Ελληνικά"));
|
|
});
|
|
}
|
|
|
|
private void ConfigureCors(ServiceConfigurationContext context, IConfiguration configuration)
|
|
{
|
|
context.Services.AddCors(options =>
|
|
{
|
|
options.AddDefaultPolicy(builder =>
|
|
{
|
|
builder
|
|
.WithOrigins(
|
|
configuration["App:CorsOrigins"]
|
|
.Split(",", StringSplitOptions.RemoveEmptyEntries)
|
|
.Select(o => o.RemovePostFix("/"))
|
|
.ToArray()
|
|
)
|
|
.WithAbpExposedHeaders()
|
|
.SetIsOriginAllowedToAllowWildcardSubdomains()
|
|
.AllowAnyHeader()
|
|
.AllowAnyMethod()
|
|
.AllowCredentials();
|
|
});
|
|
});
|
|
|
|
|
|
|
|
//添加swagger中文注释
|
|
context.Services.AddSwaggerGen(options =>
|
|
{
|
|
|
|
|
|
|
|
//var baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
|
|
|
|
var baseDirectory = AppContext.BaseDirectory;
|
|
//Serilog.Log.Information("swagger地址1:" + baseDirectory);
|
|
//var baseDirectory2 = Path.GetDirectoryName(typeof(Program).Assembly.Location);
|
|
//Serilog.Log.Information("swagger地址2:" + baseDirectory2);
|
|
//var baseDirectory3 = AppDomain.CurrentDomain.BaseDirectory;
|
|
//Serilog.Log.Information("swagger地址3:" + baseDirectory3);
|
|
|
|
var commentsFile = Path.Combine(baseDirectory, "Shentun.Peis.Application.xml");
|
|
options.IncludeXmlComments(commentsFile, true);
|
|
|
|
var commentsFileDro = Path.Combine(baseDirectory, "Shentun.Peis.Application.Contracts.xml");
|
|
options.IncludeXmlComments(commentsFileDro, true);
|
|
|
|
var commentsFileapi = Path.Combine(baseDirectory, "Shentun.Peis.HttpApi.xml");
|
|
options.IncludeXmlComments(commentsFileapi, true);
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
public override void OnApplicationInitialization(ApplicationInitializationContext context)
|
|
{
|
|
var app = context.GetApplicationBuilder();
|
|
var env = context.GetEnvironment();
|
|
var configuration = context.GetConfiguration();
|
|
|
|
//请求错误提示配置
|
|
app.UseErrorHandling();
|
|
|
|
if (env.IsDevelopment())
|
|
{
|
|
app.UseDeveloperExceptionPage();
|
|
}
|
|
|
|
app.UseAbpRequestLocalization();
|
|
|
|
if (!env.IsDevelopment())
|
|
{
|
|
app.UseErrorPage();
|
|
}
|
|
|
|
|
|
|
|
app.UseCorrelationId();
|
|
|
|
//var staticFile = new StaticFileOptions();
|
|
|
|
//var filePath = env.ContentRootPath+"UpLoad\\";
|
|
////var filePath = env.ContentRootPath ;
|
|
//staticFile.FileProvider = new PhysicalFileProvider(filePath);
|
|
|
|
//app.UseStaticFiles(new StaticFileOptions
|
|
//{
|
|
// FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "UpLoad")),
|
|
// RequestPath="/UpLoad"
|
|
//});
|
|
|
|
app.UseStaticFiles();
|
|
|
|
app.UseStaticFiles(new StaticFileOptions
|
|
{
|
|
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "ReportFile")),
|
|
RequestPath = "/ReportFile"
|
|
});
|
|
|
|
app.UseStaticFiles(new StaticFileOptions
|
|
{
|
|
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "UpLoad")),
|
|
RequestPath = "/photo"
|
|
});
|
|
|
|
|
|
|
|
//虚拟目录
|
|
app.UseStaticFiles(new StaticFileOptions
|
|
{
|
|
FileProvider = new PhysicalFileProvider(configuration["VirtualPath:RealPath"]),
|
|
RequestPath = configuration["VirtualPath:RequestPath"]
|
|
});
|
|
|
|
app.UseRouting();
|
|
app.UseCors();
|
|
|
|
|
|
|
|
app.UseAuthentication();
|
|
app.UseAbpOpenIddictValidation();
|
|
|
|
if (MultiTenancyConsts.IsEnabled)
|
|
{
|
|
app.UseMultiTenancy();
|
|
}
|
|
|
|
app.UseUnitOfWork();
|
|
app.UseAuthorization();
|
|
|
|
//app.UseMiddleware(typeof(AuthorizationMiddlewareResultHandler));
|
|
|
|
|
|
app.UseSwagger();
|
|
app.UseAbpSwaggerUI(c =>
|
|
{
|
|
|
|
//c.SwaggerEndpoint("/swagger/v1/swagger.json", "Peis API");
|
|
c.SwaggerEndpoint($"/swagger/Work/swagger.json", "业务API"); //分组显示
|
|
c.SwaggerEndpoint($"/swagger/Sys/swagger.json", "底层API"); //分组显示
|
|
|
|
//c.RoutePrefix = string.Empty; // url 中不显示swagger
|
|
|
|
|
|
var configuration = context.ServiceProvider.GetRequiredService<IConfiguration>();
|
|
c.OAuthClientId(configuration["AuthServer:SwaggerClientId"]);
|
|
c.OAuthScopes("Peis");
|
|
|
|
c.DefaultModelExpandDepth(-1);
|
|
});
|
|
|
|
app.UseAuditing();
|
|
app.UseAbpSerilogEnrichers();
|
|
app.UseConfiguredEndpoints();
|
|
}
|
|
}
|