From fafa5ae02a91837898034a7a1e28d2c7c66bff6a Mon Sep 17 00:00:00 2001
From: bicijinlian <bicijinlian@163.com>
Date: Sat, 1 May 2021 13:47:26 +0800
Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../CorsServer.WebApi31/Config/CorsOption.cs  |  18 +-
 CorsServer/CorsServer.WebApi31/Startup.cs     | 198 +++++++++++++-----
 .../CorsServer.WebApi31/StartupConfig.cs      | 127 +++++++++++
 .../StartupDefaultPolicy.cs                   |  80 +++++++
 .../CorsServer.WebApi31/appsettings.json      |   4 +-
 5 files changed, 364 insertions(+), 63 deletions(-)
 create mode 100644 CorsServer/CorsServer.WebApi31/StartupConfig.cs
 create mode 100644 CorsServer/CorsServer.WebApi31/StartupDefaultPolicy.cs

diff --git a/CorsServer/CorsServer.WebApi31/Config/CorsOption.cs b/CorsServer/CorsServer.WebApi31/Config/CorsOption.cs
index f818116..ba4cacb 100644
--- a/CorsServer/CorsServer.WebApi31/Config/CorsOption.cs
+++ b/CorsServer/CorsServer.WebApi31/Config/CorsOption.cs
@@ -8,23 +8,33 @@ namespace CorsServer.WebApi31
     public class CorsOption
     {
         /// <summary>
-        /// 允许跨域的域名列表
+        /// 允许跨域的请求来源
         /// </summary>
         public List<string> Origins { get; set; }
 
         /// <summary>
-        /// 允许跨域的方法
+        /// 允许跨域的HTTP方法
         /// </summary>
         public List<string> Methods { get; set; }
 
         /// <summary>
-        /// 允许跨域的请求头
+        /// 允许跨域的HTTP请求头
         /// </summary>
         public List<string> Headers { get; set; }
 
         /// <summary>
-        /// 允许跨域的ExposedHeader
+        /// 公开的非简单响应标头
         /// </summary>
         public List<string> ExposedHeaders { get; set; }
+
+        /// <summary>
+        /// 允许跨域请求中的凭据
+        /// </summary>
+        public bool AllowCredentials { get; set; }
+
+        /// <summary>
+        /// 预检过期时间
+        /// </summary>
+        public TimeSpan PreflightMaxAge { get; set; }
     }
 }
diff --git a/CorsServer/CorsServer.WebApi31/Startup.cs b/CorsServer/CorsServer.WebApi31/Startup.cs
index 379a9d8..acadfba 100644
--- a/CorsServer/CorsServer.WebApi31/Startup.cs
+++ b/CorsServer/CorsServer.WebApi31/Startup.cs
@@ -16,7 +16,7 @@ namespace CorsServer.WebApi31
 {
     public class Startup
     {
-        public Startup(IConfiguration configuration,IHostEnvironment hostingEnvironment,IWebHostEnvironment webHostEnvironment)
+        public Startup(IConfiguration configuration, IHostEnvironment hostingEnvironment, IWebHostEnvironment webHostEnvironment)
         {
             Configuration = configuration;
         }
@@ -25,9 +25,9 @@ namespace CorsServer.WebApi31
 
         public void ConfigureServices(IServiceCollection services)
         {
-            #region Config
+            //Config
             services.Configure<CorsOption>(Configuration.GetSection("CORS"));
-            #endregion
+
             #region  CORS
             AddCors_Test(services);
             //AddCors_2(services);
@@ -60,51 +60,6 @@ namespace CorsServer.WebApi31
             });
         }
 
-        /// <summary>
-        /// ȫ��������˵��
-        /// </summary>
-        private IServiceCollection AddCors_Info(IServiceCollection services)
-        {
-            services.AddCors(setup =>
-            {
-                setup.AddPolicy(CorsPolicyNameConst.DefaultPolicyName, build =>
-                {
-                    build
-
-                    //������Դ
-                    .AllowAnyOrigin()                               //�����κ�������Դ
-                    //.WithOrigins()                                //����ָ��������Դ
-                    .SetIsOriginAllowed(_ => true)            //ʹ��Func<string bool> ί�з�����ȷ���Ƿ���������Դ����
-                    .SetIsOriginAllowedToAllowWildcardSubdomains()  //��������Դ��ʹ��ͨ���(*��) 
-
-                    //���󷽷�(POST GET PUT DELETE OPTIONS��)
-                    .AllowAnyMethod()                               //���������
-                    //.WithMethods()                                //����ָ������
-
-                    //����ͷ
-                    .AllowAnyHeader()                               //������������ͷ
-                    //.WithHeaders()                                //����ָ������ͷ
-                    
-                    //ƾ��
-                    .AllowCredentials()                             //����ƾ�ݣ�֤���а�������(cookies)��HTTP��֤Э��(HTTP authentication schemes)
-                    //.DisallowCredentials()                        //�ܾ�ƾ��
-
-                    //.WithExposedHeaders()                         //���ñ�¶���Զ�����Ӧͷ��Ĭ������£������ֻ�ᱩ¶Ĭ�ϵ���Ӧͷ��Ӧ�ã������Զ���Ӱ��ͷ���ᱩ¶��Ӧ�ó���
-                   ;
-
-                    /*�ر�˵����
-                      ���ڰ�ȫ���ǣ�.net core 2.1��ʼ, AllowAnyOrigin() �� AllowCredentials() ����ͬʱʹ��
-                      ���������
-                                1��ʹ��AllowCredentials()ʱ����.SetIsOriginAllowed(_ => true) ���� AllowAnyOrigin()
-                                2��ʹ��AllowCredentials()ʱ���� WithOrigins()ָ��������Դ(ʹ��SetIsOriginAllowedToAllowWildcardSubdomains()������ͨ���) ���� AllowAnyOrigin()
-                                3���Զ����м��
-                     */
-                });
-            });
-
-            return services;
-        }
-
         /// <summary>
         /// CORS �
         /// </summary>
