forked from anjoy8/Blog.Core
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathStartup.cs
More file actions
281 lines (232 loc) · 11.8 KB
/
Startup.cs
File metadata and controls
281 lines (232 loc) · 11.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Autofac.Extras.DynamicProxy;
using AutoMapper;
using Blog.Core.AOP;
using Blog.Core.AuthHelper;
using Blog.Core.Common;
using Blog.Core.Filter;
using Blog.Core.Log;
using log4net;
using log4net.Config;
using log4net.Repository;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using Swashbuckle.AspNetCore.Swagger;
using static Blog.Core.SwaggerHelper.CustomApiVersion;
namespace Blog.Core
{
public class Startup
{
/// <summary>
/// log4net 仓储库
/// </summary>
public static ILoggerRepository repository { get; set; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
//log4net
repository = LogManager.CreateRepository("Blog.Core");
//指定配置文件
XmlConfigurator.Configure(repository, new FileInfo("log4net.config"));
}
public IConfiguration Configuration { get; }
private const string ApiName = "Blog.Core";
// This method gets called by the runtime. Use this method to add services to the container.
public IServiceProvider ConfigureServices(IServiceCollection services)
{
//注入全局异常捕获
services.AddMvc(o =>
{
o.Filters.Add(typeof(GlobalExceptionsFilter));
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
//缓存注入
services.AddScoped<ICaching, MemoryCaching>();//记得把缓存注入!!!
//Redis注入
services.AddScoped<IRedisCacheManager, RedisCacheManager>();
//log日志注入
services.AddSingleton<ILoggerHelper, LogHelper>();
#region Automapper
services.AddAutoMapper(typeof(Startup));
#endregion
#region CORS
//跨域第二种方法,声明策略,记得下边app中配置
services.AddCors(c =>
{
//↓↓↓↓↓↓↓注意正式环境不要使用这种全开放的处理↓↓↓↓↓↓↓↓↓↓
c.AddPolicy("AllRequests", policy =>
{
policy
.AllowAnyOrigin()//允许任何源
.AllowAnyMethod()//允许任何方式
.AllowAnyHeader()//允许任何头
.AllowCredentials();//允许cookie
});
//↑↑↑↑↑↑↑注意正式环境不要使用这种全开放的处理↑↑↑↑↑↑↑↑↑↑
//一般采用这种方法
c.AddPolicy("LimitRequests", policy =>
{
policy
.WithOrigins("http://127.0.0.1:1818", "http://localhost:8080", "http://localhost:8021", "http://localhost:8081", "http://localhost:1818")//支持多个域名端口
.AllowAnyHeader()//Ensures that the policy allows any header.
.AllowAnyMethod();
});
});
//跨域第一种办法,注意下边 Configure 中进行配置
//services.AddCors();
#endregion
#region Swagger
var basePath = Microsoft.DotNet.PlatformAbstractions.ApplicationEnvironment.ApplicationBasePath;
services.AddSwaggerGen(c =>
{
//c.SwaggerDoc("v1", new Info
//{
// Version = "v0.1.0",
// Title = "Blog.Core API",
// Description = "框架说明文档",
// TermsOfService = "None",
// Contact = new Swashbuckle.AspNetCore.Swagger.Contact { Name = "Blog.Core", Email = "Blog.Core@xxx.com", Url = "https://www.jianshu.com/u/94102b59cc2a" }
//});
//遍历出全部的版本,做文档信息展示
typeof(ApiVersions).GetEnumNames().ToList().ForEach(version =>
{
c.SwaggerDoc(version, new Info
{
// {ApiName} 定义成全局变量,方便修改
Version = version,
Title = $"{ApiName} 接口文档",
Description = $"{ApiName} HTTP API " + version,
TermsOfService = "None",
Contact = new Contact { Name = "Blog.Core", Email = "Blog.Core@xxx.com", Url = "https://www.jianshu.com/u/94102b59cc2a" }
});
});
//就是这里
var xmlPath = Path.Combine(basePath, "Blog.Core.xml");//这个就是刚刚配置的xml文件名
c.IncludeXmlComments(xmlPath, true);//默认的第二个参数是false,这个是controller的注释,记得修改
var xmlModelPath = Path.Combine(basePath, "Blog.Core.Model.xml");//这个就是Model层的xml文件名
c.IncludeXmlComments(xmlModelPath);
#region Token绑定到ConfigureServices
//添加header验证信息
//c.OperationFilter<SwaggerHeader>();
var security = new Dictionary<string, IEnumerable<string>> { { "Blog.Core", new string[] { } }, };
c.AddSecurityRequirement(security);
//方案名称“Blog.Core”可自定义,上下一致即可
c.AddSecurityDefinition("Blog.Core", new ApiKeyScheme
{
Description = "JWT授权(数据将在请求头中进行传输) 直接在下框中输入Bearer {token}(注意两者之间是一个空格)\"",
Name = "Authorization",//jwt默认的参数名称
In = "header",//jwt默认存放Authorization信息的位置(请求头中)
Type = "apiKey"
});
#endregion
});
#endregion
//认证
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(o =>
{
o.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,//是否验证Issuer
ValidateAudience = true,//是否验证Audience
ValidateIssuerSigningKey = true,//是否验证IssuerSigningKey
ValidIssuer = "Blog.Core",
ValidAudience = "wr",
ValidateLifetime = true,//是否验证超时 当设置exp和nbf时有效 同时启用ClockSkew
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(JwtHelper.secretKey)),
//注意这是缓冲过期时间,总的有效时间等于这个时间加上jwt的过期时间
ClockSkew = TimeSpan.FromSeconds(30)
};
});
#region Token服务注册
services.AddSingleton<IMemoryCache>(factory =>
{
var cache = new MemoryCache(new MemoryCacheOptions());
return cache;
});
services.AddAuthorization(options =>
{
options.AddPolicy("Client", policy => policy.RequireRole("Client").Build());
options.AddPolicy("Admin", policy => policy.RequireRole("Admin").Build());
//这个写法是错误的,这个是并列的关系,不是或的关系
//options.AddPolicy("AdminOrClient", policy => policy.RequireRole("Admin,Client").Build());
//这个才是或的关系
options.AddPolicy("SystemOrAdmin", policy => policy.RequireRole("Admin", "System"));
});
#endregion
#region AutoFac
//实例化 AutoFac 容器
var builder = new ContainerBuilder();
//注册要通过反射创建的组件
//builder.RegisterType<AdvertisementServices>().As<IAdvertisementServices>();
builder.RegisterType<BlogCacheAOP>();//可以直接替换其他拦截器
//var assemblysServices1 = Assembly.Load("Blog.Core.Services");
var servicesDllFile = Path.Combine(basePath, "Blog.Core.Services.dll");//获取项目绝对路径
var assemblysServices = Assembly.LoadFile(servicesDllFile);//直接采用加载文件的方法
//builder.RegisterAssemblyTypes(assemblysServices).AsImplementedInterfaces();//指定已扫描程序集中的类型注册为提供所有其实现的接口。
builder.RegisterAssemblyTypes(assemblysServices)
.AsImplementedInterfaces()
.InstancePerLifetimeScope()
.EnableInterfaceInterceptors()//引用Autofac.Extras.DynamicProxy;
.InterceptedBy(typeof(BlogCacheAOP));//允许将拦截器服务的列表分配给注册。可以直接替换其他拦截器
var repositoryDllFile = Path.Combine(basePath, "Blog.Core.Repository.dll");
var assemblysRepository = Assembly.LoadFile(repositoryDllFile);
builder.RegisterAssemblyTypes(assemblysRepository).AsImplementedInterfaces();
//将services填充到Autofac容器生成器中
builder.Populate(services);
//使用已进行的组件登记创建新容器
var ApplicationContainer = builder.Build();
#endregion
return new AutofacServiceProvider(ApplicationContainer);//第三方IOC接管 core内置DI容器
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
#region Swagger
app.UseSwagger();
app.UseSwaggerUI(c =>
{
//之前是写死的
//c.SwaggerEndpoint("/swagger/v1/swagger.json", "ApiHelp V1");
//c.RoutePrefix = "";//路径配置,设置为空,表示直接在根域名(localhost:8001)访问该文件,注意localhost:8001/swagger是访问不到的,去launchSettings.json把launchUrl去掉
//根据版本名称倒序 遍历展示
typeof(ApiVersions).GetEnumNames().OrderByDescending(e => e).ToList().ForEach(version =>
{
c.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"{ApiName} {version}");
});
});
#endregion
//app.UseMiddleware<JwtTokenAuth>();//注意此授权方法已经放弃,请使用下边的官方验证方法。但是如果你还想传User的全局变量,还是可以继续使用中间件
app.UseAuthentication();
//跨域第二种方法,之间使用策略
app.UseCors("LimitRequests");//将 CORS 中间件添加到 web 应用程序管线中, 以允许跨域请求。
//跨域第一种版本,请要 services.AddCors();
// app.UseCors(options => options.WithOrigins("http://localhost:8021").AllowAnyHeader()
//.AllowAnyMethod());
app.UseMvc();
}
}
}