Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

correct auth for legacy overview #460

Merged
merged 3 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public async Task<OneOf<LegacyGetCorrespondenceHistoryResponse, Error>> Process(
{
return Errors.CouldNotFindOrgNo;
}
var minimumAuthLevel = await _altinnAuthorizationService.CheckUserAccessAndGetMinimumAuthLevel(correspondence.ResourceId, new List<ResourceAccessLevel> { ResourceAccessLevel.Read }, cancellationToken);
var minimumAuthLevel = await _altinnAuthorizationService.CheckUserAccessAndGetMinimumAuthLevel(recipientParty.SSN, correspondence.ResourceId, new List<ResourceAccessLevel> { ResourceAccessLevel.Read }, correspondence.Recipient, cancellationToken);
if (minimumAuthLevel is not int authenticationLevel)
{
authenticationLevel = 2;
Andreass2 marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,11 @@ public async Task<OneOf<LegacyGetCorrespondenceOverviewResponse, Error>> Process
{
return Errors.CorrespondenceNotFound;
}
/*var minimumAuthLevel = await _altinnAuthorizationService.CheckUserAccessAndGetMinimumAuthLevel(correspondence.ResourceId, new List<ResourceAccessLevel> { ResourceAccessLevel.Read }, cancellationToken);
var minimumAuthLevel = await _altinnAuthorizationService.CheckUserAccessAndGetMinimumAuthLevel(userParty.SSN, correspondence.ResourceId, new List<ResourceAccessLevel> { ResourceAccessLevel.Read }, correspondence.Recipient, cancellationToken);
if (minimumAuthLevel == null)
{
return Errors.LegacyNoAccessToCorrespondence;
} */
var minimumAuthLevel = 2;
}
var recipients = new List<string>();
if (correspondence.Recipient != userParty.SSN && correspondence.Recipient != ("0192:" + userParty.OrgNumber))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ namespace Altinn.Correspondence.Core.Repositories;
public interface IAltinnAuthorizationService
{
Task<bool> CheckUserAccess(string resourceId, List<ResourceAccessLevel> rights, CancellationToken cancellationToken = default, string? recipientOrgNo = null);
Task<int?> CheckUserAccessAndGetMinimumAuthLevel(string resourceId, List<ResourceAccessLevel> rights, CancellationToken cancellationToken = default, string? recipientOrgNo = null);
Task<int?> CheckUserAccessAndGetMinimumAuthLevel(string ssn, string resourceId, List<ResourceAccessLevel> rights, string recipientOrgNo, CancellationToken cancellationToken = default);
Task<bool> CheckMigrationAccess(string resourceId, List<ResourceAccessLevel> rights, CancellationToken cancellationToken = default);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public Task<bool> CheckUserAccess(string resourceId, List<ResourceAccessLevel> r
return Task.FromResult(true);
}

public Task<int?> CheckUserAccessAndGetMinimumAuthLevel(string resourceId, List<ResourceAccessLevel> rights, CancellationToken cancellationToken = default, string? recipientOrgNo = null)
public Task<int?> CheckUserAccessAndGetMinimumAuthLevel(string ssn, string resourceId, List<ResourceAccessLevel> rights, string recipientOrgNo, CancellationToken cancellationToken = default)
{
return Task.FromResult((int?)3);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,25 @@ public async Task<bool> CheckUserAccess(string resourceId, List<ResourceAccessLe
var user = _httpContextAccessor.HttpContext?.User;
var validation = await ValidateCheckUserAccess(user, resourceId, cancellationToken);
if (validation != null) return (bool)validation;
var responseContent = await AuthorizeRequest(user, rights, resourceId, recipientOrgNo, cancellationToken);
var actionIds = rights.Select(GetActionId).ToList();
XacmlJsonRequestRoot jsonRequest = CreateDecisionRequest(user, actionIds, resourceId, recipientOrgNo);
var responseContent = await AuthorizeRequest(jsonRequest, cancellationToken);
if (responseContent is null) return false;

var validationResult = ValidateAuthorizationResponse(responseContent, user);
return validationResult;
}


public async Task<int?> CheckUserAccessAndGetMinimumAuthLevel(string resourceId, List<ResourceAccessLevel> rights, CancellationToken cancellationToken = default, string? recipientOrgNo = null)
public async Task<int?> CheckUserAccessAndGetMinimumAuthLevel(string ssn, string resourceId, List<ResourceAccessLevel> rights, string recipientOrgNo, CancellationToken cancellationToken = default)
Andreass2 marked this conversation as resolved.
Show resolved Hide resolved
{
var user = _httpContextAccessor.HttpContext?.User;
var validation = await ValidateCheckUserAccess(user, resourceId, cancellationToken);
if (validation != null) return (bool)validation ? 3 : null;
var responseContent = await AuthorizeRequest(user, rights, resourceId, recipientOrgNo, cancellationToken);
var actionIds = rights.Select(GetActionId).ToList();
Andreass2 marked this conversation as resolved.
Show resolved Hide resolved
var orgnr = recipientOrgNo.Split(":")[1];
Andreass2 marked this conversation as resolved.
Show resolved Hide resolved
XacmlJsonRequestRoot jsonRequest = CreateDecisionRequestForLegacy(user, ssn, actionIds, resourceId, orgnr);
var responseContent = await AuthorizeRequest(jsonRequest, cancellationToken);
if (responseContent is null) return null;

var validationResult = ValidateAuthorizationResponse(responseContent, user);
Expand Down Expand Up @@ -107,10 +112,8 @@ public async Task<bool> CheckMigrationAccess(string resourceId, List<ResourceAcc
return null;
}

private async Task<XacmlJsonResponse?> AuthorizeRequest(ClaimsPrincipal user, List<ResourceAccessLevel> rights, string resourceId, string? recipientOrgNo, CancellationToken cancellationToken)
private async Task<XacmlJsonResponse?> AuthorizeRequest(XacmlJsonRequestRoot jsonRequest, CancellationToken cancellationToken)
{
var actionIds = rights.Select(GetActionId).ToList();
XacmlJsonRequestRoot jsonRequest = CreateDecisionRequest(user, actionIds, resourceId, recipientOrgNo);
var response = await _httpClient.PostAsJsonAsync("authorization/api/v1/authorize", jsonRequest, cancellationToken);
if (!response.IsSuccessStatusCode)
{
Expand Down Expand Up @@ -143,6 +146,17 @@ private XacmlJsonRequestRoot CreateDecisionRequest(ClaimsPrincipal user, List<st
throw new SecurityTokenInvalidIssuerException();
}

private XacmlJsonRequestRoot CreateDecisionRequestForLegacy(ClaimsPrincipal user, string ssn, List<string> actionTypes, string resourceId, string recipientOrgNo)
{
var personIdClaim = GetPersonIdClaim();
if (personIdClaim is null || personIdClaim.Issuer == $"{_altinnOptions.PlatformGatewayUrl.TrimEnd('/')}/authentication/api/v1/openid/")
{
return AltinnTokenXacmlMapper.CreateAltinnDecisionRequestForLegacy(user, ssn, actionTypes, resourceId, recipientOrgNo);
}
throw new SecurityTokenInvalidIssuerException();
}

Andreass2 marked this conversation as resolved.
Show resolved Hide resolved

private bool ValidateAuthorizationResponse(XacmlJsonResponse response, ClaimsPrincipal user)
{
if (response.Response.IsNullOrEmpty())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,27 @@ public static XacmlJsonRequestRoot CreateAltinnDecisionRequest(ClaimsPrincipal u
XacmlJsonRequestRoot jsonRequest = new() { Request = request };
return jsonRequest;
}
public static XacmlJsonRequestRoot CreateAltinnDecisionRequestForLegacy(ClaimsPrincipal user, string ssn, List<string> actionTypes, string resourceId, string recipient)
{
XacmlJsonRequest request = new()
{
AccessSubject = new List<XacmlJsonCategory>(),
Action = new List<XacmlJsonCategory>(),
Resource = new List<XacmlJsonCategory>()
};

var subjectCategory = CreateSubjectCategoryForLegacy(user, ssn);
request.AccessSubject.Add(subjectCategory);
foreach (var actionType in actionTypes)
{
request.Action.Add(CreateActionCategory(actionType));
}
var resourceCategory = CreateResourceCategory(resourceId, user, true, recipient);
request.Resource.Add(resourceCategory);

XacmlJsonRequestRoot jsonRequest = new() { Request = request };
return jsonRequest;
}
Andreass2 marked this conversation as resolved.
Show resolved Hide resolved

private static XacmlJsonCategory CreateActionCategory(string actionType, bool includeResult = false)
{
Expand All @@ -47,13 +68,17 @@ private static XacmlJsonCategory CreateActionCategory(string actionType, bool in
return actionAttributes;
}

private static XacmlJsonCategory CreateResourceCategory(string resourceId, ClaimsPrincipal user)
private static XacmlJsonCategory CreateResourceCategory(string resourceId, ClaimsPrincipal user, bool legacy = false, string? orgNr = null)
{
XacmlJsonCategory resourceCategory = new() { Attribute = new List<XacmlJsonAttribute>() };

resourceCategory.Attribute.Add(DecisionHelper.CreateXacmlJsonAttribute(AltinnXacmlUrns.ResourceId, resourceId, DefaultType, DefaultIssuer));
var claim = user.Claims.FirstOrDefault(claim => IsClientOrgNo(claim.Type));
if (claim is not null)
if (legacy && orgNr is not null)
{
resourceCategory.Attribute.Add(DecisionHelper.CreateXacmlJsonAttribute(OrgNumberAttributeId, orgNr, DefaultType, DefaultIssuer));
}
else if (claim is not null)
{
resourceCategory.Attribute.Add(DecisionHelper.CreateXacmlJsonAttribute(OrgNumberAttributeId, claim.Value, DefaultType, DefaultIssuer));
}
Expand Down Expand Up @@ -93,6 +118,19 @@ private static XacmlJsonCategory CreateSubjectCategory(ClaimsPrincipal user)
xacmlJsonCategory.Attribute = list;
return xacmlJsonCategory;
}
private static XacmlJsonCategory CreateSubjectCategoryForLegacy(ClaimsPrincipal user, string ssn)
{
XacmlJsonCategory xacmlJsonCategory = new XacmlJsonCategory();
List<XacmlJsonAttribute> list = new List<XacmlJsonAttribute>();
var claim = user.Claims.FirstOrDefault(claim => IsScopeClaim(claim.Type));
if (claim is not null)
{
list.Add(CreateXacmlJsonAttribute("urn:altinn:person:identifier-no", ssn, "string", claim.Issuer));
list.Add(CreateXacmlJsonAttribute("urn:scope", claim.Value, "string", claim.Issuer));
}
xacmlJsonCategory.Attribute = list;
return xacmlJsonCategory;
}
Andreass2 marked this conversation as resolved.
Show resolved Hide resolved
private static bool IsValidUrn(string value)
{
Regex regex = new Regex("^urn*");
Expand Down Expand Up @@ -122,7 +160,7 @@ private static bool IsJtiClaim(string value)
private static bool IsValidPid(string value)
{
return value.Equals("pid");
}
}

private static XacmlJsonAttribute CreateXacmlJsonAttribute(string attributeId, string value, string dataType, string issuer, bool includeResult = false)
{
Expand Down
Loading