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

Feature/externalpdp #639

Merged
merged 31 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
ac40a09
First models
TheTechArch Dec 15, 2023
8187313
Fixed mapping
TheTechArch Dec 15, 2023
bc0551b
Updated map for respons
TheTechArch Dec 19, 2023
7bfbd99
Test update
TheTechArch Dec 20, 2023
f36f01e
Updates
TheTechArch Dec 20, 2023
3412fb5
Merge
TheTechArch Jan 2, 2024
71a1803
Test case 1
TheTechArch Jan 3, 2024
554e071
Added more tests
TheTechArch Jan 3, 2024
381dca2
Updates testdata
TheTechArch Jan 3, 2024
9e5fe43
UJpdates attribute ID
TheTechArch Jan 4, 2024
d7e284f
Testdata updates
TheTechArch Jan 5, 2024
c1ae926
Updated to latest decision on attribute names
TheTechArch Jan 17, 2024
2d82bee
Added Authentication and scope check
TheTechArch Jan 19, 2024
9290eb3
First version of merge
TheTechArch Feb 2, 2024
5797bdd
Merge fix
TheTechArch Feb 2, 2024
562cd7b
More merge fix
TheTechArch Feb 2, 2024
72ea190
Added scenario for org in policy
TheTechArch Feb 5, 2024
5490c41
Added scenario with old param
TheTechArch Feb 5, 2024
81d494b
Removed pep project
TheTechArch Feb 5, 2024
138f16a
Fixed coding issues
TheTechArch Feb 6, 2024
564d92f
Fixed testdata
TheTechArch Feb 6, 2024
cd48c05
Code updates
TheTechArch Feb 6, 2024
8ee3475
Fixed response
TheTechArch Feb 6, 2024
7abd38c
Fixed path and cancellation token
TheTechArch Feb 6, 2024
850f9af
Added Cancellationtoken
TheTechArch Feb 6, 2024
028e82b
Fixed catch of cancellationtoken
TheTechArch Feb 6, 2024
941af9b
Code smell with missing token
TheTechArch Feb 6, 2024
022ef0d
Code smell
TheTechArch Feb 7, 2024
f48ec71
Allowed list
TheTechArch Feb 8, 2024
9445a51
Multipart test for external
TheTechArch Feb 8, 2024
8829ca9
Merge
TheTechArch Feb 12, 2024
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
1 change: 1 addition & 0 deletions src/Authorization/Altinn.Platform.Authorization.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<PackageReference Include="Altinn.Common.AccessTokenClient" Version="1.1.5" />
<PackageReference Include="Altinn.Common.PEP" Version="1.3.0" />
<PackageReference Include="Altinn.Platform.Models" Version="1.2.0" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
<PackageReference Include="Azure.Identity" Version="1.10.4" />
<PackageReference Include="Azure.Security.KeyVault.Secrets" Version="4.5.0" />
<PackageReference Include="Azure.Storage.Blobs" Version="12.19.1" />
Expand Down
7 changes: 6 additions & 1 deletion src/Authorization/Constants/XacmlRequestAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public static class XacmlRequestAttribute
/// <summary>
/// xacml string that represents organization number
/// </summary>
public const string OrganizationNumberAttribute = "urn:altinn:organizationnumber";
public const string OrganizationNumberAttribute = "urn:iso6523-actorid-upi:0192";

/// <summary>
/// xacml string that represents user
Expand All @@ -64,5 +64,10 @@ public static class XacmlRequestAttribute
/// xacml string that represents resource
/// </summary>
public const string ResourceRegistryAttribute = "urn:altinn:resourceregistry";

/// <summary>
/// xacml string that represents ssn for
/// </summary>
public const string SsnAttribute = "urn:person-no";
}
}
40 changes: 29 additions & 11 deletions src/Authorization/Controllers/DecisionController.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