@@ -118,8 +73,10 @@ namespace CorsServer.WebApi31
                     build
 
                     //������Դ
+                    //����1����������Դ
                     .AllowAnyOrigin()
-                    //.WithOrigins(corsOption.Origins.ToArray())
+
+                    //����2��lamda�������Զ���
                     //.SetIsOriginAllowed(requestOrigin => 
                     //{
                     //    //����Դ(�����Э��+����+�˿ںţ����� http://wwwww.xxxx.com:80)
@@ -129,6 +86,10 @@ namespace CorsServer.WebApi31
 
                     //    return true;
                     //})
+
+                    //����3��WithOrigins���������Զ���
+                    //.WithOrigins(corsOption.Origins.ToArray())
+                    //������WithOrigins������ʹ��ͨ���(*��)
                     //.SetIsOriginAllowedToAllowWildcardSubdomains()
 
                     //���󷽷�(POST GET PUT DELETE OPTIONS��)
@@ -144,6 +105,7 @@ namespace CorsServer.WebApi31
                     //.DisallowCredentials()
 
                     //.WithExposedHeaders()
+                    //.SetPreflightMaxAge(TimeSpan.FromMinutes(10))
                    ;
                 });
             });
@@ -151,6 +113,57 @@ namespace CorsServer.WebApi31
             return services;
         }
 
