扩展跨域请求,组件可以注册自己的跨域请求处理策略。

This commit is contained in:
Falcon 2024-12-03 14:15:49 +08:00
parent cd93e01074
commit 4d55eba3a8
4 changed files with 146 additions and 0 deletions

View File

@ -0,0 +1,29 @@
namespace Falcon.SugarApi.FalconCors
{
/// <summary>
/// 跨域请求cors参数
/// </summary>
public class CorsOptions
{
/// <summary>
/// 策略名
/// </summary>
public string? PolicyName { get; set; }
/// <summary>
/// 允许通过的方法。
/// </summary>
public string? Methods { get; set; }
/// <summary>
/// 允许通过的请求头
/// </summary>
public string? Headers { get; set; }
/// <summary>
/// 运行通过的源
/// </summary>
public string? Origins { get; set; }
/// <summary>
/// 允许携带凭据
/// </summary>
public bool? AllowCredentials { get; set; }
}
}

View File

@ -0,0 +1,35 @@
using Microsoft.AspNetCore.Cors.Infrastructure;
namespace Falcon.SugarApi.FalconCors
{
/// <summary>
/// CorsPolicy装饰器
/// </summary>
public class CorsPolicyWallpaper:CorsPolicy
{
/// <summary>
/// 通过一个CorsOptions构建CorsPolicy
/// </summary>
/// <param name="options">跨域请求参数</param>
public CorsPolicyWallpaper(CorsOptions? options) {
if(options == null) {
return;
}
if(options.AllowCredentials != null) {
this.SupportsCredentials = options.AllowCredentials.Value;
}
if(options.Headers.IsNotNullOrEmpty()) {
this.Headers.Clear();
options.Headers.SplitToStringList().ForEach(a => this.Headers.Add(a));
}
if(options.Methods.IsNotNullOrEmpty()) {
this.Methods.Clear();
options.Methods.SplitToStringList().ForEach(a => this.Methods.Add(a));
}
if(options.Origins.IsNotNullOrEmpty()) {
this.Origins.Clear();
options.Origins.SplitToStringList().ForEach(a => this.Origins.Add(a));
}
}
}
}

View File

@ -0,0 +1,75 @@
using Falcon.SugarApi.ApiClient;
using Microsoft.AspNetCore.Cors.Infrastructure;
using Microsoft.Extensions.DependencyInjection;
using Npgsql.Replication.PgOutput.Messages;
using System;
namespace Falcon.SugarApi.FalconCors
{
/// <summary>
/// 服务集合方法扩展
/// </summary>
public static class IServiceCollectionExtend
{
/// <summary>
/// 通过cors方式允许所有跨域源通过。Configure中通过app.UseCors("CorsPolicy")运行策略或在控制器中通过EnableCors应用。
/// </summary>
/// <param name="services">服务集合</param>
/// <param name="policyName">策略名称默认CorsPolicy</param>
/// <returns>服务集合</returns>
public static IServiceCollection AllowAny(this IServiceCollection services,string policyName = "CorsPolicy") =>
services.AddCors(options => options.AddPolicy(policyName,builder => {
builder
.AllowAnyMethod()
//.WithMethods("GET","POST","OPTIONS")
.AllowAnyHeader()
.SetIsOriginAllowed(_ => true) // =AllowAnyOrigin()
.AllowCredentials();
}));
/// <summary>
/// 通过cors方式允许所有跨域源通过。Configure中通过app.UseCors("CorsPolicy")运行策略或在控制器中通过EnableCors应用。
/// </summary>
/// <param name="services">服务集合</param>
/// <param name="policyName">策略名称默认CorsPolicy</param>
/// <param name="policyBuilder">策略创建器</param>
/// <returns>服务集合</returns>
public static IServiceCollection AddCorsByAllowAny(
this IServiceCollection services,
string policyName,
Action<CorsPolicyBuilder>? policyBuilder = null) {
if(policyName.IsNullOrEmpty()) {
throw new ArgumentNullException(nameof(policyName));
}
services.AddCors(options => options.AddPolicy(policyName,builder => {
builder
.AllowAnyMethod() //.WithMethods("GET","POST","OPTIONS")
.AllowAnyHeader()
.SetIsOriginAllowed(_ => true) // =AllowAnyOrigin()
.AllowCredentials();
policyBuilder?.Invoke(builder);
}));
return services;
}
/// <summary>
/// 添加跨域配置。
/// </summary>
/// <param name="services">服务集合</param>
/// <param name="options">跨域配置选项</param>
/// <returns>服务集合</returns>
/// <exception cref="ArgumentNullException"></exception>
public static IServiceCollection AddCoreWithOptions(this IServiceCollection services,CorsOptions options) {
if(options == null) {
throw new ArgumentNullException(nameof(options));
}
if(options.PolicyName.IsNullOrEmpty()) {
throw new ArgumentNullException("options.PolicyName");
}
var policy = new CorsOptions();
services.AddCors(op => op.AddPolicy(options.PolicyName,new CorsPolicyWallpaper(options)));
return services;
}
}
}

View File

@ -0,0 +1,7 @@
## cors源认证
组件可以通过注册自己的cors源认证方法来实现访问的控制。
插件可以通过IServiceCollection.AddCoreWithOptions方法注册自己跨域请求策略。
然后在控制器中使用EnableCorsAttribute特性标记特性使用该策略。
如果不使用自己的策略apiservice平台允许所有跨域请求。