using Altinn.Authorization.ABAC;
using Altinn.Authorization.ABAC.Interface;
using Altinn.Authorization.ABAC.Utils;
using Altinn.Authorization.ABAC.Xacml;
using Altinn.Authorization.ABAC.Xacml.JsonProfile;
using Altinn.Platform.Authorization.Helpers;
using Altinn.Platform.Authorization.ModelBinding;
using Altinn.Platform.Authorization.Models;
using Altinn.Platform.Authorization.Models.External;
using Altinn.Platform.Authorization.Repositories.Interface;
using Altinn.Platform.Authorization.Services.Interface;
using Altinn.Platform.Authorization.Services.Interfaces;
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
Expand All @@ -43,6 +41,7 @@
private readonly IMemoryCache _memoryCache;
private readonly IEventLog _eventLog;
private readonly IFeatureManager _featureManager;
private readonly IMapper _mapper;

/// <summary>
/// Initializes a new instance of the <see cref="DecisionController"/> class.
Expand All @@ -55,7 +54,7 @@
/// <param name="memoryCache">memory cache</param>
/// <param name="eventLog">the authorization event logger</param>
/// <param name="featureManager">the feature manager</param>
public DecisionController(IContextHandler contextHandler, IDelegationContextHandler delegationContextHandler, IPolicyRetrievalPoint policyRetrievalPoint, IDelegationMetadataRepository delegationRepository, ILogger<DecisionController> logger, IMemoryCache memoryCache, IEventLog eventLog, IFeatureManager featureManager)
public DecisionController(IContextHandler contextHandler, IDelegationContextHandler delegationContextHandler, IPolicyRetrievalPoint policyRetrievalPoint, IDelegationMetadataRepository delegationRepository, ILogger<DecisionController> logger, IMemoryCache memoryCache, IEventLog eventLog, IFeatureManager featureManager, IMapper mapper)

Check warning on line 57 in src/Authorization/Controllers/DecisionController.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

Parameter 'mapper' has no matching param tag in the XML comment for 'DecisionController.DecisionController(IContextHandler, IDelegationContextHandler, IPolicyRetrievalPoint, IDelegationMetadataRepository, ILogger<DecisionController>, IMemoryCache, IEventLog, IFeatureManager, IMapper)' (but other parameters do)

Check warning on line 57 in src/Authorization/Controllers/DecisionController.cs

View workflow job for this annotation

GitHub Actions / Build and Test

Parameter 'mapper' has no matching param tag in the XML comment for 'DecisionController.DecisionController(IContextHandler, IDelegationContextHandler, IPolicyRetrievalPoint, IDelegationMetadataRepository, ILogger<DecisionController>, IMemoryCache, IEventLog, IFeatureManager, IMapper)' (but other parameters do)
TheTechArch marked this conversation as resolved.
Show resolved Hide resolved
{
_pdp = new PolicyDecisionPoint();
_prp = policyRetrievalPoint;
Expand All @@ -66,6 +65,7 @@
_memoryCache = memoryCache;
_eventLog = eventLog;
_featureManager = featureManager;
_mapper = mapper;
}

/// <summary>
Expand Down Expand Up @@ -109,13 +109,31 @@
}
}

private async Task<XacmlJsonResponse> Authorize(XacmlJsonRequest decisionRequest)
/// <summary>
/// External endpoint for autorization
/// </summary>
[HttpPost("authorize")]
TheTechArch marked this conversation as resolved.
Show resolved Hide resolved
public async Task<XacmlJsonResponseExternal> AuthorizeExternal([FromBody] XacmlJsonRequestRootExternal authorizationRequest)
{
try
{
XacmlJsonRequestRoot jsonRequest = _mapper.Map<XacmlJsonRequestRoot>(authorizationRequest);
XacmlJsonResponse xacmlResponse = await Authorize(jsonRequest.Request, true);
return _mapper.Map<XacmlJsonResponseExternal>(xacmlResponse);
}
catch (Exception ex)

Check warning on line 124 in src/Authorization/Controllers/DecisionController.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

The variable 'ex' is declared but never used

Check warning on line 124 in src/Authorization/Controllers/DecisionController.cs

View workflow job for this annotation

GitHub Actions / Build and Test

The variable 'ex' is declared but never used
TheTechArch marked this conversation as resolved.
Show resolved Hide resolved
{
throw;
}
}

