• asp.net core 系列之允许跨域访问(Enable Cross-Origin Requests:CORS)


    这篇文章介绍如何允许跨域访问

    浏览器安全不允许不同域名的网页之间发送请求。这种限制叫做同源策略(the same-origin policy)。

    同源策略可以防止一个恶意的站点读取另一个站点的敏感数据。

    有时候,你想允许网站发送跨域的请求到你的应用。

    Cross Origin Resource Sharing ( CORS ) : 

    • 是一个W3C的标准;即允许放宽同源策略
    • 不是一个安全的功能,CORS 放宽了安全性。允许跨域,会让API更不安全
    • 允许一个服务明确的允许一些跨域请求,而拒绝另外一些
    • 比早些的技术(例如JSONP)更安全,更灵活

    1.那么同源指的是什么呢

    如果两个URLs是同源的,那么它们有相同的协议,主机(域名),端口

    下面两个是同源的URLs:

    • https://example.com/foo.html
    • https://example.com/bar.html

    下面的这些相比于前面的两个URL,有不同的源:

    • https://example.net – Different domain 不同的域名
    • https://www.example.com/foo.html – Different subdomain 不同的子域名
    • http://example.com/foo.html – Different scheme  不同的协议
    • https://example.com:9000/foo.html – Different port    不同的端口号

    IE浏览器考虑同源问题的时候,不会考虑端口号

    2.带策略的CORS 和中间件

    CORS中间件处理跨域请求。下面的代码允许指定的源能对整个应用进行跨域请求

    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
    
        readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
    
        public IConfiguration Configuration { get; }
    
        public void ConfigureServices(IServiceCollection services)
        {
         //AddCors方法的调用会把CORS服务加到应用的服务容器中(service container); services.AddCors(options
    => { options.AddPolicy(MyAllowSpecificOrigins, builder => { builder.WithOrigins("http://example.com", //CorsPolicyBuilder方法可以链式调用方法, "http://www.contoso.com"); }); }); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseHsts(); } app.UseCors(MyAllowSpecificOrigins); //这个代码会把CORS策略通过CORS中间件应用到这个应用的所有终端(endpoints);即把跨域作用到整个应用
    //注意:1.UseCors必须在UseMvc之前被调用;2. URL末尾不能加/ ;这个url指的是
    builder.WithOrigins(url)中的url

    
    
            app.UseHttpsRedirection();
            app.UseMvc();
        }
    }

    这段代码做了下面的操作

    • 设置策略名为_myAllowSpecificOrigins,这个名字是随意取的
    • 调用UseCors 扩展方法来允许跨域
    • 调用带有lambda表达式的 AddCors 方法。lambda表达式取得一个 CorsPlicyBuild对象,进行一些设置

    CorsPolicyBuilder方法可以链式调用方法:

    builder.WithOrigins("http://example.com",
                                    "http://www.contoso.com")
                                    .AllowAnyHeader()
                                    .AllowAnyMethod();

    测试跨域

    3.使用[EnableCors]属性设置允许跨域

    [EnableCors]属性提供了另一种方式设置跨域。即可以只设置选择的终端,而不是所有的终端.

    这里不同于上面的那种方式,上面的方式是应用的所有终端都会被设置允许跨域;

    而这里只是设置了[EnableCors]属性的终端;

    使用[EnableCors]来指定默认的策略,而[EnableCors("{Policy String}")] 指定了特定的策略;

    [EnableCors]属性应用于:

    • Razor Page PageModel
    • Controller
    • Controller action method

    你可以使用[EnableCors]属性应用不同的策略到 controller/page-model/action 中;

    当[EnableCors]属性应用到 controller/page-model/action ,并且CORS在中间件被允许了(指【Enable("{Policy String}")】的方式),这两种策略就都被使用了;

    不推荐结合使用策略;使用[EnableCors]属性或者中间件,而不是在相同的应用中使用两个

    下面的代码给每个方法使用了一种策略

    [Route("api/[controller]")]
    [ApiController]
    public class WidgetController : ControllerBase
    {
        // GET api/values
        [EnableCors("AnotherPolicy")]
        [HttpGet]
        public ActionResult<IEnumerable<string>> Get()
        {
            return new string[] { "green widget", "red widget" };
        }
    
        // GET api/values/5
        [EnableCors]        // Default policy.
        [HttpGet("{id}")]
        public ActionResult<string> Get(int id)
        {
            switch (id)
            {
                case 1:
                    return "green widget";
                case 2:
                    return "red widget";
                default:
                    return NotFound();
            }
        }
    }

    下面的代码创建了一个跨越默认策略和一个名字叫“AnotherPolicy”的策略:

    public class StartupMultiPolicy
    {
        public StartupMultiPolicy(IConfiguration configuration)
        {
            Configuration = configuration;
        }
    
        public IConfiguration Configuration { get; }
    
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors(options =>
            {
                options.AddDefaultPolicy(
                    builder =>
                    {
                       
                        builder.WithOrigins("http://example.com",
                                            "http://www.contoso.com");
                    });
    
                options.AddPolicy("AnotherPolicy",
                    builder =>
                    {
                        builder.WithOrigins("http://www.contoso.com")
                                            .AllowAnyHeader()
                                            .AllowAnyMethod();
                    });
    
            });
    
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        }
    
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }
    
            app.UseHttpsRedirection();
            app.UseMvc();
        }
    }

    另,其实还有[DisableCors]属性可以禁止CORS,这里先暂时不做讲解

    ...未完,待续

  • 相关阅读:
    MySQL四种分区类型
    CentOS下升级MySQL 5.0.* 到5.5
    CentOS5.5使用yum来安装LAMP
    mysql-bin 常见操作
    引爆你的Javascript代码进化
    python读写excel的简单方法demo
    python时间戳数字转为字符串格式表达
    Djang——CSRF verification failed. Request aborted
    Apache部署django
    Qt设置windows系统时间
  • 原文地址:https://www.cnblogs.com/Vincent-yuan/p/10798866.html
Copyright © 2020-2023  润新知