From ce4382b20e9eeffde4b22a91883cb4a08554ca16 Mon Sep 17 00:00:00 2001 From: James Gunn Date: Tue, 17 Oct 2023 14:00:07 +0100 Subject: [PATCH] Prevent TrnMatchPolicy and TrnRequirementType from being overriden (#741) --- .../Controllers/AuthorizationController.cs | 105 ++++++++---------- .../appsettings.Development.json | 3 +- .../appsettings.json | 3 +- .../appsettings.json | 3 +- 4 files changed, 53 insertions(+), 61 deletions(-) diff --git a/dotnet-authserver/src/TeacherIdentity.AuthServer/Controllers/AuthorizationController.cs b/dotnet-authserver/src/TeacherIdentity.AuthServer/Controllers/AuthorizationController.cs index c40ac372b..d2d40023e 100644 --- a/dotnet-authserver/src/TeacherIdentity.AuthServer/Controllers/AuthorizationController.cs +++ b/dotnet-authserver/src/TeacherIdentity.AuthServer/Controllers/AuthorizationController.cs @@ -27,6 +27,7 @@ public class AuthorizationController : Controller private readonly TeacherIdentityServerDbContext _dbContext; private readonly IClock _clock; private readonly TrnTokenHelper _trnTokenHelper; + private readonly IConfiguration _configuration; public AuthorizationController( TeacherIdentityApplicationManager applicationManager, @@ -36,7 +37,8 @@ public AuthorizationController( UserClaimHelper userClaimHelper, TeacherIdentityServerDbContext dbContext, IClock clock, - TrnTokenHelper trnTokenHelper) + TrnTokenHelper trnTokenHelper, + IConfiguration configuration) { _applicationManager = applicationManager; _authorizationManager = authorizationManager; @@ -46,6 +48,7 @@ public AuthorizationController( _dbContext = dbContext; _clock = clock; _trnTokenHelper = trnTokenHelper; + _configuration = configuration; } [HttpGet("~/connect/authorize")] @@ -94,32 +97,54 @@ public async Task Authorize() if (userRequirements.HasFlag(UserRequirements.TrnHolder)) { - trnRequirementType = await GetTrnRequirementType(request); - trnMatchPolicy = await GetTrnMatchPolicy(request); + var client = (await _applicationManager.FindByClientIdAsync(request.ClientId!))!; + var allowTrnConfigurationOverrides = client.ClientId == "testclient" || _configuration.GetValue("AllowTrnConfigurationOverrides", false); - if (trnRequirementType is null) + if (allowTrnConfigurationOverrides) { - return Forbid( - authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, - properties: new AuthenticationProperties(new Dictionary() + var requestedTrnRequirement = request["trn_requirement"]; + if (requestedTrnRequirement.HasValue) + { + if (Enum.TryParse(requestedTrnRequirement?.Value as string, out var parsedTrnRequirementType)) { - [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.InvalidRequest, - [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = - "Invalid trn_requirement specified." - })); - } - - if (trnMatchPolicy is null) - { - return Forbid( - authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, - properties: new AuthenticationProperties(new Dictionary() + trnRequirementType = parsedTrnRequirementType; + } + else + { + return Forbid( + authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, + properties: new AuthenticationProperties(new Dictionary() + { + [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.InvalidRequest, + [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = + "Invalid trn_requirement specified." + })); + } + } + + var requestedTrnMatchPolicy = request["trn_match_policy"]; + if (requestedTrnMatchPolicy.HasValue) + { + if (Enum.TryParse(requestedTrnMatchPolicy?.Value as string, out var parsedTrnMatchPolicy)) + { + trnMatchPolicy = parsedTrnMatchPolicy; + } + else { - [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.InvalidRequest, - [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = - "Invalid trn_match_policy specified." - })); + return Forbid( + authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, + properties: new AuthenticationProperties(new Dictionary() + { + [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.InvalidRequest, + [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = + "Invalid trn_match_policy specified." + })); + } + } } + + trnRequirementType ??= client.TrnRequirementType; + trnMatchPolicy ??= client.TrnMatchPolicy; } var sessionId = request["session_id"]?.Value as string; @@ -490,42 +515,6 @@ private static IEnumerable GetDestinations(Claim claim, ClaimsPrincipal return signedInUser; } - private async Task GetTrnRequirementType(OpenIddictRequest request) - { - var requestedTrnRequirement = request["trn_requirement"]; - - if (requestedTrnRequirement.HasValue) - { - if (!Enum.TryParse(requestedTrnRequirement?.Value as string, out var parsedTrnRequirementType)) - { - return null; - } - - return parsedTrnRequirementType; - } - - var client = (await _applicationManager.FindByClientIdAsync(request.ClientId!))!; - return client.TrnRequirementType; - } - - private async Task GetTrnMatchPolicy(OpenIddictRequest request) - { - var trnMatchPolicy = request["trn_match_policy"]; - - if (trnMatchPolicy.HasValue) - { - if (!Enum.TryParse(trnMatchPolicy?.Value as string, out var parsedTrnMatchPolicy)) - { - return null; - } - - return parsedTrnMatchPolicy; - } - - var client = (await _applicationManager.FindByClientIdAsync(request.ClientId!))!; - return client.TrnMatchPolicy; - } - private async Task InitializeAuthenticationState(User? signedInUser, EnhancedTrnToken? trnToken, AuthenticationState authenticationState) { diff --git a/dotnet-authserver/src/TeacherIdentity.AuthServer/appsettings.Development.json b/dotnet-authserver/src/TeacherIdentity.AuthServer/appsettings.Development.json index b3582e07d..4b78acf6b 100644 --- a/dotnet-authserver/src/TeacherIdentity.AuthServer/appsettings.Development.json +++ b/dotnet-authserver/src/TeacherIdentity.AuthServer/appsettings.Development.json @@ -68,5 +68,6 @@ "UserVerification": { "UseFixedPin": true, "Pin": "00000" - } + }, + "AllowTrnConfigurationOverrides": true } diff --git a/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/appsettings.json b/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/appsettings.json index f432cdd78..2d4af743e 100644 --- a/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/appsettings.json +++ b/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/appsettings.json @@ -11,7 +11,8 @@ "UserVerification": { "UseFixedPin": true }, - "BlockEstablishmentEmailDomains": true + "BlockEstablishmentEmailDomains": true, + "AllowTrnConfigurationOverrides": true }, "TestClient": { "ClientId": "testclient", diff --git a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/appsettings.json b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/appsettings.json index 4ac9b19b5..3f8fdbf0a 100644 --- a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/appsettings.json +++ b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/appsettings.json @@ -10,5 +10,6 @@ "BlockEstablishmentEmailDomains": true, "WebHooks": { "WebHooksCacheDurationSeconds": 30 - } + }, + "AllowTrnConfigurationOverrides": true }