Compare commits
15
Commits
1.128.0
...
ad2ea48592
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ad2ea48592 | ||
|
|
bf36bb6bbc | ||
|
|
0a9a459892 | ||
|
|
00d43c8f10 | ||
|
|
f5a69de0a0 | ||
|
|
40a5f94941 | ||
|
|
fc4db32f20 | ||
|
|
9cb4b8264d | ||
|
|
ddd823afab | ||
|
|
a9aa0a675a | ||
|
|
6418d27f5a | ||
|
|
a763e5e40e | ||
|
|
9b15e296df | ||
|
|
1ef5e52ed9 | ||
|
|
f4a615277f |
@@ -3,8 +3,6 @@ using LiteCharms.Features.Api;
|
||||
using LiteCharms.Features.Api.Configuration;
|
||||
using LiteCharms.Features.Api.Sdk;
|
||||
using LiteCharms.Features.Postgres;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace LiteCharms.Features.Extensions;
|
||||
|
||||
@@ -56,9 +54,22 @@ public static class Api
|
||||
|
||||
public static IServiceCollection AddLiteCharmsWebSecurity(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
var certString = configuration["DataProtection:Certificate"] ?? configuration["DataProtection__Certificate"];
|
||||
var certPassword = configuration["DataProtection:Password"] ?? configuration["DataProtection__Password"];
|
||||
|
||||
if (string.IsNullOrEmpty(certString))
|
||||
throw new InvalidOperationException("Data Protection Certificate configuration is missing.");
|
||||
|
||||
var certificate = X509CertificateLoader.LoadPkcs12(Convert.FromBase64String(certString), certPassword);
|
||||
|
||||
services.AddDataProtection().PersistKeysToDbContext<DataProtectionDbContext>()
|
||||
.ProtectKeysWithCertificate(certificate)
|
||||
.SetApplicationName("LiteCharmsApp");
|
||||
|
||||
services.Configure<DataProtectionOptions>(options => options.ApplicationDiscriminator = "LiteCharmsApp");
|
||||
|
||||
services.ConfigureCookieOidcSameSiteSupport();
|
||||
|
||||
var configSection = configuration.GetSection(nameof(LiteCharmsSettings));
|
||||
|
||||
var authOptions = new LiteCharmsSettings();
|
||||
@@ -71,17 +82,26 @@ public static class Api
|
||||
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
|
||||
})
|
||||
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
|
||||
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
|
||||
{
|
||||
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
|
||||
options.Cookie.SameSite = SameSiteMode.Lax;
|
||||
options.Cookie.Name = "LiteCharmsApp.Session";
|
||||
})
|
||||
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
|
||||
{
|
||||
options.Authority = authOptions.Authority;
|
||||
|
||||
options.ClientId = authOptions.ClientId;
|
||||
options.ClientSecret = authOptions.ClientSecret;
|
||||
options.ResponseType = "code";
|
||||
|
||||
options.SaveTokens = true;
|
||||
options.GetClaimsFromUserInfoEndpoint = true;
|
||||
options.CorrelationCookie.SecurePolicy = CookieSecurePolicy.Always;
|
||||
options.CorrelationCookie.SameSite = SameSiteMode.None;
|
||||
|
||||
options.NonceCookie.SecurePolicy = CookieSecurePolicy.Always;
|
||||
options.NonceCookie.SameSite = SameSiteMode.None;
|
||||
|
||||
options.ForwardSignOut = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
|
||||
@@ -114,6 +134,30 @@ public static class Api
|
||||
return services;
|
||||
}
|
||||
|
||||
private static void ConfigureCookieOidcSameSiteSupport(this IServiceCollection services) =>
|
||||
services.Configure<CookiePolicyOptions>(options =>
|
||||
{
|
||||
options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
|
||||
options.OnAppendCookie = cookieContext => CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
|
||||
options.OnDeleteCookie = cookieContext => CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
|
||||
});
|
||||
|
||||
private static void CheckSameSite(HttpContext httpContext, CookieOptions options)
|
||||
{
|
||||
if (options.SameSite == SameSiteMode.None)
|
||||
{
|
||||
bool isSecure = httpContext.Request.IsHttps;
|
||||
|
||||
if (!isSecure && httpContext.Request.Headers.TryGetValue("X-Forwarded-Proto", out var proto))
|
||||
isSecure = string.Equals(proto, "https", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
if (!isSecure && httpContext.Request.Headers.TryGetValue("Forwarded", out var forwarded))
|
||||
isSecure = forwarded.ToString().Contains("proto=https", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
if (!isSecure) options.SameSite = SameSiteMode.Unspecified;
|
||||
}
|
||||
}
|
||||
|
||||
public static IServiceCollection AddLiteCharmsApiSecurity(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
var configSection = configuration.GetSection(nameof(LiteCharmsSettings));
|
||||
|
||||
@@ -11,16 +11,8 @@ public static class Postgres
|
||||
{
|
||||
var connectionString = configuration.GetConnectionString(DataProtectionDbConfigName);
|
||||
|
||||
var dataSourceBuilder = new NpgsqlDataSourceBuilder(connectionString);
|
||||
|
||||
dataSourceBuilder.ConfigureTypeLoading(options => { options.EnableTypeLoading(false); });
|
||||
|
||||
var dataSource = dataSourceBuilder.Build();
|
||||
|
||||
services.AddSingleton(dataSource);
|
||||
|
||||
services.AddPooledDbContextFactory<DataProtectionDbContext>(options =>
|
||||
options.UseNpgsql(dataSource));
|
||||
options.UseNpgsql(connectionString));
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
@@ -197,6 +197,7 @@
|
||||
<!-- Shared Usings -->
|
||||
<ItemGroup>
|
||||
<Using Include="Microsoft.AspNetCore.DataProtection" />
|
||||
<Using Include="System.Security.Cryptography.X509Certificates" />
|
||||
<Using Include="Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage" />
|
||||
<Using Include="System.Text.Json.Serialization" />
|
||||
<Using Include="System.Reflection" />
|
||||
|
||||
Reference in New Issue
Block a user