+        /// <summary>
+        /// ȫ��������˵��
+        /// </summary>
+        private IServiceCollection AddCors_Info(IServiceCollection services)
+        {
+            services.AddCors(setup =>
+            {
+                setup.AddPolicy(CorsPolicyNameConst.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>
@@ -165,7 +178,7 @@ namespace CorsServer.WebApi31
                     //������Դ
                     //.AllowAnyOrigin()
                     //.WithOrigins()
-                    .SetIsOriginAllowed(requestOrigin => 
+                    .SetIsOriginAllowed(requestOrigin =>
                     {
                         var cc = requestOrigin;
                         return true;
@@ -202,16 +215,16 @@ namespace CorsServer.WebApi31
 
                      //������Դ
                      .AllowAnyOrigin()
-                     //.WithOrigins()
-                     //.SetIsOriginAllowed(_ => true)
-                     //.SetIsOriginAllowedToAllowWildcardSubdomains()
+                    //.WithOrigins()
+                    //.SetIsOriginAllowed(_ => true)
+                    //.SetIsOriginAllowedToAllowWildcardSubdomains()
 
-                     //���󷽷�(POST GET PUT DELETE OPTIONS��)
-                     //.AllowAnyMethod()
-                     //.WithMethods()
+                    //���󷽷�(POST GET PUT DELETE OPTIONS��)
+                    //.AllowAnyMethod()
+                    //.WithMethods()
 
-                     //����ͷ
-                     //.AllowAnyHeader()
+                    //����ͷ
+                    //.AllowAnyHeader()
                     //.WithHeaders()
 
                     //ƾ��
@@ -294,5 +307,74 @@ namespace CorsServer.WebApi31
 
             return services;
         }
+
+        private IServiceCollection AddCors_Config(IServiceCollection services)
+        {
+            services.AddCors(setup =>
+              {
+                  var corsOption = services.BuildServiceProvider().GetRequiredService<IOptionsSnapshot<CorsOption>>().Value;
+                  setup.AddPolicy(CorsPolicyNameConst.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
+                      {
+                          builder.WithMethods(corsOption.Methods.ToArray());
+                      }
+
+                      if (corsOption.Headers == null || corsOption.Headers.Count == 0)
+                      {
+                          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
     }
 }
diff --git a/CorsServer/CorsServer.WebApi31/StartupConfig.cs b/CorsServer/CorsServer.WebApi31/StartupConfig.cs
new file mode 100644
index 0000000..805b106
--- /dev/null
+++ b/CorsServer/CorsServer.WebApi31/StartupConfig.cs
@@ -0,0 +1,127 @@
+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 StartupConfig
+    {
+        public StartupConfig(IConfiguration configuration, IHostEnvironment hostingEnvironment, IWebHostEnvironment webHostEnvironment)
+        {
+            Configuration = configuration;
+        }
+
+        public IConfiguration Configuration { get; }
+
+        public void ConfigureServices(IServiceCollection services)
+        {
+            //Config
+            services.Configure<CorsOption>(Configuration.GetSection("CORS"));
+
+            //Cors�����ļ�ѡ��
+            AddCors_Config(services);
+
+            services.AddControllers();
+        }
+
+        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IOptionsSnapshot<CorsOption> corsOtionsSnapshot)
+        {
+            if (env.IsDevelopment())
+            {
+                app.UseDeveloperExceptionPage();
+            }
+
+            app.UseRouting();
+
+            app.UseCors(CorsPolicyNameConst.DefaultPolicyName);
+
+            app.UseAuthorization();
+
+            app.UseEndpoints(endpoints =>
+            {
+                endpoints.MapControllers();
+            });
+        }
+
+        #region ע�᲻ͬ��Cors����
+
+        private IServiceCollection AddCors_Config(IServiceCollection services)
+        {
+            services.AddCors(setup =>
+              {
+                  var corsOption = services.BuildServiceProvider().GetRequiredService<IOptionsSnapshot<CorsOption>>().Value;
+                  setup.AddPolicy(CorsPolicyNameConst.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
+                      {
+                          builder.WithMethods(corsOption.Methods.ToArray());
+                      }
+
+                      if (corsOption.Headers == null || corsOption.Headers.Count == 0)
+                      {
+                          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
+    }
+}
diff --git a/CorsServer/CorsServer.WebApi31/StartupDefaultPolicy.cs b/CorsServer/CorsServer.WebApi31/StartupDefaultPolicy.cs
new file mode 100644
index 0000000..5070330
--- /dev/null
+++ b/CorsServer/CorsServer.WebApi31/StartupDefaultPolicy.cs
@@ -0,0 +1,80 @@
+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 StartupDefaultPolicy
+    {
+        public StartupDefaultPolicy(IConfiguration configuration, IHostEnvironment hostingEnvironment, IWebHostEnvironment webHostEnvironment)
+        {
+            Configuration = configuration;
+        }
+
+        public IConfiguration Configuration { get; }
+
+        public void ConfigureServices(IServiceCollection services)
+        {
+            //config
+            services.Configure<CorsOption>(Configuration.GetSection("CORS"));
+
+            //Cors
+            AddDefaultCors(services);
+
+            services.AddControllers();
+        }
+
+        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IOptionsSnapshot<CorsOption> corsOtionsSnapshot)
+        {
+            if (env.IsDevelopment())
+            {
+                app.UseDeveloperExceptionPage();
+            }
+
+            //��·����ȫ�ַ���ǰ� http://www.custom.com/PathBase/
+            //app.UsePathBase("/api/");
+
+            app.UseRouting();
+
+            app.UseCors();
+
+            app.UseAuthorization();
+
+            app.UseEndpoints(endpoints =>
+            {
+                endpoints.MapControllers();
+            });
+        }
+
+        /// <summary>
+        /// ����Ĭ�ϲ���Cors
+        /// </summary>
+        private IServiceCollection AddDefaultCors(IServiceCollection services)
+        {
+            services.AddCors(setupCors =>
+            {
+                setupCors.AddDefaultPolicy(build =>
+                {
+                    build
+                    .AllowAnyOrigin()
+                    .AllowAnyMethod()
+                    .AllowAnyHeader()
+                    .SetPreflightMaxAge(TimeSpan.FromMinutes(10))
+                    ;
+                });
+            });
+
+            return services;
+        }
+    }
+}
diff --git a/CorsServer/CorsServer.WebApi31/appsettings.json b/CorsServer/CorsServer.WebApi31/appsettings.json
index 7013fb5..bc33d6e 100644
--- a/CorsServer/CorsServer.WebApi31/appsettings.json
+++ b/CorsServer/CorsServer.WebApi31/appsettings.json
@@ -4,7 +4,9 @@
     "Origins": ["*"],
     "Methods": [ "*" ],
     "Headers": [ "*" ],
-    "ExposedHeaders": ["x-custom-error"]
+    "AllowCredentials": false,
+    "ExposedHeaders": [ "x-custom-error" ],
+    "PreflightMaxAge": "00:20:30"
   },
   "Logging": {
     "LogLevel": {