You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

423 lines
15 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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()
//方法2lamda方法中自定义
//.SetIsOriginAllowed(requestOrigin =>
//{
// //请求源(请求的协议+主机+端口号,比如 http://wwwww.xxxx.com:80)
// var address = requestOrigin;
// //根据请求源自行过滤
// return true;
//})
//方法3WithOrigins方法参数自定义
//.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
}
}