欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-07-11 10:03:38
这篇文章介绍如何允许跨域访问 浏览器安全不允许不同域名的网页之间发送请求。这种限制叫做同源策略(the same-origin policy)。 同源策略可以防止一个恶意的站点读取另一个站点的敏感数据。 有时候,你想允许网站发送跨域的请求到你的应用。 Cross Origin Resource Sh ......

 

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

 

浏览器安全不允许不同域名的网页之间发送请求。这种限制叫做同源策略(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,这里先暂时不做讲解

 

 

...未完,待续