我有一个 API,可提供大部分公开可用的文档列表。它们通过第一方 SPA 出现,并且也可以嵌入其他网站。因此,我需要允许 CORS 中的所有来源。
但是,某些文档受到限制,并且需要身份验证(为此,我在 Authorization
header 中使用不记名 token )。因此,我还必须允许 CORS 中的凭据。 (请注意,只有公共(public)文档才可嵌入,因此嵌入时无需身份验证。)
是否可以在 ASP.NET Core 中进行配置?
- 如果我允许凭据,则不能允许通配符域。
- 如果我不允许凭据,那么据我所知,第一方 SPA 不会向登录用户发送必要的授权。
- 如果我动态允许任何域(使用
SetIsOriginAllowed
并始终返回true
),那么据我所知,如果第三方网站嵌入来自 API 的数据,我就会面临漏洞容易受到 XSS 攻击。
在我看来,我需要的是允许通配符来源无需身份验证,并允许特定(第一方)来源进行身份验证。
如果没有适当的解决方案,但有好的解决方法,请告诉我。
我能想到的可能的解决方法:
- 使用不同的基本 URL 和 CORS 配置部署 API 两次(更复杂的 DevOps)
- 动态允许任何具有凭据的来源(安全问题,请参阅前面的注释)
- 动态允许任何具有凭据的来源,但手动阻止来自非白名单来源的经过身份验证的请求(非标准、黑客行为)
- 禁止 CORS 中的凭据,并为不记名 token (来自 SPA)使用非标准身份验证 header 。这会导致安全问题吗?
如果相关的话,我正在使用 F# 和 Giraffe。
最佳答案
似乎可以使用ICorsPolicyProvider
来实现这一点。
type CorsPolicyProvider(config: IConfiguration) =
let origins = config.GetSection("CORS:Origins").Get<string []>()
let configureCommonAndBuild (builder: CorsPolicyBuilder) =
builder
.AllowAnyMethod()
.AllowAnyHeader()
.SetPreflightMaxAge(TimeSpan.FromMinutes 60.)
.WithExposedHeaders((*...*))
.Build()
let allowCredentialsPolicy =
CorsPolicyBuilder().WithOrigins(origins).AllowCredentials()
|> configureCommonAndBuild
let publicPolicy =
CorsPolicyBuilder().AllowAnyOrigin()
|> configureCommonAndBuild
interface ICorsPolicyProvider with
member _.GetPolicyAsync(ctx: Microsoft.AspNetCore.Http.HttpContext, _policyName: string) =
let policy =
match ctx.TryGetRequestHeader "Origin" with
| Some origin when origins |> Array.contains (origin.ToLowerInvariant()) -> allowCredentialsPolicy
| _ -> publicPolicy
Threading.Tasks.Task.FromResult policy
type Startup(config: IConfiguration) =
member _.ConfigureServices(services: IServiceCollection) : unit =
services
// ...
.AddCors()
.AddSingleton<ICorsPolicyProvider>(CorsPolicyProvider(config))
// ...
member _.Configure(app: IApplicationBuilder) : unit =
app
// ...
.UseCors()
// ...
关于asp.net-core - 在 ASP.NET Core 中设置 CORS,以允许无需身份验证的通配符来源和具有身份验证的白名单域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67803262/