Skip to content

Commit

Permalink
feat(authorization): add role authorization (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
Phil91 authored Apr 2, 2024
1 parent f3beecc commit 221a435
Show file tree
Hide file tree
Showing 11 changed files with 162 additions and 2 deletions.
12 changes: 11 additions & 1 deletion charts/dim/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,17 @@ spec:
- name: "SWAGGERENABLED"
value: "{{ .Values.dim.swaggerEnabled }}"
- name: "DIM__ROOTDIRECTORYID"
value: "{{ .Values.dim.rootDirectoryId }}"
value: "{{ .Values.dim.rootDirectoryId }}"
- name: "JWTBEAREROPTIONS__METADATAADDRESS"
value: "{{ .Values.idp.address }}{{ .Values.idp.jwtBearerOptions.metadataPath }}"
- name: "JWTBEAREROPTIONS__REQUIREHTTPSMETADATA"
value: "{{ .Values.idp.jwtBearerOptions.requireHttpsMetadata }}"
- name: "JWTBEAREROPTIONS__TOKENVALIDATIONPARAMETERS__VALIDAUDIENCE"
value: "{{ .Values.idp.jwtBearerOptions.tokenValidationParameters.validAudience }}"
- name: "JWTBEAREROPTIONS__TOKENVALIDATIONPARAMETERS__VALIDISSUER"
value: "{{ .Values.idp.address }}{{ .Values.idp.jwtBearerOptions.tokenValidationParameters.validIssuerPath }}"
- name: "JWTBEAREROPTIONS__REFRESHINTERVAL"
value: "{{ .Values.idp.jwtBearerOptions.refreshInterval }}"
ports:
- name: http
containerPort: {{ .Values.portContainer }}
Expand Down
1 change: 1 addition & 0 deletions charts/dim/templates/service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,4 @@ spec:
targetPort: {{ .Values.portContainer }}
selector:
{{- include "dim.selectorLabels" . | nindent 4 }}

16 changes: 16 additions & 0 deletions charts/dim/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,22 @@ externalDatabase:
# -- Secret containing the password non-root username, (default 'dim').
existingSecret: "dim-external-db"

# -- Provide details about idp instance.
idp:
# -- Provide idp base address, without trailing '/auth'.
address: "https://centralidp.example.org"
authRealm: "CX-Central"
jwtBearerOptions:
requireHttpsMetadata: "true"
metadataPath: "/auth/realms/CX-Central/.well-known/openid-configuration"
tokenValidationParameters:
validIssuerPath: "/auth/realms/CX-Central"
validAudience: "Cl25-CX-Dim"
refreshInterval: "00:00:30"
tokenPath: "/auth/realms/CX-Central/protocol/openid-connect/token"
# -- Flag if the api should be used with an leading /auth path
useAuthTrail: true

ingress:
# -- DIM ingress parameters,
# enable ingress record generation for dim.
Expand Down
6 changes: 6 additions & 0 deletions consortia/environments/values-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ processesworker:
# -- Url to the cf service api
baseAddress: "https://portal-backend.dev.demo.catena-x.net/api/administration/registration/dim/"

idp:
address: "https://centralidp.dev.demo.catena-x.net"
jwtBearerOptions:
tokenValidationParameters:
validAudience: "Cl24-CX-Dim"

postgresql:
auth:
postgrespassword: "<path:portal/data/dim/dev/postgres#postgres-password>"
Expand Down
6 changes: 6 additions & 0 deletions consortia/environments/values-int.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ processesworker:
# -- Url to the cf service api
baseAddress: "https://portal-backend.dev.demo.catena-x.net/api/administration/registration/dim/"

idp:
address: "https://centralidp.int.demo.catena-x.net"
jwtBearerOptions:
tokenValidationParameters:
validAudience: "Cl25-CX-Dim"

postgresql:
auth:
postgrespassword: "<path:portal/data/dim/int/postgres#postgres-password>"
Expand Down
28 changes: 28 additions & 0 deletions src/web/Dim.Web/Authentication/CustomClaimTypes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/********************************************************************************
* Copyright (c) 2024 BMW Group AG
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

namespace Dim.Web.Authentication;

public static class CustomClaimTypes
{
public const string Sub = "sub";
public const string ClientId = "clientId";
public const string PreferredUserName = "preferred_username";
public const string ResourceAccess = "resource_access";
}
73 changes: 73 additions & 0 deletions src/web/Dim.Web/Authentication/KeycloakClaimsTransformation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/********************************************************************************
* Copyright (c) 2024 BMW Group AG
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.Options;
using Org.Eclipse.TractusX.Portal.Backend.Framework.Linq;
using System.Json;
using System.Security.Claims;

namespace Dim.Web.Authentication
{
public class KeycloakClaimsTransformation : IClaimsTransformation
{
private readonly JwtBearerOptions _options;

public KeycloakClaimsTransformation(IOptions<JwtBearerOptions> options)
{
_options = options.Value;
}

public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
var claimsIdentity = new ClaimsIdentity();
if (AddRoles(principal, claimsIdentity))
{
principal.AddIdentity(claimsIdentity);
}

return Task.FromResult(principal);
}

private bool AddRoles(ClaimsPrincipal principal, ClaimsIdentity claimsIdentity) =>
principal.Claims
.Where(claim =>
claim.Type == CustomClaimTypes.ResourceAccess &&
claim.ValueType == "JSON")
.SelectMany(claim =>
JsonValue.Parse(claim.Value) is JsonObject jsonObject &&
jsonObject.TryGetValue(
_options.TokenValidationParameters.ValidAudience,
out var audience) &&
audience is JsonObject client &&
client.TryGetValue("roles", out var jsonRoles) &&
jsonRoles is JsonArray roles
? roles.Where(x => x.JsonType == JsonType.String)
.Select(role => new Claim(ClaimTypes.Role, role))
: Enumerable.Empty<Claim>())
.IfAny(claims =>
{
foreach (var claim in claims)
{
claimsIdentity.AddClaim(claim);
}
});
}
}
2 changes: 2 additions & 0 deletions src/web/Dim.Web/Controllers/DimController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public static RouteGroupBuilder MapDimApi(this RouteGroupBuilder group)
"the name of the company",
"bpn of the wallets company",
"The did document location")
.RequireAuthorization(r => r.RequireRole("setup_wallet"))
.Produces(StatusCodes.Status201Created);

policyHub.MapPost("setup-issuer", ([FromQuery] string companyName, [FromQuery] string bpn, [FromQuery] string didDocumentLocation, IDimBusinessLogic dimBusinessLogic) => dimBusinessLogic.StartSetupDim(companyName, bpn, didDocumentLocation, true))
Expand All @@ -46,6 +47,7 @@ public static RouteGroupBuilder MapDimApi(this RouteGroupBuilder group)
"the name of the company",
"bpn of the wallets company",
"The did document location")
.RequireAuthorization(r => r.RequireRole("setup_wallet"))
.Produces(StatusCodes.Status201Created);

return group;
Expand Down
1 change: 1 addition & 0 deletions src/web/Dim.Web/Dim.Web.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.10"/>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0"/>
<PackageReference Include="Org.Eclipse.TractusX.Portal.Backend.Framework.Web" Version="1.3.0"/>
<PackageReference Include="System.Json" Version="4.7.1" />
</ItemGroup>

<ItemGroup>
Expand Down
3 changes: 3 additions & 0 deletions src/web/Dim.Web/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
********************************************************************************/

using Dim.DbAccess.DependencyInjection;
using Dim.Web.Authentication;
using Dim.Web.Controllers;
using Dim.Web.Extensions;
using Microsoft.AspNetCore.Authentication;
using Org.Eclipse.TractusX.Portal.Backend.Framework.Web;
using System.Text.Json.Serialization;

Expand All @@ -30,6 +32,7 @@
builder =>
{
builder.Services
.AddTransient<IClaimsTransformation, KeycloakClaimsTransformation>()
.AddDim(builder.Configuration.GetSection("Dim"))
.AddEndpointsApiExplorer()
.AddDatabase(builder.Configuration)
Expand Down
16 changes: 15 additions & 1 deletion src/web/Dim.Web/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,19 @@
"Dim": {
"RootDirectoryId": ""
},
"SwaggerEnabled": false
"SwaggerEnabled": false,
"JwtBearerOptions": {
"RequireHttpsMetadata": true,
"MetadataAddress": "",
"SaveToken": true,
"TokenValidationParameters": {
"ValidateIssuer": true,
"ValidIssuer": "",
"ValidateIssuerSigningKey": true,
"ValidAudience": "",
"ValidateAudience": true,
"ValidateLifetime": true,
"ClockSkew": 600000
}
}
}

0 comments on commit 221a435

Please sign in to comment.