Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/apps/api/Program.cs
diff options
context:
space:
mode:
authorLeitwolf2026-10-23 08:01:02 +0300
committerGitHub2026-10-23 08:01:02 +0300
commit3481b5fe411fb3aa5898b0965e42cc852f3d690c (patch)
tree4e5f6caf530344fb13f2b892238d1e1b1f89c10c /apps/api/Program.cs
parenta68bb18e2d750fabcbcff985b5fe921d7c828d7e (diff)
parent7f1cb91eb16bc3d7fd78320465c32d5e2f47ec97 (diff)
downloadprogmaweb-3481b5fe411fb3aa5898b0965e42cc852f3d690c.tar.gz
Merge pull request #43 from Progmasoft/feature/progmasoft-credentials
Add Progmasoft OAuth, an OAuth 2.1 and OpenID Connect provider
Diffstat (limited to 'apps/api/Program.cs')
-rw-r--r--apps/api/Program.cs21
1 files changed, 21 insertions, 0 deletions
diff --git a/apps/api/Program.cs b/apps/api/Program.cs
index 31b46a2..aeeff29 100644
--- a/apps/api/Program.cs
+++ b/apps/api/Program.cs
@@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.Google;
using Microsoft.AspNetCore.HttpOverrides;
using Progmasoft.Progmaweb.Api.Accounts;
+using Progmasoft.OAuth;
using Progmasoft.Progmaweb.Api.Security;
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
@@ -18,6 +19,9 @@ AccountStoreKind accountStore = builder.Services.AddAccountStore(
builder.Environment.IsProduction());
builder.Services.AddSingleton<AccountService>();
builder.Services.AddSingleton<SessionService>();
+// Progmasoft OAuth, the OAuth 2.1 and OpenID Connect provider on its own host; see OAuth/OAuthRegistration.cs.
+builder.Services.AddProgmasoftOAuth(builder.Configuration, accountStore, builder.Environment.IsProduction());
+builder.Services.AddAuthorization();
AuthenticationBuilder authentication = builder.Services
.AddAuthentication()
.AddCookie(AccountEndpoints.ExternalCookieScheme, options =>
@@ -66,6 +70,19 @@ builder.Services.AddHealthChecks();
builder.Services.AddRateLimiter(options =>
{
options.RejectionStatusCode = StatusCodes.Status429TooManyRequests;
+ // The OAuth endpoints and the developer portal: generous for real clients, a ceiling for scripted abuse.
+ options.AddPolicy("oauth", context =>
+ {
+ string partition = context.Connection.RemoteIpAddress?.ToString() ?? "unknown";
+ return RateLimitPartition.GetSlidingWindowLimiter(partition, _ => new SlidingWindowRateLimiterOptions
+ {
+ AutoReplenishment = true,
+ PermitLimit = 60,
+ QueueLimit = 0,
+ SegmentsPerWindow = 6,
+ Window = TimeSpan.FromMinutes(1)
+ });
+ });
options.AddPolicy("account-auth", context =>
{
string partition = context.Connection.RemoteIpAddress?.ToString() ?? "unknown";
@@ -99,7 +116,10 @@ if (!app.Environment.IsDevelopment())
app.UseHttpsRedirection();
app.UseMiddleware<SecurityHeadersMiddleware>();
+// Before authentication, where OpenIddict answers its own endpoints: OAuth only on its host, and nothing else there.
+app.UseMiddleware<OAuthHostFilter>();
app.UseAuthentication();
+app.UseAuthorization();
app.UseRateLimiter();
app.UseExceptionHandler();
@@ -111,6 +131,7 @@ app.MapGet("/api/v1/status", () => Results.Ok(new
version = "1.0.0"
}));
app.MapAccountEndpoints();
+app.MapProgmasoftOAuth();
app.Run();