From 77115c8946acc08a8b26c76371b4ff763c0f11e8 Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Wed, 21 Oct 2026 10:58:36 +0100 Subject: [PATCH] add api defaults library --- Directory.Packages.props | 25 +-- .../Token/Token.feature.cs | 60 +++--- .../Users/Users.feature.cs | 62 +++---- .../Common/GenericSteps.cs | 2 +- SecurityService/Program.cs | 6 + SecurityService/SecurityService.csproj | 1 + .../Controllers/HomeController.cs | 8 +- SecurityServiceTestUI/Program.cs | 174 +++++++++++------- SecurityServiceTestUI/Startup.cs | 136 -------------- 9 files changed, 200 insertions(+), 274 deletions(-) delete mode 100644 SecurityServiceTestUI/Startup.cs diff --git a/Directory.Packages.props b/Directory.Packages.props index 106e215c..e91a4550 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -3,34 +3,35 @@ true - + - + - - - + + + - + + - + @@ -40,7 +41,7 @@ - + @@ -50,11 +51,11 @@ - - - + + + - + diff --git a/SecurityService.IntegrationTests/Token/Token.feature.cs b/SecurityService.IntegrationTests/Token/Token.feature.cs index 2c656c0c..91b4271f 100644 --- a/SecurityService.IntegrationTests/Token/Token.feature.cs +++ b/SecurityService.IntegrationTests/Token/Token.feature.cs @@ -121,83 +121,83 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa { #line 4 #line hidden - global::Reqnroll.Table table1 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table23 = new global::Reqnroll.Table(new string[] { "Role Name"}); - table1.AddRow(new string[] { + table23.AddRow(new string[] { "Estate"}); - table1.AddRow(new string[] { + table23.AddRow(new string[] { "Merchant"}); #line 6 - await testRunner.GivenAsync("I create the following roles", ((string)(null)), table1, "Given "); + await testRunner.GivenAsync("I create the following roles", ((string)(null)), table23, "Given "); #line hidden - global::Reqnroll.Table table2 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table24 = new global::Reqnroll.Table(new string[] { "Name", "DisplayName", "Description"}); - table2.AddRow(new string[] { + table24.AddRow(new string[] { "estateManagement", "estateManagement Scope", "A scope for estateManagement"}); - table2.AddRow(new string[] { + table24.AddRow(new string[] { "transactionProcessor", "transactionProcessor Scope", "A scope for transactionProcessor"}); - table2.AddRow(new string[] { + table24.AddRow(new string[] { "transactionProcessorAcl", "transactionProcessorAcl Scope", "A scope for transactionProcessorAcl"}); #line 11 - await testRunner.GivenAsync("I create the following api scopes", ((string)(null)), table2, "Given "); + await testRunner.GivenAsync("I create the following api scopes", ((string)(null)), table24, "Given "); #line hidden - global::Reqnroll.Table table3 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table25 = new global::Reqnroll.Table(new string[] { "Name", "DisplayName", "Secret", "Scopes", "UserClaims"}); - table3.AddRow(new string[] { + table25.AddRow(new string[] { "estateManagement", "Estate Managememt REST", "Secret1", "estateManagement", "MerchantId, EstateId, role"}); - table3.AddRow(new string[] { + table25.AddRow(new string[] { "transactionProcessor", "Transaction Processor REST", "Secret1", "transactionProcessor", ""}); - table3.AddRow(new string[] { + table25.AddRow(new string[] { "transactionProcessorAcl", "Transaction Processor ACL REST", "Secret1", "transactionProcessorAcl", "MerchantId, EstateId, role"}); #line 17 - await testRunner.GivenAsync("I create the following api resources", ((string)(null)), table3, "Given "); + await testRunner.GivenAsync("I create the following api resources", ((string)(null)), table25, "Given "); #line hidden - global::Reqnroll.Table table4 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table26 = new global::Reqnroll.Table(new string[] { "ClientId", "Name", "Secret", "Scopes", "GrantTypes"}); - table4.AddRow(new string[] { + table26.AddRow(new string[] { "serviceClient", "Service Client", "Secret1", "estateManagement,transactionProcessor,transactionProcessorAcl", "client_credentials"}); - table4.AddRow(new string[] { + table26.AddRow(new string[] { "merchantClient", "Merchant Client", "Secret1", "transactionProcessorAcl", "password"}); #line 23 - await testRunner.GivenAsync("I create the following clients", ((string)(null)), table4, "Given "); + await testRunner.GivenAsync("I create the following clients", ((string)(null)), table26, "Given "); #line hidden - global::Reqnroll.Table table5 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table27 = new global::Reqnroll.Table(new string[] { "User Name", "Email Address", "Password", @@ -207,7 +207,7 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa "Family Name", "Claims", "Roles"}); - table5.AddRow(new string[] { + table27.AddRow(new string[] { "merchantuser", "", "123456", @@ -218,7 +218,7 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa "EstateId:1,MerchantId:2", "Merchant"}); #line 28 - await testRunner.GivenAsync("I create the following users", ((string)(null)), table5, "Given "); + await testRunner.GivenAsync("I create the following users", ((string)(null)), table27, "Given "); #line hidden } @@ -252,14 +252,14 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa #line 4 await this.FeatureBackgroundAsync(); #line hidden - global::Reqnroll.Table table6 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table28 = new global::Reqnroll.Table(new string[] { "ClientId", "ClientSecret"}); - table6.AddRow(new string[] { + table28.AddRow(new string[] { "serviceClient", "Secret1"}); #line 34 - await testRunner.WhenAsync("I request a client token with the following values", ((string)(null)), table6, "When "); + await testRunner.WhenAsync("I request a client token with the following values", ((string)(null)), table28, "When "); #line hidden #line 37 await testRunner.ThenAsync("my token is returned", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); @@ -299,18 +299,18 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa #line 42 await testRunner.ThenAsync("the user MFA policy operation succeeds", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); #line hidden - global::Reqnroll.Table table7 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table29 = new global::Reqnroll.Table(new string[] { "ClientId", "ClientSecret", "Username", "Password"}); - table7.AddRow(new string[] { + table29.AddRow(new string[] { "merchantClient", "Secret1", "merchantuser", "123456"}); #line 43 - await testRunner.WhenAsync("I request a password token with the following values", ((string)(null)), table7, "When "); + await testRunner.WhenAsync("I request a password token with the following values", ((string)(null)), table29, "When "); #line hidden #line 46 await testRunner.ThenAsync("the password token request fails", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); @@ -321,18 +321,18 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa #line 48 await testRunner.ThenAsync("the user MFA policy operation succeeds", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); #line hidden - global::Reqnroll.Table table8 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table30 = new global::Reqnroll.Table(new string[] { "ClientId", "ClientSecret", "Username", "Password"}); - table8.AddRow(new string[] { + table30.AddRow(new string[] { "merchantClient", "Secret1", "merchantuser", "123456"}); #line 49 - await testRunner.WhenAsync("I request a password token with the following values", ((string)(null)), table8, "When "); + await testRunner.WhenAsync("I request a password token with the following values", ((string)(null)), table30, "When "); #line hidden #line 52 await testRunner.ThenAsync("my token is returned", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); diff --git a/SecurityService.IntegrationTests/Users/Users.feature.cs b/SecurityService.IntegrationTests/Users/Users.feature.cs index cf938452..2e4626fc 100644 --- a/SecurityService.IntegrationTests/Users/Users.feature.cs +++ b/SecurityService.IntegrationTests/Users/Users.feature.cs @@ -113,16 +113,16 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa { #line 4 #line hidden - global::Reqnroll.Table table1 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table31 = new global::Reqnroll.Table(new string[] { "Role Name"}); - table1.AddRow(new string[] { + table31.AddRow(new string[] { "TestRole1"}); - table1.AddRow(new string[] { + table31.AddRow(new string[] { "TestRole2"}); - table1.AddRow(new string[] { + table31.AddRow(new string[] { "TestRole3"}); #line 5 - await testRunner.GivenAsync("I create the following roles", ((string)(null)), table1, "Given "); + await testRunner.GivenAsync("I create the following roles", ((string)(null)), table31, "Given "); #line hidden } @@ -156,7 +156,7 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa #line 4 await this.FeatureBackgroundAsync(); #line hidden - global::Reqnroll.Table table2 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table32 = new global::Reqnroll.Table(new string[] { "Email Address", "Phone Number", "Given Name", @@ -164,7 +164,7 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa "Family Name", "Claims", "Roles"}); - table2.AddRow(new string[] { + table32.AddRow(new string[] { "testuser1@testing.co.uk", "123456789", "Test", @@ -172,7 +172,7 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa "User 1", "", "TestRole1"}); - table2.AddRow(new string[] { + table32.AddRow(new string[] { "testuser2@testing.co.uk", "123456789", "Test", @@ -180,7 +180,7 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa "User 2", "", "TestRole2"}); - table2.AddRow(new string[] { + table32.AddRow(new string[] { "testuser3@testing.co.uk", "123456789", "Test", @@ -189,9 +189,9 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa "", "TestRole3"}); #line 13 - await testRunner.GivenAsync("I create the following users", ((string)(null)), table2, "Given "); + await testRunner.GivenAsync("I create the following users", ((string)(null)), table32, "Given "); #line hidden - global::Reqnroll.Table table3 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table33 = new global::Reqnroll.Table(new string[] { "Email Address", "Phone Number", "Given Name", @@ -200,7 +200,7 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa "Claims", "Roles", "RegistrationDate"}); - table3.AddRow(new string[] { + table33.AddRow(new string[] { "testuser1@testing.co.uk", "123456789", "Test", @@ -211,9 +211,9 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa "Today"}); #line 18 await testRunner.WhenAsync("I get the user with user name \'testuser1@testing.co.uk\' the user details are retu" + - "rned as follows", ((string)(null)), table3, "When "); + "rned as follows", ((string)(null)), table33, "When "); #line hidden - global::Reqnroll.Table table4 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table34 = new global::Reqnroll.Table(new string[] { "Email Address", "Phone Number", "Given Name", @@ -222,7 +222,7 @@ await testRunner.WhenAsync("I get the user with user name \'testuser1@testing.co "Claims", "Roles", "RegistrationDate"}); - table4.AddRow(new string[] { + table34.AddRow(new string[] { "testuser2@testing.co.uk", "123456789", "Test", @@ -233,9 +233,9 @@ await testRunner.WhenAsync("I get the user with user name \'testuser1@testing.co "Today"}); #line 21 await testRunner.WhenAsync("I get the user with user name \'testuser2@testing.co.uk\' the user details are retu" + - "rned as follows", ((string)(null)), table4, "When "); + "rned as follows", ((string)(null)), table34, "When "); #line hidden - global::Reqnroll.Table table5 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table35 = new global::Reqnroll.Table(new string[] { "Email Address", "Phone Number", "Given Name", @@ -244,7 +244,7 @@ await testRunner.WhenAsync("I get the user with user name \'testuser2@testing.co "Claims", "Roles", "RegistrationDate"}); - table5.AddRow(new string[] { + table35.AddRow(new string[] { "testuser3@testing.co.uk", "123456789", "Test", @@ -255,7 +255,7 @@ await testRunner.WhenAsync("I get the user with user name \'testuser2@testing.co "Today"}); #line 24 await testRunner.WhenAsync("I get the user with user name \'testuser3@testing.co.uk\' the user details are retu" + - "rned as follows", ((string)(null)), table5, "When "); + "rned as follows", ((string)(null)), table35, "When "); #line hidden } await this.ScenarioCleanupAsync(); @@ -286,7 +286,7 @@ await testRunner.WhenAsync("I get the user with user name \'testuser3@testing.co #line 4 await this.FeatureBackgroundAsync(); #line hidden - global::Reqnroll.Table table6 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table36 = new global::Reqnroll.Table(new string[] { "Email Address", "Phone Number", "Given Name", @@ -294,7 +294,7 @@ await testRunner.WhenAsync("I get the user with user name \'testuser3@testing.co "Family Name", "Claims", "Roles"}); - table6.AddRow(new string[] { + table36.AddRow(new string[] { "testuser1@testing.co.uk", "123456789", "Test", @@ -302,7 +302,7 @@ await testRunner.WhenAsync("I get the user with user name \'testuser3@testing.co "User 1", "", "TestRole1"}); - table6.AddRow(new string[] { + table36.AddRow(new string[] { "testuser2@testing.co.uk", "123456789", "Test", @@ -310,7 +310,7 @@ await testRunner.WhenAsync("I get the user with user name \'testuser3@testing.co "User 2", "", "TestRole2"}); - table6.AddRow(new string[] { + table36.AddRow(new string[] { "testuser3@testing.co.uk", "123456789", "Test", @@ -318,7 +318,7 @@ await testRunner.WhenAsync("I get the user with user name \'testuser3@testing.co "User 3", "", "TestRole3"}); - table6.AddRow(new string[] { + table36.AddRow(new string[] { "mfauser@testing.co.uk", "123456789", "MFA", @@ -327,7 +327,7 @@ await testRunner.WhenAsync("I get the user with user name \'testuser3@testing.co "", "TestRole1"}); #line 30 - await testRunner.GivenAsync("I create the following users", ((string)(null)), table6, "Given "); + await testRunner.GivenAsync("I create the following users", ((string)(null)), table36, "Given "); #line hidden #line 36 await testRunner.WhenAsync("I require MFA for user \'mfauser@testing.co.uk\'", ((string)(null)), ((global::Reqnroll.Table)(null)), "When "); @@ -347,7 +347,7 @@ await testRunner.WhenAsync("I get the user with user name \'testuser3@testing.co #line 41 await testRunner.ThenAsync("the user MFA policy operation succeeds", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); #line hidden - global::Reqnroll.Table table7 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table37 = new global::Reqnroll.Table(new string[] { "Email Address", "Phone Number", "Given Name", @@ -356,7 +356,7 @@ await testRunner.WhenAsync("I get the user with user name \'testuser3@testing.co "Claims", "Roles", "RegistrationDate"}); - table7.AddRow(new string[] { + table37.AddRow(new string[] { "testuser1@testing.co.uk", "123456789", "Test", @@ -365,7 +365,7 @@ await testRunner.WhenAsync("I get the user with user name \'testuser3@testing.co "emailaddress:testuser1@testing.co.uk, givenname:Test, surname:User 1", "TestRole1", "Today"}); - table7.AddRow(new string[] { + table37.AddRow(new string[] { "testuser2@testing.co.uk", "123456789", "Test", @@ -374,7 +374,7 @@ await testRunner.WhenAsync("I get the user with user name \'testuser3@testing.co "emailaddress:testuser2@testing.co.uk, givenname:Test, surname:User 2", "TestRole2", "Today"}); - table7.AddRow(new string[] { + table37.AddRow(new string[] { "testuser3@testing.co.uk", "123456789", "Test", @@ -383,7 +383,7 @@ await testRunner.WhenAsync("I get the user with user name \'testuser3@testing.co "emailaddress:testuser3@testing.co.uk, givenname:Test, surname:User 3", "TestRole3", "Today"}); - table7.AddRow(new string[] { + table37.AddRow(new string[] { "mfauser@testing.co.uk", "123456789", "MFA", @@ -393,7 +393,7 @@ await testRunner.WhenAsync("I get the user with user name \'testuser3@testing.co "TestRole1", "Today"}); #line 42 - await testRunner.WhenAsync("I get the users 4 users details are returned as follows", ((string)(null)), table7, "When "); + await testRunner.WhenAsync("I get the users 4 users details are returned as follows", ((string)(null)), table37, "When "); #line hidden } await this.ScenarioCleanupAsync(); diff --git a/SecurityService.OpenIdConnect.IntegrationTests/Common/GenericSteps.cs b/SecurityService.OpenIdConnect.IntegrationTests/Common/GenericSteps.cs index 495f811e..b2839903 100644 --- a/SecurityService.OpenIdConnect.IntegrationTests/Common/GenericSteps.cs +++ b/SecurityService.OpenIdConnect.IntegrationTests/Common/GenericSteps.cs @@ -35,7 +35,7 @@ public async Task StartSystem() logger.Initialise(LogManager.GetLogger(scenarioName), scenarioName); LogManager.AddHiddenAssembly(typeof(NlogLogger).Assembly); - DockerServices dockerServices = DockerServices.SecurityService | DockerServices.SqlServer | DockerServices.MessagingService | DockerServices.EventStore; + DockerServices dockerServices = DockerServices.SecurityService | DockerServices.SqlServer | DockerServices.MessagingService | DockerServices.KurrentDb; this.TestingContext.DockerHelper = new DockerHelper(); this.TestingContext.DockerHelper.Logger = logger; diff --git a/SecurityService/Program.cs b/SecurityService/Program.cs index 33ea3105..b275a2a4 100644 --- a/SecurityService/Program.cs +++ b/SecurityService/Program.cs @@ -33,6 +33,7 @@ using Shared.Serialisation; using System.Reflection; using System.Security.Cryptography; +using TransactionProcessing.ApiDefaults; using ILogger = Microsoft.Extensions.Logging.ILogger; using Logger = Shared.Logger.Logger; using LogLevel = Microsoft.Extensions.Logging.LogLevel; @@ -273,6 +274,11 @@ HttpLoggingFields.ResponseStatusCode | HttpLoggingFields.Duration; }); +builder.Services.AddApiDefaults(options => +{ + options.Title = "Security Service"; + options.Description = "API to manage all aspects of application identity and security"; +}); var rsa = RSA.Create(2048); var key = new RsaSecurityKey(rsa); diff --git a/SecurityService/SecurityService.csproj b/SecurityService/SecurityService.csproj index 927bfa32..c79201af 100644 --- a/SecurityService/SecurityService.csproj +++ b/SecurityService/SecurityService.csproj @@ -37,6 +37,7 @@ + diff --git a/SecurityServiceTestUI/Controllers/HomeController.cs b/SecurityServiceTestUI/Controllers/HomeController.cs index fc90c1d1..39fb2c1b 100644 --- a/SecurityServiceTestUI/Controllers/HomeController.cs +++ b/SecurityServiceTestUI/Controllers/HomeController.cs @@ -14,6 +14,12 @@ namespace SecurityServiceTestUI.Controllers public class HomeController : Controller { + private readonly IConfiguration _configuration; + + public HomeController(IConfiguration configuration) + { + _configuration = configuration; + } public IActionResult Index() { return View(); @@ -27,7 +33,7 @@ public IActionResult Privacy() [Authorize] public IActionResult ChangePassword() { - String redirectUri = $"{Startup.Configuration.GetValue("AppSettings:Authority")}/Account/ChangePassword?clientId={Startup.Configuration.GetValue("AppSettings:ClientId")}"; + String redirectUri = $"{_configuration.GetValue("AppSettings:Authority")}/Account/ChangePassword?clientId={_configuration.GetValue("AppSettings:ClientId")}"; return this.Redirect(redirectUri); } diff --git a/SecurityServiceTestUI/Program.cs b/SecurityServiceTestUI/Program.cs index 1eca6b2c..cdc98045 100644 --- a/SecurityServiceTestUI/Program.cs +++ b/SecurityServiceTestUI/Program.cs @@ -1,75 +1,123 @@ -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; using System; -using System.Collections.Generic; +using System.IdentityModel.Tokens.Jwt; +using System.IO; using System.Linq; +using System.Net; +using System.Net.Http; +using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; +using HealthChecks.UI.Client; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.AspNetCore.Diagnostics.HealthChecks; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Server.Kestrel.Core; +using Microsoft.IdentityModel.Tokens; -namespace SecurityServiceTestUI -{ - using System.IO; - using System.Net; - using System.Security.Cryptography.X509Certificates; - using Microsoft.AspNetCore.Server.Kestrel.Core; +var builder = WebApplication.CreateBuilder(args); + +Console.Title = "Security Service Test UI"; + +var hostingConfiguration = new ConfigurationBuilder() + .SetBasePath(builder.Environment.ContentRootPath) + .AddJsonFile("hosting.json", optional: true) + .AddJsonFile("hosting.development.json", optional: true) + .AddEnvironmentVariables() + .Build(); +builder.WebHost.UseConfiguration(hostingConfiguration); - public class Program +builder.Services.AddControllersWithViews(); +builder.Services.AddHealthChecks(); + +JwtSecurityTokenHandler.DefaultMapInboundClaims = false; + +var authority = builder.Configuration.GetValue("AppSettings:Authority"); +var clientId = builder.Configuration.GetValue("AppSettings:ClientId"); +var clientSecret = builder.Configuration.GetValue("AppSettings:ClientSecret"); + +Console.WriteLine($"Authority is {authority}"); + +builder.Services.AddAuthentication(options => + { + options.DefaultScheme = "Cookies"; + options.DefaultChallengeScheme = "oidc"; + }) + .AddCookie("Cookies") + .AddOpenIdConnect("oidc", options => { - public static IHostBuilder CreateHostBuilder(String[] args) + var handler = new HttpClientHandler { - Console.Title = "Security Service Test UI"; - - //At this stage, we only need our hosting file for ip and ports - IConfigurationRoot config = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("hosting.json", optional: true) - .AddJsonFile("hosting.development.json", optional: true).AddEnvironmentVariables().Build(); - - IHostBuilder hostBuilder = Host.CreateDefaultBuilder(args); - hostBuilder.ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - webBuilder.UseConfiguration(config); - - var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); - - //if (environment == "IntegrationTest") - //{ - webBuilder.UseKestrel(options => - { - var port = 5004; - - options.Listen(IPAddress.Any, - port, - listenOptions => - { - // Enable support for HTTP1 and HTTP2 (required if you want to host gRPC endpoints) - listenOptions.Protocols = HttpProtocols.Http1AndHttp2; - // Configure Kestrel to use a certificate from a local .PFX file for hosting HTTPS - listenOptions.UseHttps(Program.LoadCertificate()); - }); - }); - //} - //else - //{ - // webBuilder.UseKestrel(); - //} - }); - return hostBuilder; - } - - private static X509Certificate2 LoadCertificate() + ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator + }; + options.BackchannelHttpHandler = handler; + + options.Authority = authority; + options.TokenValidationParameters = new TokenValidationParameters { - //just to ensure that we are picking the right file! little bit of ugly code: - var files = Directory.GetFiles(Directory.GetCurrentDirectory()); - var certificateFile = files.First(name => name.Contains("pfx")); - Console.WriteLine(certificateFile); + ValidateAudience = false, + }; - return new X509Certificate2(certificateFile, "password"); - } + options.ClientSecret = clientSecret; + options.ClientId = clientId; + options.MetadataAddress = $"{authority}/.well-known/openid-configuration"; + options.ResponseType = "code"; + options.UsePkce = true; - public static void Main(String[] args) + options.Scope.Clear(); + options.Scope.Add("openid"); + options.Scope.Add("profile"); + options.Scope.Add("email"); + options.Scope.Add("offline_access"); + + options.ClaimActions.MapAllExcept("iss", "nbf", "exp", "aud", "nonce", "iat", "c_hash"); + options.GetClaimsFromUserInfoEndpoint = true; + options.SaveTokens = true; + options.Events.OnRedirectToIdentityProvider = context => { - Program.CreateHostBuilder(args).Build().Run(); - } - } + context.ProtocolMessage.IssuerAddress = $"{authority}/connect/authorize"; + return Task.CompletedTask; + }; + }); + +builder.WebHost.ConfigureKestrel(options => +{ + options.Listen(IPAddress.Any, 5004, listenOptions => + { + listenOptions.Protocols = HttpProtocols.Http1AndHttp2; + listenOptions.UseHttps(LoadCertificate()); + }); +}); + +var app = builder.Build(); + +app.UseDeveloperExceptionPage(); +app.UseHttpsRedirection(); +app.UseStaticFiles(); +app.UseRouting(); +app.UseAuthentication(); +app.UseAuthorization(); + +app.MapDefaultControllerRoute(); +app.MapHealthChecks("health", new HealthCheckOptions +{ + Predicate = _ => true, + ResponseWriter = Shared.HealthChecks.HealthCheckMiddleware.WriteResponse +}); +app.MapHealthChecks("healthui", new HealthCheckOptions +{ + Predicate = _ => true, + ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse +}); + +app.Run(); + +static X509Certificate2 LoadCertificate() +{ + var certificateFile = Directory.GetFiles(Directory.GetCurrentDirectory()) + .First(name => name.Contains("pfx", StringComparison.OrdinalIgnoreCase)); + Console.WriteLine(certificateFile); + + return new X509Certificate2(certificateFile, "password"); } diff --git a/SecurityServiceTestUI/Startup.cs b/SecurityServiceTestUI/Startup.cs deleted file mode 100644 index c2f9da6d..00000000 --- a/SecurityServiceTestUI/Startup.cs +++ /dev/null @@ -1,136 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.HttpsPolicy; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace SecurityServiceTestUI -{ - using System.IdentityModel.Tokens.Jwt; - using System.Net.Http; - using HealthChecks.UI.Client; - using Microsoft.AspNetCore.Authentication; - using Microsoft.AspNetCore.Diagnostics.HealthChecks; - using Microsoft.IdentityModel.Tokens; - - public class Startup - { - public Startup(IWebHostEnvironment webHostEnvironment) - { - IConfigurationBuilder builder = new ConfigurationBuilder().SetBasePath(webHostEnvironment.ContentRootPath) - .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) - .AddJsonFile($"appsettings.{webHostEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true) - .AddEnvironmentVariables(); - Startup.Configuration = builder.Build(); - } - - public static IConfigurationRoot Configuration { get; set; } - - // This method gets called by the runtime. Use this method to add services to the container. - public void ConfigureServices(IServiceCollection services) - { - services.AddControllersWithViews(); - - JwtSecurityTokenHandler.DefaultMapInboundClaims = false; - - Console.WriteLine($"Authority is {Configuration.GetValue("AppSettings:Authority")}"); - - services.AddHealthChecks(); - - services.AddAuthentication(options => - { - options.DefaultScheme = "Cookies"; - options.DefaultChallengeScheme = "oidc"; - }) - .AddCookie("Cookies") - .AddOpenIdConnect("oidc", options => - { - HttpClientHandler handler = new HttpClientHandler(); - handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; - options.BackchannelHttpHandler = handler; - - options.Authority = Configuration.GetValue("AppSettings:Authority"); - options.TokenValidationParameters = new TokenValidationParameters - { - ValidateAudience = false, - }; - - options.ClientSecret = - Configuration.GetValue("AppSettings:ClientSecret"); - options.ClientId = Configuration.GetValue("AppSettings:ClientId"); - - options.MetadataAddress = $"{Configuration.GetValue("AppSettings:Authority")}/.well-known/openid-configuration"; - - options.ResponseType = "code"; - options.UsePkce = true; - - options.Scope.Clear(); - options.Scope.Add("openid"); - options.Scope.Add("profile"); - options.Scope.Add("email"); - options.Scope.Add("offline_access"); - - options.ClaimActions.MapAllExcept("iss", - "nbf", - "exp", - "aud", - "nonce", - "iat", - "c_hash"); - - options.GetClaimsFromUserInfoEndpoint = true; - options.SaveTokens = true; - - options.Events.OnRedirectToIdentityProvider = context => - { - // Intercept the redirection so the browser navigates to the right URL in your host - context.ProtocolMessage.IssuerAddress = $"{Configuration.GetValue("AppSettings:Authority")}/connect/authorize"; - return Task.CompletedTask; - }; - }); - } - - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - //if (env.IsDevelopment()) - //{ - app.UseDeveloperExceptionPage(); - //} - //else - //{ - // app.UseExceptionHandler("/Home/Error"); - // // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. - // app.UseHsts(); - //} - app.UseHttpsRedirection(); - app.UseStaticFiles(); - - app.UseRouting(); - app.UseAuthentication(); - app.UseAuthorization(); - - app.UseEndpoints(endpoints => - { - endpoints.MapDefaultControllerRoute(); - endpoints.MapHealthChecks("health", - new HealthCheckOptions - { - Predicate = _ => true, - ResponseWriter = Shared.HealthChecks.HealthCheckMiddleware.WriteResponse - }); - endpoints.MapHealthChecks("healthui", - new HealthCheckOptions - { - Predicate = _ => true, - ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse - }); - }); - } - } -}