diff --git a/src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/DecisionRequestHelper.cs b/src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/DecisionRequestHelper.cs index 567f70ade..390db3c6f 100644 --- a/src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/DecisionRequestHelper.cs +++ b/src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/DecisionRequestHelper.cs @@ -76,42 +76,38 @@ public static DialogDetailsAuthorizationResult CreateDialogDetailsResponse(List< }; } - private static List CreateAccessSubjectCategory(IEnumerable claims) - { + private static List CreateAccessSubjectCategory(IEnumerable claims) => // The PDP expects for the most part only a single subject attribute, and will even fail the request // for some types (e.g. the urn:altinn:systemuser:uuid) if there are multiple subject attributes (for // security reasons). We therefore need to filter out the relevant attributes and only include those, - // which in essence is the pid and the systemuser uuid. In addition, we also utilize urn:altinn:userid + // which in essence is the pid and the system user uuid. In addition, we also utilize urn:altinn:userid // if present instead of the pid as a simple optimization as this offloads the PDP from having to look up // the user id from the pid. - foreach (var claim in claims) + claims.Select(claim => claim.Type switch { - if (claim.Type == UserIdClaimType) + UserIdClaimType => new XacmlJsonCategory { - return [new() { Id = SubjectId, Attribute = - [new XacmlJsonAttribute { AttributeId = AttributeIdUserId, Value = claim.Value }] }]; - } - - if (claim.Type == PidClaimType) + Id = SubjectId, + Attribute = [new() { AttributeId = AttributeIdUserId, Value = claim.Value }] + }, + PidClaimType => new XacmlJsonCategory { - return [new() { Id = SubjectId, Attribute = - [new XacmlJsonAttribute { AttributeId = NorwegianPersonIdentifier.Prefix, Value = claim.Value }] }]; - } - - if (claim.Type == RarAuthorizationDetailsClaimType) + Id = SubjectId, + Attribute = [new() { AttributeId = NorwegianPersonIdentifier.Prefix, Value = claim.Value }] + }, + RarAuthorizationDetailsClaimType when new ClaimsPrincipal(new ClaimsIdentity(new[] { claim })).TryGetSystemUserId(out var systemUserId) => new XacmlJsonCategory { - var claimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity(new[] { claim })); - if (claimsPrincipal.TryGetSystemUserId(out var systemUserId)) - { - return [new() { Id = SubjectId, Attribute = - [new XacmlJsonAttribute { AttributeId = AttributeIdSystemUser, Value = systemUserId }] }]; - } - } - } - - throw new UnreachableException("Unable to find a suitable subject attribute for the authorization request. Having a known user type should be enforced during authentication (see UserTypeValidationMiddleware)."); - } + Id = SubjectId, + Attribute = [new XacmlJsonAttribute { AttributeId = AttributeIdSystemUser, Value = systemUserId }] + }, + _ => null + }) + .FirstOrDefault(x => x != null) switch + { + { } validCategory => new List { validCategory }, + _ => throw new UnreachableException("Unable to find a suitable subject attribute for the authorization request. Having a known user type should be enforced during authentication (see UserTypeValidationMiddleware)."), + }; private static List CreateActionCategories( List altinnActions, out Dictionary actionIdByName) diff --git a/tests/Digdir.Domain.Dialogporten.Infrastructure.Unit.Tests/DecisionRequestHelperTests.cs b/tests/Digdir.Domain.Dialogporten.Infrastructure.Unit.Tests/DecisionRequestHelperTests.cs index 583fa548b..623b7f94b 100644 --- a/tests/Digdir.Domain.Dialogporten.Infrastructure.Unit.Tests/DecisionRequestHelperTests.cs +++ b/tests/Digdir.Domain.Dialogporten.Infrastructure.Unit.Tests/DecisionRequestHelperTests.cs @@ -1,4 +1,5 @@ -using System.Security.Claims; +using System.Diagnostics; +using System.Security.Claims; using Altinn.Authorization.ABAC.Xacml.JsonProfile; using Digdir.Domain.Dialogporten.Application.Common.Authorization; using Digdir.Domain.Dialogporten.Application.Externals.AltinnAuthorization; @@ -10,8 +11,6 @@ namespace Digdir.Domain.Dialogporten.Infrastructure.Unit.Tests; public class DecisionRequestHelperTests { - private const string ConsumerClaimValue = /*lang=json,strict*/ "{\"authority\":\"iso6523-actorid-upis\",\"ID\":\"0192:991825827\"}"; - private const string AuthorizationDetailsClaimValue = /*lang=json,strict*/"[{\"type\":\"urn:altinn:systemuser\",\"systemuser_id\":[\"unique_systemuser_id\"]}]"; [Fact] @@ -136,8 +135,7 @@ public void CreateDialogDetailsRequestShouldReturnCorrectRequestForSystemUser() var request = CreateDialogDetailsAuthorizationRequest( GetAsClaims( ("authorization_details", AuthorizationDetailsClaimValue), - ("pid", "12345678901"), - ("consumer", ConsumerClaimValue) + ("pid", "12345678901") ), $"{NorwegianOrganizationIdentifier.PrefixWithSeparator}713330310" ); @@ -209,7 +207,6 @@ public void CreateDialogDetailsRequestShouldReturnCorrectRequestForOverriddenRes } [Fact] - public void CreateDialogDetailsRequestShouldReturnCorrectRequestForFullyQualifiedSubresource() { // Arrange @@ -264,6 +261,21 @@ public void CreateDialogDetailsResponseShouldReturnCorrectResponse() Assert.DoesNotContain(new AltinnAction("failaction", Constants.MainResource), response.AuthorizedAltinnActions); } + [Fact] + public void CreateDetailsRequestShouldThrowUnreachableExceptionIfNoValidUserType() + { + // Arrange + var request = CreateDialogDetailsAuthorizationRequest( + GetAsClaims( + ("consumer", "somevalue") + ), + $"{NorwegianOrganizationIdentifier.PrefixWithSeparator}713330310"); + + // Act / assert + Assert.Throws(() => DecisionRequestHelper.CreateDialogDetailsRequest(request)); + } + + private static DialogDetailsAuthorizationRequest CreateDialogDetailsAuthorizationRequest(List principalClaims, string party, bool isApp = false) { var allClaims = new List