private async Task<XacmlJsonResponse> Authorize(XacmlJsonRequest decisionRequest, bool isExternalRequest = false)
{
if (decisionRequest.MultiRequests == null || decisionRequest.MultiRequests.RequestReference == null
|| decisionRequest.MultiRequests.RequestReference.Count < 2)
{
XacmlContextRequest request = XacmlJsonXmlConverter.ConvertRequest(decisionRequest);
XacmlContextResponse xmlResponse = await Authorize(request);
XacmlContextResponse xmlResponse = await Authorize(request, isExternalRequest);
return XacmlJsonXmlConverter.ConvertResponse(xmlResponse);
}
else
Expand Down Expand Up @@ -164,7 +182,7 @@
}
}

XacmlContextResponse partResponse = await Authorize(XacmlJsonXmlConverter.ConvertRequest(jsonMultiRequestPart));
XacmlContextResponse partResponse = await Authorize(XacmlJsonXmlConverter.ConvertRequest(jsonMultiRequestPart), isExternalRequest);
XacmlJsonResponse xacmlJsonResponsePart = XacmlJsonXmlConverter.ConvertResponse(partResponse);

if (multiResponse.Response == null)
Expand All @@ -187,7 +205,7 @@
request = XacmlParser.ReadContextRequest(reader);
}

XacmlContextResponse xacmlContextResponse = await Authorize(request);
XacmlContextResponse xacmlContextResponse = await Authorize(request, false);
return CreateResponse(xacmlContextResponse);
}

Expand All @@ -213,9 +231,9 @@
return Content(xml);
}

private async Task<XacmlContextResponse> Authorize(XacmlContextRequest decisionRequest)
private async Task<XacmlContextResponse> Authorize(XacmlContextRequest decisionRequest, bool isExernalRequest)
{
decisionRequest = await this._contextHandler.Enrich(decisionRequest);
decisionRequest = await this._contextHandler.Enrich(decisionRequest, isExernalRequest);

////_logger.LogInformation($"// DecisionController // Authorize // Roles // Enriched request: {JsonConvert.SerializeObject(decisionRequest)}.");
XacmlPolicy policy = await this._prp.GetPolicyAsync(decisionRequest);
Expand All @@ -232,7 +250,7 @@
XacmlContextResult delegationResult = delegationContextResponse.Results.First();
if (delegationResult.Decision.Equals(XacmlContextDecision.Permit))
{
_eventLog.CreateAuthorizationEvent(_featureManager, decisionRequest, HttpContext, delegationContextResponse);

Check warning on line 253 in src/Authorization/Controllers/DecisionController.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.

Check warning on line 253 in src/Authorization/Controllers/DecisionController.cs

View workflow job for this annotation

GitHub Actions / Build and Test

Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
return delegationContextResponse;
}
}
Expand All @@ -242,7 +260,7 @@
}
}

_eventLog.CreateAuthorizationEvent(_featureManager, decisionRequest, HttpContext, rolesContextResponse);

Check warning on line 263 in src/Authorization/Controllers/DecisionController.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.

Check warning on line 263 in src/Authorization/Controllers/DecisionController.cs

View workflow job for this annotation

GitHub Actions / Build and Test

Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
return rolesContextResponse;
}

Expand Down
44 changes: 44 additions & 0 deletions src/Authorization/Models/External/RequestMapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using Altinn.Authorization.ABAC.Xacml.JsonProfile;

