Merge pull request #23 from LD-Reborn/11-add-cors-settings
feat(server): adds CORS settings
This commit is contained in:
@@ -73,6 +73,44 @@ if (settings.Keycloak.IsConfigured)
|
|||||||
|
|
||||||
builder.Services.AddAuthorization();
|
builder.Services.AddAuthorization();
|
||||||
|
|
||||||
|
builder.Services.AddCors(options =>
|
||||||
|
{
|
||||||
|
options.AddDefaultPolicy(policy =>
|
||||||
|
{
|
||||||
|
if (settings.Cors.AllowedOrigins.Contains("*"))
|
||||||
|
{
|
||||||
|
policy.AllowAnyOrigin();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
policy.WithOrigins(settings.Cors.AllowedOrigins);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.Cors.AllowedMethods.Contains("*"))
|
||||||
|
{
|
||||||
|
policy.AllowAnyMethod();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
policy.WithMethods(settings.Cors.AllowedMethods);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.Cors.AllowedHeaders.Contains("*"))
|
||||||
|
{
|
||||||
|
policy.AllowAnyHeader();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
policy.WithHeaders(settings.Cors.AllowedHeaders);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.Cors.AllowCredentials)
|
||||||
|
{
|
||||||
|
policy.AllowCredentials();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
var managementStore = app.Services.GetRequiredService<ManagementStore>();
|
var managementStore = app.Services.GetRequiredService<ManagementStore>();
|
||||||
@@ -87,20 +125,12 @@ if (settings.Keycloak.IsConfigured)
|
|||||||
|
|
||||||
app.UseElmah();
|
app.UseElmah();
|
||||||
|
|
||||||
|
app.UseCors();
|
||||||
|
|
||||||
app.Use(async (context, next) =>
|
app.Use(async (context, next) =>
|
||||||
{
|
{
|
||||||
context.Response.Headers.AccessControlAllowOrigin = "*";
|
|
||||||
context.Response.Headers.AccessControlAllowMethods = "GET, POST, PUT, DELETE, PATCH, OPTIONS";
|
|
||||||
context.Response.Headers.AccessControlAllowHeaders = "Content-Type, Authorization";
|
|
||||||
context.Response.Headers.XFrameOptions = "DENY";
|
context.Response.Headers.XFrameOptions = "DENY";
|
||||||
context.Response.Headers.ContentSecurityPolicy = "frame-ancestors 'none'";
|
context.Response.Headers.ContentSecurityPolicy = "frame-ancestors 'none'";
|
||||||
|
|
||||||
if (HttpMethods.IsOptions(context.Request.Method))
|
|
||||||
{
|
|
||||||
context.Response.StatusCode = StatusCodes.Status204NoContent;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await next();
|
await next();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ internal sealed class ServerSettings
|
|||||||
|
|
||||||
public KeycloakSettings Keycloak { get; init; } = new();
|
public KeycloakSettings Keycloak { get; init; } = new();
|
||||||
|
|
||||||
|
public CorsSettings Cors { get; init; } = new();
|
||||||
|
|
||||||
public static ServerSettings FromConfiguration(IConfiguration configuration)
|
public static ServerSettings FromConfiguration(IConfiguration configuration)
|
||||||
{
|
{
|
||||||
return new ServerSettings
|
return new ServerSettings
|
||||||
@@ -47,6 +49,13 @@ internal sealed class ServerSettings
|
|||||||
true,
|
true,
|
||||||
"Authentication:Keycloak:RequireHttpsMetadata",
|
"Authentication:Keycloak:RequireHttpsMetadata",
|
||||||
"REVERSE_LLAMA_KEYCLOAK_REQUIRE_HTTPS_METADATA")
|
"REVERSE_LLAMA_KEYCLOAK_REQUIRE_HTTPS_METADATA")
|
||||||
|
},
|
||||||
|
Cors = new CorsSettings
|
||||||
|
{
|
||||||
|
AllowedOrigins = ReadStringArray(configuration, ["CORS:AllowedOrigins"]),
|
||||||
|
AllowedMethods = ReadStringArray(configuration, ["CORS:AllowedMethods"]),
|
||||||
|
AllowedHeaders = ReadStringArray(configuration, ["CORS:AllowedHeaders"]),
|
||||||
|
AllowCredentials = ReadBool(configuration, false, "CORS:AllowCredentials")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -77,10 +86,32 @@ internal sealed class ServerSettings
|
|||||||
return bool.TryParse(value, out var parsed) ? parsed : fallback;
|
return bool.TryParse(value, out var parsed) ? parsed : fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string[] ReadStringArray(IConfiguration configuration, params string[] keys)
|
||||||
|
{
|
||||||
|
var value = Read(configuration, keys);
|
||||||
|
if (string.IsNullOrWhiteSpace(value))
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return value.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
||||||
|
}
|
||||||
|
|
||||||
private static string NormalizePath(string path) =>
|
private static string NormalizePath(string path) =>
|
||||||
path.StartsWith('/') ? path : $"/{path}";
|
path.StartsWith('/') ? path : $"/{path}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal sealed class CorsSettings
|
||||||
|
{
|
||||||
|
public string[] AllowedOrigins { get; init; } = ["*"];
|
||||||
|
|
||||||
|
public string[] AllowedMethods { get; init; } = ["*"];
|
||||||
|
|
||||||
|
public string[] AllowedHeaders { get; init; } = ["*"];
|
||||||
|
|
||||||
|
public bool AllowCredentials { get; init; }
|
||||||
|
}
|
||||||
|
|
||||||
internal sealed class KeycloakSettings
|
internal sealed class KeycloakSettings
|
||||||
{
|
{
|
||||||
public string? Authority { get; init; }
|
public string? Authority { get; init; }
|
||||||
|
|||||||
@@ -5,5 +5,11 @@
|
|||||||
"Microsoft.AspNetCore": "Warning"
|
"Microsoft.AspNetCore": "Warning"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"CORS": {
|
||||||
|
"AllowedOrigins": [ "*" ],
|
||||||
|
"AllowedMethods": [ "GET", "POST", "PUT", "DELETE", "PATCH" ],
|
||||||
|
"AllowedHeaders": [ "Content-Type", "Authorization" ],
|
||||||
|
"AllowCredentials": false
|
||||||
|
},
|
||||||
"AllowedHosts": "*"
|
"AllowedHosts": "*"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user