|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Linq;
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
using Microsoft.AspNetCore.Builder;
|
|
|
using Microsoft.AspNetCore.Hosting;
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
using Microsoft.Extensions.Configuration;
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
using Microsoft.Extensions.Hosting;
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
using Microsoft.Extensions.Options;
|
|
|
|
|
|
namespace CorsServer.WebApi31
|
|
|
{
|
|
|
public class Startup
|
|
|
{
|
|
|
public Startup(IConfiguration configuration, IHostEnvironment hostingEnvironment, IWebHostEnvironment webHostEnvironment)
|
|
|
{
|
|
|
Configuration = configuration;
|
|
|
}
|
|
|
|
|
|
public IConfiguration Configuration { get; }
|
|
|
|
|
|
public void ConfigureServices(IServiceCollection services)
|
|
|
{
|
|
|
//Config
|
|
|
services.Configure<CorsOption>(Configuration.GetSection(ApplicationConst.CorsConfigOptionName));
|
|
|
|
|
|
#region CORS
|
|
|
AddCors_Config(services);
|
|
|
//AddCors_Test(services);
|
|
|
//AddCors_2(services);
|
|
|
//AddCors_3(services);
|
|
|
//AddCors_4(services);
|
|
|
//AddCors_5(services);
|
|
|
#endregion
|
|
|
services.AddControllers();
|
|
|
}
|
|
|
|
|
|
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IOptionsSnapshot<CorsOption> corsOtionsSnapshot)
|
|
|
{
|
|
|
if (env.IsDevelopment())
|
|
|
{
|
|
|
app.UseDeveloperExceptionPage();
|
|
|
//app.UseDatabaseErrorPage();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//app.UseExceptionHandler("/Error");
|
|
|
//app.UseHsts();
|
|
|
}
|
|
|
|
|
|
// app.UseHttpsRedirection();
|
|
|
|
|
|
#region 压缩和绑在静态文件
|
|
|
// app.UseResponseCompression();
|
|
|
// app.UseResponseCaching();
|
|
|
#endregion
|
|
|
|
|
|
// app.UseStaticFiles();
|
|
|
|
|
|
// app.UseCookiePolicy();
|
|
|
|
|
|
// 根路径:全局访问前辍 http://www.custom.com/PathBase/
|
|
|
// app.UsePathBase("/api/");
|
|
|
|
|
|
app.UseRouting();
|
|
|
|
|
|
// app.UseRequestLocalization();
|
|
|
|
|
|
// UseRouting() 和 UseAuthentication()之间
|
|
|
// 中间件顺序 https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/middleware/?view=aspnetcore-6.0#middleware-order
|
|
|
app.UseCors(ApplicationConst.DefaultPolicyName);
|
|
|
|
|
|
//app.UseAuthentication();
|
|
|
|
|
|
app.UseAuthorization();
|
|
|
|
|
|
//请在 Cookie策略中间件之后和 MVC中间件之前调用会话中间件。
|
|
|
// app.UseSession();
|
|
|
|
|
|
// app.UseResponseCompression();
|
|
|
|
|
|
// app.UseResponseCaching();
|
|
|
|
|
|
//自定义中间件
|
|
|
|
|
|
app.UseEndpoints(endpoints =>
|
|
|
{
|
|
|
endpoints.MapControllers();
|
|
|
});
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// CORS 模板
|
|
|
/// </summary>
|
|
|
private IServiceCollection AddCors_Template(IServiceCollection services)
|
|
|
{
|
|
|
services.AddCors(setup =>
|
|
|
{
|
|
|
var corsOption = services.BuildServiceProvider().GetRequiredService<IOptionsSnapshot<CorsOption>>().Value;
|
|
|
setup.AddPolicy(ApplicationConst.DefaultPolicyName, build =>
|
|
|
{
|
|
|
build
|
|
|
|
|
|
//请求来源
|
|
|
//方法1:所有请求源
|
|
|
.AllowAnyOrigin()
|
|
|
|
|
|
//方法2:lamda方法中自定义
|
|
|
//.SetIsOriginAllowed(requestOrigin =>
|
|
|
//{
|
|
|
// //请求源(请求的协议+主机+端口号,比如 http://wwwww.xxxx.com:80)
|
|
|
// var address = requestOrigin;
|
|
|
|
|
|
// //根据请求源自行过滤
|
|
|
|
|
|
// return true;
|
|
|
//})
|
|
|
|
|
|
//方法3:WithOrigins方法参数自定义
|
|
|
//.WithOrigins(corsOption.Origins.ToArray())
|
|
|
//允许在WithOrigins方法中使用通配符(*等)
|
|
|
//.SetIsOriginAllowedToAllowWildcardSubdomains()
|
|
|
|
|
|
//请求方法(POST GET PUT DELETE OPTIONS等)
|
|
|
.AllowAnyMethod()
|
|
|
//.WithMethods(corsOption.Methods.ToArray())
|
|
|
|
|
|
//请求头
|
|
|
.AllowAnyHeader()
|
|
|
//.WithHeaders(corsOption.Headers.ToArray())
|
|
|
|
|
|
//凭据
|
|
|
//.AllowCredentials()
|
|
|
//.DisallowCredentials()
|
|
|
|
|
|
//.WithExposedHeaders()
|
|
|
//.SetPreflightMaxAge(TimeSpan.FromMinutes(10))
|
|
|
;
|
|
|
});
|
|
|
});
|
|
|
|
|
|
return services;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 全部设置项说明
|
|
|
/// </summary>
|
|
|
private IServiceCollection AddCors_Info(IServiceCollection services)
|
|
|
{
|
|
|
services.AddCors(setup =>
|
|
|
{
|
|
|
setup.AddPolicy(ApplicationConst.DefaultPolicyName, build =>
|
|
|
{
|
|
|
build
|
|
|
|
|
|
//设置允许跨域的请求来源
|
|
|
.AllowAnyOrigin() //允许任何请求来源
|
|
|
//.SetIsOriginAllowed(_=> true) //使用Func<string bool> 委托方法,自定义是否允许请求源跨域
|
|
|
//.WithOrigins() //允许指定请求来源
|
|
|
//.SetIsOriginAllowedToAllowWildcardSubdomains() //允许WithOrigins()方法,在请求源中使用通配符(*等)
|
|
|
|
|
|
//设置允许跨域的HTTP方法(POST GET PUT DELETE OPTIONS等)
|
|
|
.AllowAnyMethod() //允许所有方法
|
|
|
//.WithMethods() //允许指定方法
|
|
|
|
|
|
//设置允许跨域的请求标头
|
|
|
.AllowAnyHeader() //允许所有请求头
|
|
|
//.WithHeaders() //允许指定请求头
|
|
|
|
|
|
//跨域请求中的凭据
|
|
|
.AllowCredentials() //允许凭据:证书中包含缓存(cookies)和HTTP验证协议(HTTP authentication schemes)
|
|
|
//.DisallowCredentials() //拒绝凭据
|
|
|
|
|
|
//设置公开的非简单响应标头 /设置暴露的自定义响应头(默认情况下,浏览器只会暴露默认的响应头给应用,其它自定义影响头不会暴露给应用程序)
|
|
|
.WithExposedHeaders("x-custom-a", "x-custom-b")
|
|
|
|
|
|
//设置预检过期时间
|
|
|
.SetPreflightMaxAge(TimeSpan.FromMinutes(10)) //此标头指定可缓存对预检请求的响应的时间长度
|
|
|
;
|
|
|
|
|
|
/*特别说明:
|
|
|
出于安全考虑:.net core 2.1开始, AllowAnyOrigin() 和 AllowCredentials() 不能同时使用
|
|
|
解决方案:
|
|
|
1、使用AllowCredentials()时,用.SetIsOriginAllowed(_ => true) 代替 AllowAnyOrigin()
|
|
|
2、使用AllowCredentials()时,用 WithOrigins()指定请求来源(使用SetIsOriginAllowedToAllowWildcardSubdomains()来启用通配符) 代替 AllowAnyOrigin()
|
|
|
3、自定义中间件
|
|
|
*/
|
|
|
});
|
|
|
});
|
|
|
|
|
|
return services;
|
|
|
}
|
|
|
|
|
|
#region 注册不同的Cors策略
|
|
|
|
|
|
/// <summary>
|
|
|
/// 测试
|
|
|
/// </summary>
|
|
|
private IServiceCollection AddCors_Test(IServiceCollection services)
|
|
|
{
|
|
|
services.AddCors(setup =>
|
|
|
{
|
|
|
setup.AddPolicy(ApplicationConst.DefaultPolicyName, build =>
|
|
|
{
|
|
|
build
|
|
|
|
|
|
//请求来源
|
|
|
//.AllowAnyOrigin()
|
|
|
//.WithOrigins()
|
|
|
.SetIsOriginAllowed(requestOrigin =>
|
|
|
{
|
|
|
var cc = requestOrigin;
|
|
|
return true;
|
|
|
})
|
|
|
//.SetIsOriginAllowedToAllowWildcardSubdomains()
|
|
|
|
|
|
//请求方法(POST GET PUT DELETE OPTIONS等)
|
|
|
.AllowAnyMethod()
|
|
|
//.WithMethods()
|
|
|
|
|
|
//请求头
|
|
|
.AllowAnyHeader()
|
|
|
//.WithHeaders()
|
|
|
|
|
|
//凭据
|
|
|
//.AllowCredentials()
|
|
|
//.DisallowCredentials()
|
|
|
|
|
|
//.WithExposedHeaders()
|
|
|
;
|
|
|
});
|
|
|
});
|
|
|
|
|
|
return services;
|
|
|
}
|
|
|
|
|
|
private IServiceCollection AddCors_Single(IServiceCollection services)
|
|
|
{
|
|
|
services.AddCors(setup =>
|
|
|
{
|
|
|
setup.AddPolicy(ApplicationConst.DefaultPolicyName, build =>
|
|
|
{
|
|
|
build
|
|
|
|
|
|
//请求来源
|
|
|
.AllowAnyOrigin()
|
|
|
//.WithOrigins()
|
|
|
//.SetIsOriginAllowed(_ => true)
|
|
|
//.SetIsOriginAllowedToAllowWildcardSubdomains()
|
|
|
|
|
|
//请求方法(POST GET PUT DELETE OPTIONS等)
|
|
|
//.AllowAnyMethod()
|
|
|
//.WithMethods()
|
|
|
|
|
|
//请求头
|
|
|
//.AllowAnyHeader()
|
|
|
//.WithHeaders()
|
|
|
|
|
|
//凭据
|
|
|
//.AllowCredentials()
|
|
|
//.DisallowCredentials()
|
|
|
|
|
|
//.WithExposedHeaders()
|
|
|
;
|
|
|
});
|
|
|
});
|
|
|
|
|
|
return services;
|
|
|
}
|
|
|
|
|
|
private IServiceCollection AddCors_All(IServiceCollection services)
|
|
|
{
|
|
|
services.AddCors(setup =>
|
|
|
{
|
|
|
setup.AddPolicy(ApplicationConst.DefaultPolicyName, build =>
|
|
|
{
|
|
|
build
|
|
|
.AllowAnyOrigin()
|
|
|
.AllowAnyMethod()
|
|
|
.AllowAnyHeader()
|
|
|
;
|
|
|
});
|
|
|
});
|
|
|
|
|
|
return services;
|
|
|
}
|
|
|
|
|
|
private IServiceCollection AddCors_3(IServiceCollection services)
|
|
|
{
|
|
|
services.AddCors(setup =>
|
|
|
{
|
|
|
var corsOption = services.BuildServiceProvider().GetRequiredService<IOptionsSnapshot<CorsOption>>().Value;
|
|
|
setup.AddPolicy(ApplicationConst.DefaultPolicyName, build =>
|
|
|
{
|
|
|
build
|
|
|
.WithOrigins(corsOption.Origins.ToArray())
|
|
|
.WithMethods(corsOption.Methods.ToArray())
|
|
|
.WithHeaders(corsOption.Headers.ToArray())
|
|
|
.WithExposedHeaders(corsOption.ExposedHeaders.ToArray());
|
|
|
});
|
|
|
});
|
|
|
|
|
|
return services;
|
|
|
}
|
|
|
|
|
|
private IServiceCollection AddCors_4(IServiceCollection services)
|
|
|
{
|
|
|
services.AddCors(setup =>
|
|
|
{
|
|
|
setup.AddPolicy(ApplicationConst.DefaultPolicyName, build =>
|
|
|
{
|
|
|
build.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader().WithExposedHeaders("x-custom-error");
|
|
|
});
|
|
|
});
|
|
|
return services;
|
|
|
}
|
|
|
|
|
|
private IServiceCollection AddCors_5(IServiceCollection services)
|
|
|
{
|
|
|
services.AddCors(setup =>
|
|
|
{
|
|
|
var corsOption = services.BuildServiceProvider().GetRequiredService<IOptionsSnapshot<CorsOption>>().Value;
|
|
|
setup.AddPolicy(ApplicationConst.DefaultPolicyName, builder =>
|
|
|
{
|
|
|
builder
|
|
|
////.SetIsOriginAllowedToAllowWildcardSubdomains()
|
|
|
.WithOrigins("http://localhost:5002")
|
|
|
//.AllowAnyMethod()
|
|
|
////.WithMethods(corsOption.Methods.ToArray())
|
|
|
//.AllowAnyHeader()
|
|
|
////.WithHeaders(corsOption.Headers.ToArray())
|
|
|
////.WithExposedHeaders(corsOption.ExposedHeaders.ToArray())
|
|
|
;
|
|
|
});
|
|
|
});
|
|
|
|
|
|
return services;
|
|
|
}
|
|
|
|
|
|
private IServiceCollection AddCors_Config(IServiceCollection services)
|
|
|
{
|
|
|
services.AddCors(setup =>
|
|
|
{
|
|
|
var corsOption = services.BuildServiceProvider().GetRequiredService<IOptionsSnapshot<CorsOption>>().Value;
|
|
|
setup.AddPolicy(ApplicationConst.DefaultPolicyName, builder =>
|
|
|
{
|
|
|
if (corsOption.Origins == null)
|
|
|
{
|
|
|
builder.SetIsOriginAllowed(_ => true);
|
|
|
}
|
|
|
else if (corsOption.Origins.Count == 0)
|
|
|
{
|
|
|
builder.SetIsOriginAllowed(_ => true);
|
|
|
}
|
|
|
else if (corsOption.Origins.Contains("*"))
|
|
|
{
|
|
|
builder.SetIsOriginAllowed(_ => true);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
builder.WithOrigins(corsOption.Origins.ToArray());
|
|
|
builder.SetIsOriginAllowedToAllowWildcardSubdomains();
|
|
|
}
|
|
|
|
|
|
if (corsOption.Methods == null || corsOption.Methods.Count == 0)
|
|
|
{
|
|
|
builder.AllowAnyMethod();
|
|
|
}
|
|
|
else if (corsOption.Methods.Contains("*"))
|
|
|
{
|
|
|
builder.AllowAnyMethod();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
builder.WithMethods(corsOption.Methods.ToArray());
|
|
|
}
|
|
|
|
|
|
if (corsOption.Headers == null || corsOption.Headers.Count == 0)
|
|
|
{
|
|
|
builder.AllowAnyHeader();
|
|
|
}
|
|
|
|
|
|
else if (corsOption.Headers.Contains("*"))
|
|
|
{
|
|
|
builder.AllowAnyHeader();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
builder.WithMethods(corsOption.Headers.ToArray());
|
|
|
}
|
|
|
|
|
|
if (corsOption.ExposedHeaders != null && corsOption.ExposedHeaders.Count > 0)
|
|
|
{
|
|
|
builder.WithExposedHeaders(corsOption.ExposedHeaders.ToArray());
|
|
|
}
|
|
|
|
|
|
if (corsOption.AllowCredentials)
|
|
|
{
|
|
|
builder.AllowCredentials();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
builder.DisallowCredentials();
|
|
|
}
|
|
|
|
|
|
if (corsOption.PreflightMaxAge.TotalSeconds > 0)
|
|
|
{
|
|
|
builder.SetPreflightMaxAge(corsOption.PreflightMaxAge);
|
|
|
}
|
|
|
});
|
|
|
});
|
|
|
|
|
|
return services;
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
}
|
|
|
}
|