namespace Altinn.Platform.Authorization.Models.External
{
/// <summary>
/// A class that hold access managment mapping
/// </summary>
public class RequestMapper : AutoMapper.Profile
{
/// <summary>
/// Initializes a new instance of the <see cref="RequestMapper"/> class.
/// </summary>
public RequestMapper()
{
AllowNullCollections = true;
CreateMap<XacmlJsonAttributeExternal, XacmlJsonAttribute>();

CreateMap<XacmlJsonIdReferenceExternal, XacmlJsonIdReference>();
CreateMap<XacmlJsonMultiRequestsExternal, XacmlJsonMultiRequests>();

CreateMap<XacmlJsonPolicyIdentifierListExternal, XacmlJsonPolicyIdentifierList>();
CreateMap<XacmlJsonRequestExternal, XacmlJsonRequest>();
CreateMap<XacmlJsonRequestReferenceExternal, XacmlJsonRequestReference>();
CreateMap<XacmlJsonRequestRootExternal, XacmlJsonRequestRoot>();
CreateMap<XacmlJsonRequestExternal, XacmlJsonRequest>();
CreateMap<XacmlJsonObligationOrAdviceExternal, XacmlJsonObligationOrAdvice>();
CreateMap<XacmlJsonCategoryExternal, XacmlJsonCategory>();
CreateMap<XacmlJsonStatusCodeExternal, XacmlJsonStatusCode>();
CreateMap<XacmlJsonStatusExternal, XacmlJsonStatus>();

CreateMap<XacmlJsonResponse, XacmlJsonResponseExternal>();
CreateMap<XacmlJsonResult, XacmlJsonResultExternal>();

CreateMap<XacmlJsonObligationOrAdvice, XacmlJsonObligationOrAdviceExternal>();
CreateMap<XacmlJsonCategory, XacmlJsonCategoryExternal>();
CreateMap<XacmlJsonStatus, XacmlJsonStatusExternal>();
CreateMap<XacmlJsonStatusCode, XacmlJsonStatusCodeExternal>();
CreateMap<XacmlJsonPolicyIdentifierList, XacmlJsonPolicyIdentifierListExternal>();
CreateMap<XacmlJsonAttribute, XacmlJsonAttributeExternal>();
CreateMap<XacmlJsonIdReference, XacmlJsonIdReferenceExternal>();
CreateMap<XacmlJsonAttributeAssignment, XacmlJsonAttributeAssignmentExternal>();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
namespace Altinn.Platform.Authorization.Models.External
{
/// <summary>
/// Json reprentation of Attribute assignment returned.
/// </summary>
public class XacmlJsonAttributeAssignmentExternal
{
/// <summary>
/// Gets or sets a string containing a XACML attribute URI. Mandatory.
/// </summary>
public string AttributeId { get; set; }

/// <summary>
/// Gets or sets the value. Mandatory.
/// </summary>
public string Value { get; set; }

/// <summary>
/// Gets or sets a string containing a XACML category URI or the shorthand notation defined in section 4.2.2.1.
/// </summary>
public string Category { get; set; }

/// <summary>
/// Gets or sets the datattype of the attribute.
/// </summary>
public string DataType { get; set; }

/// <summary>
/// Gets or sets the issuer of the attribute. Optional.
/// </summary>
public string Issuer { get; set; }
}
}
33 changes: 33 additions & 0 deletions src/Authorization/Models/External/XacmlJsonAttributeExternal.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
namespace Altinn.Platform.Authorization.Models.External
{
/// <summary>
/// Defines the Attribute Json object.
/// </summary>
public class XacmlJsonAttributeExternal
{
/// <summary>
/// Gets or sets the AttributeId. Required.
/// </summary>
public string AttributeId { get; set; }

/// <summary>
/// Gets or sets the value for the Attribute. Required.
/// </summary>
public string Value { get; set; }

/// <summary>
/// Gets or sets the issuer of the attribute. Optional.
/// </summary>
public string Issuer { get; set; }

/// <summary>
/// Gets or sets the datatype of the attribute. Optional in some cases.
/// </summary>
public string DataType { get; set; }

/// <summary>
/// Gets or sets a value indicating whether the attribute should be returned in the result.
/// </summary>
public bool IncludeInResult { get; set; }
}
}
33 changes: 33 additions & 0 deletions src/Authorization/Models/External/XacmlJsonCategoryExternal.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.Collections.Generic;

namespace Altinn.Platform.Authorization.Models.External
{
/// <summary>
/// The Category object corresponds to the XML <Attributes /> element. Just like the <Attributes /> element is specific to a given XACML
/// attribute category, the Category object in JSON is specific to a given XACML attribute category.
/// http://docs.oasis-open.org/xacml/xacml-json-http/v1.1/csprd01/xacml-json-http-v1.1-csprd01.html.
/// </summary>
public class XacmlJsonCategoryExternal
{
/// <summary>
/// Gets or sets CategoryId.
/// Mandatory for a Category object in the "Category" member array; otherwise, optional. See section 4.2.2.2.
/// </summary>
public string CategoryId { get; set; }

/// <summary>
/// Gets or sets the Id of the category, mappes to attributeId in xml version of ContextRequest.
/// </summary>
public string Id { get; set; }

/// <summary>
/// Gets or sets optional XML content.
/// </summary>
public string Content { get; set; }

/// <summary>
/// Gets or sets a list over all attributes for a given attribute Id mappes to the.
/// </summary>
public List<XacmlJsonAttributeExternal> Attribute { get; set; }
}
}
19 changes: 19 additions & 0 deletions src/Authorization/Models/External/XacmlJsonIdReferenceExternal.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace Altinn.Platform.Authorization.Models.External
{
/// <summary>
/// A JSON object for policy refernces.
/// </summary>
public class XacmlJsonIdReferenceExternal
{
/// <summary>
/// Gets or sets a string containing a XACML policy or policy set URI.
/// Represents the value stored inside the XACML XML<PolicyIdReference /> or<PolicySetIdReference/> element.
/// </summary>
public string Id { get; set; }

/// <summary>
/// Gets or sets the version.
/// </summary>
public string Version { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Collections.Generic;

namespace Altinn.Platform.Authorization.Models.External
{
/// <summary>
/// A JSON object for information about missing attributes in the Context Request.
/// </summary>
public class XacmlJsonMissingAttributeDetailExternal
{
/// <summary>
/// Gets or sets a string containing a XACML attribute URI.
/// </summary>
public string AttributeId { get; set; }

/// <summary>
/// Gets or sets the value.
/// </summary>
public List<string> Value { get; set; }

/// <summary>
/// Gets or sets the issuer.
/// </summary>
public string Issuer { get; set; }

/// <summary>
/// Gets or sets the datatype.
/// </summary>
public string DataType { get; set; }

/// <summary>
/// Gets or sets the category of the missing attribute.
/// </summary>
public string Category { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System.Collections.Generic;

namespace Altinn.Platform.Authorization.Models.External
{
/// <summary>
/// A JSON object that defines references to multiple requests.
/// </summary>
public class XacmlJsonMultiRequestsExternal
{
/// <summary>
/// Gets or sets the request reference.
/// </summary>
public List<XacmlJsonRequestReferenceExternal> RequestReference { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Collections.Generic;

namespace Altinn.Platform.Authorization.Models.External
{
/// <summary>
/// Defines a Json object for ObligationOrAdvice.
/// </summary>
public class XacmlJsonObligationOrAdviceExternal
{
/// <summary>
/// Gets or sets a string containing a XACML obligation or advice URI.
/// </summary>
public string Id { get; set; }

/// <summary>
/// Gets or sets an array of AttributeAssignment objects.
/// </summary>
public List<XacmlJsonAttributeAssignmentExternal> AttributeAssignment { get; set; }
}
}
Loading
Loading