From 3630f30cec9883db668b0f9f9d3f536272bb369b Mon Sep 17 00:00:00 2001 From: Dominic Burger Date: Mon, 26 Aug 2024 16:08:51 +0200 Subject: [PATCH] Add authentication in Swagger UI --- CHANGELOG.md | 1 + config/realms/keycloak-geopilot.json | 22 +++++++- docker-compose.yml | 3 ++ src/Geopilot.Api/Program.cs | 51 +++++++++++++++++++ src/Geopilot.Api/appsettings.Development.json | 5 +- 5 files changed, 79 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9ff03e2..1ad9dd68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - Added grid to manage organisations in administration area. - Added grid to manage users in administration area. - Added local Keycloak server for development. +- Added authentication in Swagger UI. ### Changed diff --git a/config/realms/keycloak-geopilot.json b/config/realms/keycloak-geopilot.json index c1ac9c89..571dd886 100644 --- a/config/realms/keycloak-geopilot.json +++ b/config/realms/keycloak-geopilot.json @@ -14,11 +14,29 @@ "alwaysDisplayInConsole": true, "redirectUris": [ "https://localhost:5173", - "http://localhost:5173" + "http://localhost:5173", + "https://localhost:7188/swagger/oauth2-redirect.html", + "http://localhost:5173/swagger/oauth2-redirect.html" ], "webOrigins": [ "https://localhost:5173", - "http://localhost:5173" + "http://localhost:5173", + "https://localhost:7188" + ], + "protocolMappers": [ + { + "name": "geopilot-audience-mapper", + "protocol": "openid-connect", + "protocolMapper": "oidc-audience-mapper", + "consentRequired": false, + "config": { + "included.client.audience": "geopilot-client", + "id.token.claim": "false", + "lightweight.claim": "false", + "access.token.claim": "true", + "introspection.token.claim": "true" + } + } ] } ], diff --git a/docker-compose.yml b/docker-compose.yml index 1cafeb22..cc0ca123 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -65,6 +65,9 @@ services: ReverseProxy__Clusters__stacBrowserCluster__Destinations__stacBrowserDestination__Address: http://stac-browser:8080/ Auth__Authority: http://localhost:4011/realms/geopilot Auth__ClientId: geopilot-client + Auth__AuthorizationUrl: http://localhost:4011/realms/geopilot/protocol/openid-connect/auth + Auth__TokenUrl: http://localhost:4011/realms/geopilot/protocol/openid-connect/token + Auth__ApiOrigin: http://localhost:5173 Validation__InterlisCheckServiceUrl: http://interlis-check-service/ volumes: - ./src/Geopilot.Api/Uploads:/uploads diff --git a/src/Geopilot.Api/Program.cs b/src/Geopilot.Api/Program.cs index 82a7a14a..e7ceef7d 100644 --- a/src/Geopilot.Api/Program.cs +++ b/src/Geopilot.Api/Program.cs @@ -102,6 +102,53 @@ // Workaround for STAC API having multiple actions mapped to the "search" route. options.ResolveConflictingActions(apiDescriptions => apiDescriptions.First()); + + var scopes = new Dictionary + { + { "openid", "Open Id" }, + { "email", "User Email" }, + { "profile", "User Profile" }, + }; + var apiScope = builder.Configuration["Auth:ApiScope"]; + if (apiScope != null) + { + scopes.Add(apiScope, "geopilot API (required)"); + } + + options.AddSecurityDefinition(JwtBearerDefaults.AuthenticationScheme, new OpenApiSecurityScheme + { + Name = "Authorization", + Scheme = JwtBearerDefaults.AuthenticationScheme, + In = ParameterLocation.Header, + Type = SecuritySchemeType.OAuth2, + Flows = new OpenApiOAuthFlows + { + AuthorizationCode = new OpenApiOAuthFlow + { + Scopes = scopes, + AuthorizationUrl = new Uri(builder.Configuration["Auth:AuthorizationUrl"] !), + TokenUrl = new Uri(builder.Configuration["Auth:TokenUrl"] !), + RefreshUrl = new Uri(builder.Configuration["Auth:TokenUrl"] !), + }, + }, + }); + options.AddSecurityRequirement(new OpenApiSecurityRequirement + { + { + new OpenApiSecurityScheme + { + Reference = new OpenApiReference + { + Type = ReferenceType.SecurityScheme, + Id = JwtBearerDefaults.AuthenticationScheme, + }, + Scheme = "oauth2", + Name = JwtBearerDefaults.AuthenticationScheme, + In = ParameterLocation.Header, + }, + Array.Empty() + }, + }); }); builder.Services @@ -189,6 +236,10 @@ app.UseSwaggerUI(options => { options.SwaggerEndpoint("/swagger/v1/swagger.json", "geopilot API v1.0"); + + options.OAuthClientId(builder.Configuration["Auth:ClientId"]); + options.OAuth2RedirectUrl($"{builder.Configuration["Auth:ApiOrigin"]}/swagger/oauth2-redirect.html"); + options.OAuthUsePkce(); }); app.UseHttpsRedirection(); diff --git a/src/Geopilot.Api/appsettings.Development.json b/src/Geopilot.Api/appsettings.Development.json index 2dcb803d..31365e8e 100644 --- a/src/Geopilot.Api/appsettings.Development.json +++ b/src/Geopilot.Api/appsettings.Development.json @@ -1,7 +1,10 @@ { "Auth": { "Authority": "http://localhost:4011/realms/geopilot", - "ClientId": "geopilot-client" + "ClientId": "geopilot-client", + "AuthorizationUrl": "http://localhost:4011/realms/geopilot/protocol/openid-connect/auth", + "TokenUrl": "http://localhost:4011/realms/geopilot/protocol/openid-connect/token", + "ApiOrigin": "https://localhost:7188" }, "Logging": { "LogLevel": {