【问题标题】:How to setup ClientCredentials flow with swagger UI and workaround options preflight issue (CORS)如何使用 swagger UI 和解决方法选项预检问题 (CORS) 设置 ClientCredentials 流
【发布时间】:2020-11-12 22:05:01
【问题描述】:

我有一个使用 swagger 库的 asp.net 核心应用程序

<PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />

我希望允许使用 /swagger 网页的 api 开发人员能够使用“ClientCredentials”流程获取令牌。 我已经尝试了以下方法,但遇到了选项预检问题

        c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
        {
            Type = SecuritySchemeType.OAuth2,
            Flows = new OpenApiOAuthFlows
            {
                ClientCredentials = new OpenApiOAuthFlow
                {
                    TokenUrl = new Uri(baseAuthURL + "/oauth2/v2.0/token"),
                    Scopes = new Dictionary<string, string>
                    {
                        { "ABC/.default", "Access read operations" }
                    },
                    AuthorizationUrl = new Uri(baseAuthURL + "/oauth2/authorize")
                }
            }
        });

当我点击授权时

在查看控制台时,这是我所看到的

访问获取 来自来源的“https://login.microsoftonline.com/ABCD/oauth2/v2.0/token” “https://localhost:44312”已被 CORS 策略阻止:否 请求中存在“Access-Control-Allow-Origin”标头 资源。如果不透明的响应满足您的需求,请设置请求的 模式为“no-cors”以获取禁用 CORS 的资源。

我该如何解决这个问题?究竟需要对“AddSecurityDefinition”进行哪些更改才能解决此问题?这是我什至可以解决的问题吗? (假设身份提供者可以支持选项预检请求)

是创建反向代理的唯一解决方法吗?

如何扩展上述代码以在请求中发送自定义 HTTP 请求标头?

我已经在网上搜索了几个小时有人成功使用 ClientCredentials 流在 swaggerUI 中获取 oauth 令牌的示例。

更新 1: 非常奇怪的是,即使选项预检请求正在接收带有标头的响应 访问控制允许来源:* 如果我使用 chrome 扩展将此值覆盖为完全相同的值,它可以解决该问题。它显然不是一个解决方案,而是更多的观察。将值设置为完全相同的值会以某种方式改变结果,这很奇怪。

以下是响应标头的差异。左侧没有任何镀铬扩展,右侧镀铬扩展覆盖到完全相同的值。你可以看到没有区别。那么,为什么浏览器会以不同的方式对待它呢?

我还尝试使用 AWS API Gateway 添加授权 api 代理,您可以看到下面设置的响应标头。这也不起作用。

【问题讨论】:

  • 你解决了吗?

标签: asp.net-core oauth swagger


【解决方案1】:

我必须通读 NET Core CORS 文档:https://docs.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-3.1#preflight-requests-1

浏览器在设置 Access-Control-Request-Headers 的方式上并不一致。如果是:

  • 标题设置为“*”以外的任何内容
  • AllowAnyHeader 被调用:至少包括 Accept、Content-Type 和 Origin,以及您想要支持的任何自定义标头。

... 和 Swagger 文档:https://swagger.io/docs/open-source-tools/swagger-ui/usage/cors/

在我的类似情况下,我必须使用此配置在 API 中启用 CORS(注意标头):

        services.AddCors(options =>
        {
            options.AddPolicy(CorsPolicyName, configure =>
            {
                configure
                    .WithHeaders(
                       //Microsoft minimum set recommended 
                       "Accept", "Content-Type", "Origin", 
                       //Swagger headers
                       "api_key", "authorization", "x-requested-with" )
                    .WithOrigins(...);
            });
        });

您也可以允许使用任何标头,这是一种综合解决方案与暴露/安全性之间的折衷

【讨论】:

    【解决方案2】:

    将此添加到您在 Starup 中的服务配置中:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy("AnyOrigin", builder =>
            {
                builder =>                              
                    builder.WithOrigins("https://login.microsoftonline.com")
                        .AllowAnyMethod()
                        .AllowAnyHeader()
                        .AllowCredentials());
            });
        });
    }
    

    然后这是你的应用程序配置:

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env
    {
        // after routing / mvc
        app.UseCors("AnyOrigin");
    }
    

    请注意,您发送的是授权标头,因此是凭据请求,并且会转换为 Access-Control-Allow-Credentials CORS 标头。端点需要返回 200 OK,这应该可以工作。

    有关 SwaggerUI 的更多帮助,以下是有用的资源:@​​987654321@

    【讨论】:

    • 您能否解释一下这将如何解决上述问题?在上面,您可以看到预检将转到一个单独的 url,而不是 api..
    • 更新了我的答案以更具体地满足您的要求。
    • 您尚未将跨域预检选项请求发送到其他域。
    • 您能否验证一下您可以在使用两个不同的域时完成此操作?
    • @jbooker 你能解决这个问题吗?
    猜你喜欢
    • 1970-01-01
    • 2021-10-09
    • 1970-01-01
    • 2019-12-29
    • 2019-08-10
    • 1970-01-01
    • 2019-10-21
    • 2017-10-12
    • 1970-01-01
    相关资源
    最近更新 更多