From 906fb52f8e0ca7e8e5e9d0f09554a99d416a08c0 Mon Sep 17 00:00:00 2001 From: "GRUPOGMV\\ssis" Date: Thu, 4 Jul 2024 08:47:02 +0200 Subject: [PATCH 01/10] =?UTF-8?q?extensiones=20de=20auditor=C3=ADa?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extensions/audit-configuration/README.md | 18 ++++++ .../audit-configuration/build.gradle.kts | 17 ++++++ .../upm/inesdata/audit/AuditExtension.java | 34 +++++++++++ .../audit/HttpRequestInterceptor.java | 56 +++++++++++++++++++ ...rg.eclipse.edc.spi.system.ServiceExtension | 1 + .../audit-event-configuration/README.md | 18 ++++++ .../build.gradle.kts | 17 ++++++ .../auditevent/AuditEventSubscriber.java | 20 +++++++ .../AuditEventSubscriptionExtension.java | 21 +++++++ ...rg.eclipse.edc.spi.system.ServiceExtension | 1 + launchers/connector/build.gradle.kts | 4 ++ settings.gradle.kts | 2 + 12 files changed, 209 insertions(+) create mode 100644 extensions/audit-configuration/README.md create mode 100644 extensions/audit-configuration/build.gradle.kts create mode 100644 extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/AuditExtension.java create mode 100644 extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/HttpRequestInterceptor.java create mode 100644 extensions/audit-configuration/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension create mode 100644 extensions/audit-event-configuration/README.md create mode 100644 extensions/audit-event-configuration/build.gradle.kts create mode 100644 extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriber.java create mode 100644 extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriptionExtension.java create mode 100644 extensions/audit-event-configuration/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension diff --git a/extensions/audit-configuration/README.md b/extensions/audit-configuration/README.md new file mode 100644 index 0000000..51bb140 --- /dev/null +++ b/extensions/audit-configuration/README.md @@ -0,0 +1,18 @@ +# Oauth2 JWT Token Authentication Service + +This extension provides the capability to authorizate the request to the connector management API. The extension will access the Bearer token provided in the Authorization header and validate that it is a valid JWT-encoded bearer token. It is necessary to have the `org.eclipse.edc:oauth2-core` extension correctly configured. + +To authorize a user, the roles of the provided JWT token must contain: +- a valid role from those configured in `allowedRoles` +- a role with the `connector name` + +## Configuration + +Example configuration: + +```properties +edc.api.auth.oauth2.allowedRoles.1.role=connector-admin +edc.api.auth.oauth2.allowedRoles.2.role=connector-management +``` + +The `edc.api.auth.oauth2.allowedRoles` will be used by the federated catalog to retrieve the list of allowed roles that can perform requests on the managemente API connector. \ No newline at end of file diff --git a/extensions/audit-configuration/build.gradle.kts b/extensions/audit-configuration/build.gradle.kts new file mode 100644 index 0000000..9261f24 --- /dev/null +++ b/extensions/audit-configuration/build.gradle.kts @@ -0,0 +1,17 @@ +plugins { + `java-library` + id("com.gmv.inesdata.edc-application") +} + +dependencies { + api(libs.edc.auth.spi) + + implementation(libs.edc.iam.oauth2.core) + implementation(libs.jakarta.rsApi) + + testImplementation(libs.edc.core.junit) + testImplementation(libs.assertj) + testImplementation(libs.mockito.core) +} + + diff --git a/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/AuditExtension.java b/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/AuditExtension.java new file mode 100644 index 0000000..3583152 --- /dev/null +++ b/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/AuditExtension.java @@ -0,0 +1,34 @@ +package org.upm.inesdata.audit; + +import jakarta.servlet.Filter; +import org.eclipse.edc.runtime.metamodel.annotation.Extension; +import org.eclipse.edc.runtime.metamodel.annotation.Inject; +import org.eclipse.edc.runtime.metamodel.annotation.Provides; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.system.ServiceExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.web.spi.WebService; + +@Provides(HttpRequestInterceptor.class) +@Extension(value = AuditExtension.NAME) +public class AuditExtension implements ServiceExtension { + + public static final String NAME = "Audit configuration"; + + + @Inject + private WebService webService; + + @Override + public String name() { + return NAME; + } + + @Override + public void initialize(ServiceExtensionContext context) { + // Registrar el interceptor HTTP + context.registerService(Filter.class, new HttpRequestInterceptor(context.getMonitor())); + webService.registerResource(new HttpRequestInterceptor(context.getMonitor())); + context.getMonitor().info("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - Registered Filter"); + } +} diff --git a/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/HttpRequestInterceptor.java b/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/HttpRequestInterceptor.java new file mode 100644 index 0000000..b16c213 --- /dev/null +++ b/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/HttpRequestInterceptor.java @@ -0,0 +1,56 @@ +package org.upm.inesdata.audit; + +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.annotation.WebFilter; +import jakarta.servlet.http.HttpServletRequest; +import org.eclipse.edc.spi.monitor.Monitor; + +import java.io.IOException; +import java.util.Enumeration; + +@WebFilter("/*") +public class HttpRequestInterceptor implements Filter { + + private final Monitor monitor; + + public HttpRequestInterceptor(Monitor monitor) { + this.monitor = monitor; + } + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + // Inicialización si es necesaria + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + + HttpServletRequest httpRequest = (HttpServletRequest) request; + + // Auditar la petición + monitor.info("Intercepted Request: "); + monitor.info("Method: " + httpRequest.getMethod()); + monitor.info("URL: " + httpRequest.getRequestURL().toString()); + + // Imprimir cabeceras + Enumeration headerNames = httpRequest.getHeaderNames(); + while (headerNames.hasMoreElements()) { + String headerName = headerNames.nextElement(); + monitor.info(headerName + ": " + httpRequest.getHeader(headerName)); + } + + // Continuar con el siguiente filtro o recurso + chain.doFilter(request, response); + } + + @Override + public void destroy() { + // Limpieza si es necesaria + } +} \ No newline at end of file diff --git a/extensions/audit-configuration/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/extensions/audit-configuration/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension new file mode 100644 index 0000000..933cff4 --- /dev/null +++ b/extensions/audit-configuration/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -0,0 +1 @@ +org.upm.inesdata.audit.AuditExtension diff --git a/extensions/audit-event-configuration/README.md b/extensions/audit-event-configuration/README.md new file mode 100644 index 0000000..51bb140 --- /dev/null +++ b/extensions/audit-event-configuration/README.md @@ -0,0 +1,18 @@ +# Oauth2 JWT Token Authentication Service + +This extension provides the capability to authorizate the request to the connector management API. The extension will access the Bearer token provided in the Authorization header and validate that it is a valid JWT-encoded bearer token. It is necessary to have the `org.eclipse.edc:oauth2-core` extension correctly configured. + +To authorize a user, the roles of the provided JWT token must contain: +- a valid role from those configured in `allowedRoles` +- a role with the `connector name` + +## Configuration + +Example configuration: + +```properties +edc.api.auth.oauth2.allowedRoles.1.role=connector-admin +edc.api.auth.oauth2.allowedRoles.2.role=connector-management +``` + +The `edc.api.auth.oauth2.allowedRoles` will be used by the federated catalog to retrieve the list of allowed roles that can perform requests on the managemente API connector. \ No newline at end of file diff --git a/extensions/audit-event-configuration/build.gradle.kts b/extensions/audit-event-configuration/build.gradle.kts new file mode 100644 index 0000000..9261f24 --- /dev/null +++ b/extensions/audit-event-configuration/build.gradle.kts @@ -0,0 +1,17 @@ +plugins { + `java-library` + id("com.gmv.inesdata.edc-application") +} + +dependencies { + api(libs.edc.auth.spi) + + implementation(libs.edc.iam.oauth2.core) + implementation(libs.jakarta.rsApi) + + testImplementation(libs.edc.core.junit) + testImplementation(libs.assertj) + testImplementation(libs.mockito.core) +} + + diff --git a/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriber.java b/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriber.java new file mode 100644 index 0000000..3a1fcff --- /dev/null +++ b/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriber.java @@ -0,0 +1,20 @@ +package org.upm.inesdata.auditevent; + +import org.eclipse.edc.spi.event.Event; +import org.eclipse.edc.spi.event.EventEnvelope; +import org.eclipse.edc.spi.event.EventSubscriber; +import org.eclipse.edc.spi.monitor.Monitor; + +public class AuditEventSubscriber implements EventSubscriber { + + private final Monitor monitor; + + public AuditEventSubscriber(Monitor monitor) { + this.monitor = monitor; + } + + @Override + public void on(EventEnvelope event) { + monitor.info("el evento"+event.getPayload().toString()); + } +} \ No newline at end of file diff --git a/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriptionExtension.java b/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriptionExtension.java new file mode 100644 index 0000000..f9fe934 --- /dev/null +++ b/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriptionExtension.java @@ -0,0 +1,21 @@ +package org.upm.inesdata.auditevent; + +import org.eclipse.edc.runtime.metamodel.annotation.Inject; +import org.eclipse.edc.spi.event.Event; +import org.eclipse.edc.spi.event.EventRouter; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.system.ServiceExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; + +public class AuditEventSubscriptionExtension implements ServiceExtension { + @Inject + private EventRouter eventRouter; + @Inject + private Monitor monitor; + + @Override + public void initialize(ServiceExtensionContext context) { + eventRouter.register(Event.class, new AuditEventSubscriber(monitor)); + eventRouter.registerSync(Event.class, new AuditEventSubscriber(monitor)); + } +} \ No newline at end of file diff --git a/extensions/audit-event-configuration/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/extensions/audit-event-configuration/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension new file mode 100644 index 0000000..10363ec --- /dev/null +++ b/extensions/audit-event-configuration/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -0,0 +1 @@ +org.upm.inesdata.auditevent.AuditEventSubscriptionExtension diff --git a/launchers/connector/build.gradle.kts b/launchers/connector/build.gradle.kts index 7d485ea..abc1da3 100644 --- a/launchers/connector/build.gradle.kts +++ b/launchers/connector/build.gradle.kts @@ -93,6 +93,10 @@ dependencies { //Data plane public api implementation(project(":extensions:extended-data-plane-public-api")) + // Storage assets + implementation(project(":extensions:audit-configuration")) + implementation(project(":extensions:audit-event-configuration")) + runtimeOnly(libs.edc.transaction.local) runtimeOnly(libs.postgres) } diff --git a/settings.gradle.kts b/settings.gradle.kts index 7803ccb..49a1eef 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -23,6 +23,8 @@ include(":extensions:federated-catalog-cache-api") include(":extensions:count-elements-api") include(":extensions:count-elements-sql") include(":extensions:extended-data-plane-public-api") +include(":extensions:audit-configuration") +include(":extensions:audit-event-configuration") // Connector include(":launchers:connector") From ebba017bbfbbaf383c1ff21a8d5a8bc8784f753d Mon Sep 17 00:00:00 2001 From: "GRUPOGMV\\ssis" Date: Thu, 4 Jul 2024 09:31:07 +0200 Subject: [PATCH 02/10] Control --- .../src/main/java/org/upm/inesdata/audit/AuditExtension.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/AuditExtension.java b/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/AuditExtension.java index 3583152..fd9072d 100644 --- a/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/AuditExtension.java +++ b/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/AuditExtension.java @@ -8,6 +8,7 @@ import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.edc.web.spi.WebService; +import org.eclipse.edc.web.spi.configuration.ApiContext; @Provides(HttpRequestInterceptor.class) @Extension(value = AuditExtension.NAME) @@ -28,7 +29,7 @@ public String name() { public void initialize(ServiceExtensionContext context) { // Registrar el interceptor HTTP context.registerService(Filter.class, new HttpRequestInterceptor(context.getMonitor())); - webService.registerResource(new HttpRequestInterceptor(context.getMonitor())); + webService.registerResource(ApiContext.CONTROL,new HttpRequestInterceptor(context.getMonitor())); context.getMonitor().info("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - Registered Filter"); } } From d0cabaa2d6bfdaca123e991c09ae00c0640059a3 Mon Sep 17 00:00:00 2001 From: "GRUPOGMV\\ssis" Date: Thu, 4 Jul 2024 11:09:22 +0200 Subject: [PATCH 03/10] Cambios en la auditoria --- .../upm/inesdata/audit/AuditExtension.java | 3 +- .../audit/HttpRequestInterceptor.java | 46 +++++-------------- 2 files changed, 12 insertions(+), 37 deletions(-) diff --git a/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/AuditExtension.java b/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/AuditExtension.java index fd9072d..7069697 100644 --- a/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/AuditExtension.java +++ b/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/AuditExtension.java @@ -28,8 +28,7 @@ public String name() { @Override public void initialize(ServiceExtensionContext context) { // Registrar el interceptor HTTP - context.registerService(Filter.class, new HttpRequestInterceptor(context.getMonitor())); - webService.registerResource(ApiContext.CONTROL,new HttpRequestInterceptor(context.getMonitor())); + webService.registerResource(ApiContext.MANAGEMENT,new HttpRequestInterceptor(context.getMonitor())); context.getMonitor().info("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - Registered Filter"); } } diff --git a/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/HttpRequestInterceptor.java b/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/HttpRequestInterceptor.java index b16c213..85e0d69 100644 --- a/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/HttpRequestInterceptor.java +++ b/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/HttpRequestInterceptor.java @@ -1,20 +1,15 @@ package org.upm.inesdata.audit; -import jakarta.servlet.Filter; -import jakarta.servlet.FilterChain; -import jakarta.servlet.FilterConfig; -import jakarta.servlet.ServletException; -import jakarta.servlet.ServletRequest; -import jakarta.servlet.ServletResponse; -import jakarta.servlet.annotation.WebFilter; -import jakarta.servlet.http.HttpServletRequest; import org.eclipse.edc.spi.monitor.Monitor; +import jakarta.ws.rs.container.ContainerRequestContext; +import jakarta.ws.rs.container.ContainerRequestFilter; +import jakarta.ws.rs.ext.Provider; import java.io.IOException; import java.util.Enumeration; -@WebFilter("/*") -public class HttpRequestInterceptor implements Filter { +@Provider +public class HttpRequestInterceptor implements ContainerRequestFilter { private final Monitor monitor; @@ -23,34 +18,15 @@ public HttpRequestInterceptor(Monitor monitor) { } @Override - public void init(FilterConfig filterConfig) throws ServletException { - // Inicialización si es necesaria - } - - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) - throws IOException, ServletException { - - HttpServletRequest httpRequest = (HttpServletRequest) request; - + public void filter(ContainerRequestContext requestContext) throws IOException { // Auditar la petición monitor.info("Intercepted Request: "); - monitor.info("Method: " + httpRequest.getMethod()); - monitor.info("URL: " + httpRequest.getRequestURL().toString()); + monitor.info("Method: " + requestContext.getMethod()); + monitor.info("URL: " + requestContext.getUriInfo().getRequestUri().toString()); // Imprimir cabeceras - Enumeration headerNames = httpRequest.getHeaderNames(); - while (headerNames.hasMoreElements()) { - String headerName = headerNames.nextElement(); - monitor.info(headerName + ": " + httpRequest.getHeader(headerName)); + for (String headerName : requestContext.getHeaders().keySet()) { + monitor.info(headerName + ": " + String.join(", ", requestContext.getHeaders().get(headerName))); } - - // Continuar con el siguiente filtro o recurso - chain.doFilter(request, response); - } - - @Override - public void destroy() { - // Limpieza si es necesaria } -} \ No newline at end of file +} From c5a0536c3d8e73187b7eb5826f43ad5eebb557a4 Mon Sep 17 00:00:00 2001 From: "GRUPOGMV\\ssis" Date: Thu, 4 Jul 2024 13:58:40 +0200 Subject: [PATCH 04/10] Logs --- .../audit/HttpRequestInterceptor.java | 23 ++++++++----------- .../build.gradle.kts | 2 ++ .../auditevent/AuditEventSubscriber.java | 15 +++++++++++- gradle/libs.versions.toml | 2 ++ 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/HttpRequestInterceptor.java b/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/HttpRequestInterceptor.java index 85e0d69..8908a37 100644 --- a/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/HttpRequestInterceptor.java +++ b/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/HttpRequestInterceptor.java @@ -1,12 +1,11 @@ package org.upm.inesdata.audit; -import org.eclipse.edc.spi.monitor.Monitor; - import jakarta.ws.rs.container.ContainerRequestContext; import jakarta.ws.rs.container.ContainerRequestFilter; import jakarta.ws.rs.ext.Provider; -import java.io.IOException; -import java.util.Enumeration; +import org.eclipse.edc.spi.monitor.Monitor; + +import java.text.MessageFormat; @Provider public class HttpRequestInterceptor implements ContainerRequestFilter { @@ -18,15 +17,11 @@ public HttpRequestInterceptor(Monitor monitor) { } @Override - public void filter(ContainerRequestContext requestContext) throws IOException { - // Auditar la petición - monitor.info("Intercepted Request: "); - monitor.info("Method: " + requestContext.getMethod()); - monitor.info("URL: " + requestContext.getUriInfo().getRequestUri().toString()); - - // Imprimir cabeceras - for (String headerName : requestContext.getHeaders().keySet()) { - monitor.info(headerName + ": " + String.join(", ", requestContext.getHeaders().get(headerName))); - } + public void filter(ContainerRequestContext requestContext){ + // Formatear y registrar el mensaje de auditoría + String auditLog = MessageFormat.format("[AUDIT][MANAGEMENT] User ''{0}'' calls ''{1}''", + "USER", + requestContext.getUriInfo().getRequestUri().toString()); + monitor.info(auditLog); } } diff --git a/extensions/audit-event-configuration/build.gradle.kts b/extensions/audit-event-configuration/build.gradle.kts index 9261f24..191d231 100644 --- a/extensions/audit-event-configuration/build.gradle.kts +++ b/extensions/audit-event-configuration/build.gradle.kts @@ -8,6 +8,8 @@ dependencies { implementation(libs.edc.iam.oauth2.core) implementation(libs.jakarta.rsApi) + implementation(libs.edc.contract.spi) + implementation(libs.edc.transfer.spi) testImplementation(libs.edc.core.junit) testImplementation(libs.assertj) diff --git a/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriber.java b/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriber.java index 3a1fcff..520f4f2 100644 --- a/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriber.java +++ b/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriber.java @@ -1,10 +1,14 @@ package org.upm.inesdata.auditevent; +import org.eclipse.edc.connector.controlplane.contract.spi.event.contractnegotiation.ContractNegotiationEvent; +import org.eclipse.edc.connector.controlplane.transfer.spi.event.TransferProcessEvent; import org.eclipse.edc.spi.event.Event; import org.eclipse.edc.spi.event.EventEnvelope; import org.eclipse.edc.spi.event.EventSubscriber; import org.eclipse.edc.spi.monitor.Monitor; +import java.text.MessageFormat; + public class AuditEventSubscriber implements EventSubscriber { private final Monitor monitor; @@ -15,6 +19,15 @@ public AuditEventSubscriber(Monitor monitor) { @Override public void on(EventEnvelope event) { - monitor.info("el evento"+event.getPayload().toString()); + if(event.getPayload() instanceof ContractNegotiationEvent){ + String simpleName = event.getPayload().getClass().getSimpleName(); + ContractNegotiationEvent payload = (ContractNegotiationEvent) event.getPayload(); + monitor.info(MessageFormat.format("[AUDIT][DSP] {0} from counterPartyId '{1}' with contractNegotiationId '{2}'",simpleName, payload.getCounterPartyId(),payload.getContractNegotiationId())); + }else if (event.getPayload() instanceof TransferProcessEvent){ + String simpleName = event.getPayload().getClass().getSimpleName(); + TransferProcessEvent payload = (TransferProcessEvent) event.getPayload(); + monitor.info(MessageFormat.format("[AUDIT][DSP] {0} from contractId '{1}' with assetId '{2}' for type '{3}'",simpleName, payload.getContractId(),payload.getAssetId(),payload.getType())); + } + } } \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2875eef..deb5e1f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -26,6 +26,7 @@ edc-auth-spi = { module = "org.eclipse.edc:auth-spi", version.ref = "edc" } edc-build-plugin = { module = "org.eclipse.edc.edc-build:org.eclipse.edc.edc-build.gradle.plugin", version.ref = "edc" } edc-configuration-filesystem = { module = "org.eclipse.edc:configuration-filesystem", version.ref = "edc" } edc-connector-core = { module = "org.eclipse.edc:connector-core", version.ref = "edc" } +edc-contract-spi = { module = "org.eclipse.edc:contract-spi", version.ref = "edc" } edc-control-plane-api = { module = "org.eclipse.edc:control-plane-api", version.ref = "edc" } edc-control-plane-api-client = { module = "org.eclipse.edc:control-plane-api-client", version.ref = "edc" } edc-control-plane-core = { module = "org.eclipse.edc:control-plane-core", version.ref = "edc" } @@ -62,6 +63,7 @@ edc-transaction-local = { module = "org.eclipse.edc:transaction-local", version. edc-transaction-spi = { module = "org.eclipse.edc:transaction-spi", version.ref = "edc" } edc-transfer-data-plane-signaling = { module = "org.eclipse.edc:transfer-data-plane-signaling", version.ref = "edc" } edc-transfer-pull-http-receiver = { module = "org.eclipse.edc:transfer-pull-http-dynamic-receiver", version.ref = "edc" } +edc-transfer-spi = { module = "org.eclipse.edc:transfer-spi", version.ref = "edc" } edc-validator-data-address-http-data = { module = "org.eclipse.edc:validator-data-address-http-data", version.ref = "edc" } edc-validator-spi = { module = "org.eclipse.edc:validator-spi", version.ref = "edc" } edc-vault-hashicorp = { module = "org.eclipse.edc:vault-hashicorp", version.ref = "edc" } From 368fdc61a2525a89e13809cb02a7455b1c53107b Mon Sep 17 00:00:00 2001 From: "GRUPOGMV\\ssis" Date: Thu, 4 Jul 2024 14:07:08 +0200 Subject: [PATCH 05/10] Log mensaje --- .../org/upm/inesdata/auditevent/AuditEventSubscriber.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriber.java b/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriber.java index 520f4f2..316a414 100644 --- a/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriber.java +++ b/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriber.java @@ -22,11 +22,11 @@ public void on(EventEnvelope event) { if(event.getPayload() instanceof ContractNegotiationEvent){ String simpleName = event.getPayload().getClass().getSimpleName(); ContractNegotiationEvent payload = (ContractNegotiationEvent) event.getPayload(); - monitor.info(MessageFormat.format("[AUDIT][DSP] {0} from counterPartyId '{1}' with contractNegotiationId '{2}'",simpleName, payload.getCounterPartyId(),payload.getContractNegotiationId())); + monitor.info(MessageFormat.format("[AUDIT][DSP] '{0}' from counterPartyId ''{1}'' with contractNegotiationId ''{2}''",simpleName, payload.getCounterPartyId(),payload.getContractNegotiationId())); }else if (event.getPayload() instanceof TransferProcessEvent){ String simpleName = event.getPayload().getClass().getSimpleName(); TransferProcessEvent payload = (TransferProcessEvent) event.getPayload(); - monitor.info(MessageFormat.format("[AUDIT][DSP] {0} from contractId '{1}' with assetId '{2}' for type '{3}'",simpleName, payload.getContractId(),payload.getAssetId(),payload.getType())); + monitor.info(MessageFormat.format("[AUDIT][DSP] '{0}' from contractId ''{1}'' with assetId ''{2}'' for type ''{3}''",simpleName, payload.getContractId(),payload.getAssetId(),payload.getType())); } } From d713feb5150ed98d04a9ab9bf801fe7509e938f1 Mon Sep 17 00:00:00 2001 From: "GRUPOGMV\\ssis" Date: Thu, 4 Jul 2024 14:17:43 +0200 Subject: [PATCH 06/10] Logs --- .../org/upm/inesdata/auditevent/AuditEventSubscriber.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriber.java b/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriber.java index 316a414..4482173 100644 --- a/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriber.java +++ b/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriber.java @@ -22,11 +22,11 @@ public void on(EventEnvelope event) { if(event.getPayload() instanceof ContractNegotiationEvent){ String simpleName = event.getPayload().getClass().getSimpleName(); ContractNegotiationEvent payload = (ContractNegotiationEvent) event.getPayload(); - monitor.info(MessageFormat.format("[AUDIT][DSP] '{0}' from counterPartyId ''{1}'' with contractNegotiationId ''{2}''",simpleName, payload.getCounterPartyId(),payload.getContractNegotiationId())); + monitor.info(MessageFormat.format("[AUDIT][DSP] ''{0}'' from counterPartyId ''{1}'' with contractNegotiationId ''{2}''",simpleName, payload.getCounterPartyId(),payload.getContractNegotiationId())); }else if (event.getPayload() instanceof TransferProcessEvent){ String simpleName = event.getPayload().getClass().getSimpleName(); TransferProcessEvent payload = (TransferProcessEvent) event.getPayload(); - monitor.info(MessageFormat.format("[AUDIT][DSP] '{0}' from contractId ''{1}'' with assetId ''{2}'' for type ''{3}''",simpleName, payload.getContractId(),payload.getAssetId(),payload.getType())); + monitor.info(MessageFormat.format("[AUDIT][DSP] ''{0}'' from contractId ''{1}'' with assetId ''{2}'' for type ''{3}''",simpleName, payload.getContractId(),payload.getAssetId(),payload.getType())); } } From 732d18e1558670d470ef943174aeedaceddec047 Mon Sep 17 00:00:00 2001 From: "GRUPOGMV\\ssis" Date: Fri, 5 Jul 2024 09:33:57 +0200 Subject: [PATCH 07/10] Cambios token y participant --- .../upm/inesdata/audit/AuditExtension.java | 10 ++--- .../audit/HttpRequestInterceptor.java | 44 +++++++++++++++++-- .../auditevent/AuditEventSubscriber.java | 8 ++-- .../AuditEventSubscriptionExtension.java | 4 +- 4 files changed, 52 insertions(+), 14 deletions(-) diff --git a/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/AuditExtension.java b/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/AuditExtension.java index 7069697..ccbe050 100644 --- a/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/AuditExtension.java +++ b/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/AuditExtension.java @@ -1,10 +1,9 @@ package org.upm.inesdata.audit; -import jakarta.servlet.Filter; import org.eclipse.edc.runtime.metamodel.annotation.Extension; import org.eclipse.edc.runtime.metamodel.annotation.Inject; import org.eclipse.edc.runtime.metamodel.annotation.Provides; -import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.iam.IdentityService; import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.edc.web.spi.WebService; @@ -20,6 +19,9 @@ public class AuditExtension implements ServiceExtension { @Inject private WebService webService; + @Inject + private IdentityService identityService; + @Override public String name() { return NAME; @@ -27,8 +29,6 @@ public String name() { @Override public void initialize(ServiceExtensionContext context) { - // Registrar el interceptor HTTP - webService.registerResource(ApiContext.MANAGEMENT,new HttpRequestInterceptor(context.getMonitor())); - context.getMonitor().info("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - Registered Filter"); + webService.registerResource(ApiContext.MANAGEMENT,new HttpRequestInterceptor(context.getMonitor(), identityService, context.getParticipantId())); } } diff --git a/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/HttpRequestInterceptor.java b/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/HttpRequestInterceptor.java index 8908a37..022d9e4 100644 --- a/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/HttpRequestInterceptor.java +++ b/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/HttpRequestInterceptor.java @@ -3,25 +3,61 @@ import jakarta.ws.rs.container.ContainerRequestContext; import jakarta.ws.rs.container.ContainerRequestFilter; import jakarta.ws.rs.ext.Provider; +import org.eclipse.edc.spi.iam.IdentityService; +import org.eclipse.edc.spi.iam.TokenRepresentation; import org.eclipse.edc.spi.monitor.Monitor; import java.text.MessageFormat; +import java.util.List; +import java.util.Map; @Provider public class HttpRequestInterceptor implements ContainerRequestFilter { + private static final String TEMPLATE_AUDIT_LOG = "[AUDIT][''{0}''][MANAGEMENT] User ''{1}'' calls ''{2}''"; + + private static final String BEARER_PREFIX = "Bearer "; + private static final String REALM_ACCESS_CLAIM_NAME = "realm_access"; + private static final String ROLES_NAME = "roles"; + public static final String TOKEN_PROPERTY_PREFERRED_USERNAME = "preferred_username"; + private final Monitor monitor; + private final IdentityService identityService; - public HttpRequestInterceptor(Monitor monitor) { + private final String participantId; + + public HttpRequestInterceptor(Monitor monitor, IdentityService identityService, String participantId) { this.monitor = monitor; + this.identityService = identityService; + this.participantId = participantId; } @Override public void filter(ContainerRequestContext requestContext){ - // Formatear y registrar el mensaje de auditoría - String auditLog = MessageFormat.format("[AUDIT][MANAGEMENT] User ''{0}'' calls ''{1}''", - "USER", + String user = getUserFromRequest(requestContext); + String auditLog = MessageFormat.format(TEMPLATE_AUDIT_LOG, participantId, + user, requestContext.getUriInfo().getRequestUri().toString()); monitor.info(auditLog); } + + private String getUserFromRequest(ContainerRequestContext requestContext) { + List authorizationHeaders = requestContext.getHeaders().get("Authorization"); + if (authorizationHeaders != null && !authorizationHeaders.isEmpty()) { + String authHeader = authorizationHeaders.get(0); + if (authHeader.startsWith(BEARER_PREFIX)) { + String token = authHeader.replace(BEARER_PREFIX, ""); + return decodeJWT(token); + } + } + return "NotAuthenticatedUser"; + } + + private String decodeJWT(String token) { + var tokenRepresentation = TokenRepresentation.Builder.newInstance().token(token).build(); + var tokenValidation = identityService.verifyJwtToken(tokenRepresentation, null); + var claimToken = tokenValidation.getContent(); + var realmAccess = (Map) claimToken.getClaim(REALM_ACCESS_CLAIM_NAME); + return (String) realmAccess.get(TOKEN_PROPERTY_PREFERRED_USERNAME); + } } diff --git a/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriber.java b/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriber.java index 4482173..0a63a37 100644 --- a/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriber.java +++ b/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriber.java @@ -12,9 +12,11 @@ public class AuditEventSubscriber implements EventSubscriber { private final Monitor monitor; + private final String participantId; - public AuditEventSubscriber(Monitor monitor) { + public AuditEventSubscriber(Monitor monitor, String participantId) { this.monitor = monitor; + this.participantId = participantId; } @Override @@ -22,11 +24,11 @@ public void on(EventEnvelope event) { if(event.getPayload() instanceof ContractNegotiationEvent){ String simpleName = event.getPayload().getClass().getSimpleName(); ContractNegotiationEvent payload = (ContractNegotiationEvent) event.getPayload(); - monitor.info(MessageFormat.format("[AUDIT][DSP] ''{0}'' from counterPartyId ''{1}'' with contractNegotiationId ''{2}''",simpleName, payload.getCounterPartyId(),payload.getContractNegotiationId())); + monitor.info(MessageFormat.format("[AUDIT][''{0}''][DSP] ''{1}'' from counterPartyId ''{2}'' with contractNegotiationId ''{3}''",participantId,simpleName, payload.getCounterPartyId(),payload.getContractNegotiationId())); }else if (event.getPayload() instanceof TransferProcessEvent){ String simpleName = event.getPayload().getClass().getSimpleName(); TransferProcessEvent payload = (TransferProcessEvent) event.getPayload(); - monitor.info(MessageFormat.format("[AUDIT][DSP] ''{0}'' from contractId ''{1}'' with assetId ''{2}'' for type ''{3}''",simpleName, payload.getContractId(),payload.getAssetId(),payload.getType())); + monitor.info(MessageFormat.format("[AUDIT][''{0}''][DSP] ''{1}'' from contractId ''{2}'' with assetId ''{3}'' for type ''{4}''",participantId,simpleName, payload.getContractId(),payload.getAssetId(),payload.getType())); } } diff --git a/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriptionExtension.java b/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriptionExtension.java index f9fe934..d4bc9bb 100644 --- a/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriptionExtension.java +++ b/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriptionExtension.java @@ -15,7 +15,7 @@ public class AuditEventSubscriptionExtension implements ServiceExtension { @Override public void initialize(ServiceExtensionContext context) { - eventRouter.register(Event.class, new AuditEventSubscriber(monitor)); - eventRouter.registerSync(Event.class, new AuditEventSubscriber(monitor)); + eventRouter.register(Event.class, new AuditEventSubscriber(monitor,context.getParticipantId())); + eventRouter.registerSync(Event.class, new AuditEventSubscriber(monitor, context.getParticipantId())); } } \ No newline at end of file From 0160b7d0cfe28c389eb17cc68e148e4824d40d6c Mon Sep 17 00:00:00 2001 From: "GRUPOGMV\\ssis" Date: Fri, 5 Jul 2024 09:54:09 +0200 Subject: [PATCH 08/10] Error claims --- .../java/org/upm/inesdata/audit/HttpRequestInterceptor.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/HttpRequestInterceptor.java b/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/HttpRequestInterceptor.java index 022d9e4..acaf1d9 100644 --- a/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/HttpRequestInterceptor.java +++ b/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/HttpRequestInterceptor.java @@ -56,8 +56,6 @@ private String getUserFromRequest(ContainerRequestContext requestContext) { private String decodeJWT(String token) { var tokenRepresentation = TokenRepresentation.Builder.newInstance().token(token).build(); var tokenValidation = identityService.verifyJwtToken(tokenRepresentation, null); - var claimToken = tokenValidation.getContent(); - var realmAccess = (Map) claimToken.getClaim(REALM_ACCESS_CLAIM_NAME); - return (String) realmAccess.get(TOKEN_PROPERTY_PREFERRED_USERNAME); + return (String) tokenValidation.getContent().getClaims().get(TOKEN_PROPERTY_PREFERRED_USERNAME); } } From a21fabb1f5c5df0bffdd31db0aa041468849d32d Mon Sep 17 00:00:00 2001 From: "GRUPOGMV\\ssis" Date: Fri, 5 Jul 2024 10:52:08 +0200 Subject: [PATCH 09/10] =?UTF-8?q?=C3=9Altimos=20retoques?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extensions/audit-configuration/README.md | 21 +++----- .../upm/inesdata/audit/AuditExtension.java | 17 ++++++- .../audit/HttpRequestInterceptor.java | 50 ++++++++++++++----- .../audit-event-configuration/README.md | 18 +++---- .../build.gradle.kts | 3 +- .../auditevent/AuditEventSubscriber.java | 29 ++++++++--- .../AuditEventSubscriptionExtension.java | 13 ++++- 7 files changed, 103 insertions(+), 48 deletions(-) diff --git a/extensions/audit-configuration/README.md b/extensions/audit-configuration/README.md index 51bb140..cfc1bee 100644 --- a/extensions/audit-configuration/README.md +++ b/extensions/audit-configuration/README.md @@ -1,18 +1,13 @@ -# Oauth2 JWT Token Authentication Service +# Audit Extension -This extension provides the capability to authorizate the request to the connector management API. The extension will access the Bearer token provided in the Authorization header and validate that it is a valid JWT-encoded bearer token. It is necessary to have the `org.eclipse.edc:oauth2-core` extension correctly configured. +This extension provides the capability to log audit events for HTTP requests made to the connector management API. The `AuditExtension` registers an `HttpRequestInterceptor` that logs details about the user making the request and the request URI. -To authorize a user, the roles of the provided JWT token must contain: -- a valid role from those configured in `allowedRoles` -- a role with the `connector name` +## Features -## Configuration - -Example configuration: +- Logs audit details for incoming HTTP requests. +- Extracts and verifies JWT tokens to log the username. +- Configurable participant ID for audit logging. -```properties -edc.api.auth.oauth2.allowedRoles.1.role=connector-admin -edc.api.auth.oauth2.allowedRoles.2.role=connector-management -``` +## Configuration -The `edc.api.auth.oauth2.allowedRoles` will be used by the federated catalog to retrieve the list of allowed roles that can perform requests on the managemente API connector. \ No newline at end of file +To configure the audit logging, you need to ensure that the `HttpRequestInterceptor` is registered with the web service. This is done within the `AuditExtension` class. diff --git a/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/AuditExtension.java b/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/AuditExtension.java index ccbe050..249a585 100644 --- a/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/AuditExtension.java +++ b/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/AuditExtension.java @@ -9,26 +9,39 @@ import org.eclipse.edc.web.spi.WebService; import org.eclipse.edc.web.spi.configuration.ApiContext; +/** + * Service extension for configuring audit logging. + * Registers the {@link HttpRequestInterceptor} as a resource with the web service. + */ @Provides(HttpRequestInterceptor.class) @Extension(value = AuditExtension.NAME) public class AuditExtension implements ServiceExtension { public static final String NAME = "Audit configuration"; - @Inject private WebService webService; @Inject private IdentityService identityService; + /** + * Returns the name of the extension. + * + * @return the name of the extension + */ @Override public String name() { return NAME; } + /** + * Initializes the service extension by registering the {@link HttpRequestInterceptor} with the web service. + * + * @param context the service extension context providing configuration and services + */ @Override public void initialize(ServiceExtensionContext context) { - webService.registerResource(ApiContext.MANAGEMENT,new HttpRequestInterceptor(context.getMonitor(), identityService, context.getParticipantId())); + webService.registerResource(ApiContext.MANAGEMENT, new HttpRequestInterceptor(context.getMonitor(), identityService, context.getParticipantId())); } } diff --git a/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/HttpRequestInterceptor.java b/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/HttpRequestInterceptor.java index acaf1d9..67b7543 100644 --- a/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/HttpRequestInterceptor.java +++ b/extensions/audit-configuration/src/main/java/org/upm/inesdata/audit/HttpRequestInterceptor.java @@ -9,38 +9,55 @@ import java.text.MessageFormat; import java.util.List; -import java.util.Map; +/** + * Intercepts HTTP requests to audit user actions. + * Logs details about the user and the request URI. + */ @Provider public class HttpRequestInterceptor implements ContainerRequestFilter { - private static final String TEMPLATE_AUDIT_LOG = "[AUDIT][''{0}''][MANAGEMENT] User ''{1}'' calls ''{2}''"; - + private static final String TEMPLATE_AUDIT_LOG = "[AUDIT][{0}][MANAGEMENT] User ''{1}'' calls ''{2}''"; private static final String BEARER_PREFIX = "Bearer "; - private static final String REALM_ACCESS_CLAIM_NAME = "realm_access"; - private static final String ROLES_NAME = "roles"; - public static final String TOKEN_PROPERTY_PREFERRED_USERNAME = "preferred_username"; + private static final String TOKEN_PROPERTY_PREFERRED_USERNAME = "preferred_username"; + private static final String TOKEN_USER_NOT_VALID_USER = "NotValidUser"; + private static final String TOKEN_USER_NOT_AUTHENTICATED_USER = "NotAuthenticatedUser"; private final Monitor monitor; private final IdentityService identityService; - private final String participantId; + /** + * Constructor for HttpRequestInterceptor. + * + * @param monitor the monitor interface used for logging + * @param identityService the identity service for token verification + * @param participantId the participant ID for audit log entries + */ public HttpRequestInterceptor(Monitor monitor, IdentityService identityService, String participantId) { this.monitor = monitor; this.identityService = identityService; this.participantId = participantId; } + /** + * Filters the HTTP request context to log audit details. + * + * @param requestContext the container request context + */ @Override - public void filter(ContainerRequestContext requestContext){ + public void filter(ContainerRequestContext requestContext) { String user = getUserFromRequest(requestContext); - String auditLog = MessageFormat.format(TEMPLATE_AUDIT_LOG, participantId, - user, - requestContext.getUriInfo().getRequestUri().toString()); + String auditLog = MessageFormat.format(TEMPLATE_AUDIT_LOG, participantId, user, requestContext.getUriInfo().getRequestUri().toString()); monitor.info(auditLog); } + /** + * Extracts the user from the HTTP request context by decoding the JWT token. + * + * @param requestContext the container request context + * @return the username extracted from the token, or a default value if not authenticated or token is invalid + */ private String getUserFromRequest(ContainerRequestContext requestContext) { List authorizationHeaders = requestContext.getHeaders().get("Authorization"); if (authorizationHeaders != null && !authorizationHeaders.isEmpty()) { @@ -50,12 +67,21 @@ private String getUserFromRequest(ContainerRequestContext requestContext) { return decodeJWT(token); } } - return "NotAuthenticatedUser"; + return TOKEN_USER_NOT_AUTHENTICATED_USER; } + /** + * Decodes the JWT token to extract the username. + * + * @param token the JWT token + * @return the username if token is valid, otherwise a default value indicating the token is not valid + */ private String decodeJWT(String token) { var tokenRepresentation = TokenRepresentation.Builder.newInstance().token(token).build(); var tokenValidation = identityService.verifyJwtToken(tokenRepresentation, null); + if (tokenValidation.failed()) { + return TOKEN_USER_NOT_VALID_USER; + } return (String) tokenValidation.getContent().getClaims().get(TOKEN_PROPERTY_PREFERRED_USERNAME); } } diff --git a/extensions/audit-event-configuration/README.md b/extensions/audit-event-configuration/README.md index 51bb140..6f343e6 100644 --- a/extensions/audit-event-configuration/README.md +++ b/extensions/audit-event-configuration/README.md @@ -1,18 +1,14 @@ -# Oauth2 JWT Token Authentication Service +# AuditEventSubscriptionExtension -This extension provides the capability to authorizate the request to the connector management API. The extension will access the Bearer token provided in the Authorization header and validate that it is a valid JWT-encoded bearer token. It is necessary to have the `org.eclipse.edc:oauth2-core` extension correctly configured. +This extension provides the capability to subscribe to audit events related to contract negotiations and transfer processes. The `AuditEventSubscriber` logs details about these events using the provided monitoring interface. -To authorize a user, the roles of the provided JWT token must contain: -- a valid role from those configured in `allowedRoles` -- a role with the `connector name` +## Features + +- Logs audit details for contract negotiation and transfer process events. +- Registers the `AuditEventSubscriber` with the event router for both asynchronous and synchronous event handling. ## Configuration -Example configuration: +To configure the `AuditEventSubscriptionExtension`, ensure that the `AuditEventSubscriber` is registered with the event router. This is done within the `AuditEventSubscriptionExtension` class. -```properties -edc.api.auth.oauth2.allowedRoles.1.role=connector-admin -edc.api.auth.oauth2.allowedRoles.2.role=connector-management -``` -The `edc.api.auth.oauth2.allowedRoles` will be used by the federated catalog to retrieve the list of allowed roles that can perform requests on the managemente API connector. \ No newline at end of file diff --git a/extensions/audit-event-configuration/build.gradle.kts b/extensions/audit-event-configuration/build.gradle.kts index 191d231..abfed22 100644 --- a/extensions/audit-event-configuration/build.gradle.kts +++ b/extensions/audit-event-configuration/build.gradle.kts @@ -5,8 +5,7 @@ plugins { dependencies { api(libs.edc.auth.spi) - - implementation(libs.edc.iam.oauth2.core) + implementation(libs.jakarta.rsApi) implementation(libs.edc.contract.spi) implementation(libs.edc.transfer.spi) diff --git a/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriber.java b/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriber.java index 0a63a37..a9649b1 100644 --- a/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriber.java +++ b/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriber.java @@ -9,27 +9,44 @@ import java.text.MessageFormat; +/** + * Subscriber for auditing contract negotiation and transfer process events. + * Logs event details using a specified monitoring interface. + */ public class AuditEventSubscriber implements EventSubscriber { + private static final String NEGOTIATION_TEMPLATE_AUDIT_LOG = "[AUDIT][{0}][DSP] ''{1}'' from counterPartyId ''{2}'' with contractNegotiationId ''{3}''"; + private static final String TRANSFER_TEMPLATE_AUDIT_LOG = "[AUDIT][{0}][DSP] ''{1}'' from contractId ''{2}'' with assetId ''{3}'' for type ''{4}''"; private final Monitor monitor; private final String participantId; + /** + * Constructor for AuditEventSubscriber. + * + * @param monitor the monitor interface used for logging + * @param participantId the participant ID for audit log entries + */ public AuditEventSubscriber(Monitor monitor, String participantId) { this.monitor = monitor; this.participantId = participantId; } + /** + * Processes the received event envelope and logs relevant details based on event type. + * + * @param event the event envelope containing the event to be processed + * @param the type of the event + */ @Override public void on(EventEnvelope event) { - if(event.getPayload() instanceof ContractNegotiationEvent){ + if (event.getPayload() instanceof ContractNegotiationEvent) { String simpleName = event.getPayload().getClass().getSimpleName(); ContractNegotiationEvent payload = (ContractNegotiationEvent) event.getPayload(); - monitor.info(MessageFormat.format("[AUDIT][''{0}''][DSP] ''{1}'' from counterPartyId ''{2}'' with contractNegotiationId ''{3}''",participantId,simpleName, payload.getCounterPartyId(),payload.getContractNegotiationId())); - }else if (event.getPayload() instanceof TransferProcessEvent){ + monitor.info(MessageFormat.format(NEGOTIATION_TEMPLATE_AUDIT_LOG, participantId, simpleName, payload.getCounterPartyId(), payload.getContractNegotiationId())); + } else if (event.getPayload() instanceof TransferProcessEvent) { String simpleName = event.getPayload().getClass().getSimpleName(); TransferProcessEvent payload = (TransferProcessEvent) event.getPayload(); - monitor.info(MessageFormat.format("[AUDIT][''{0}''][DSP] ''{1}'' from contractId ''{2}'' with assetId ''{3}'' for type ''{4}''",participantId,simpleName, payload.getContractId(),payload.getAssetId(),payload.getType())); + monitor.info(MessageFormat.format(TRANSFER_TEMPLATE_AUDIT_LOG, participantId, simpleName, payload.getContractId(), payload.getAssetId(), payload.getType())); } - } -} \ No newline at end of file +} diff --git a/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriptionExtension.java b/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriptionExtension.java index d4bc9bb..36b3e49 100644 --- a/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriptionExtension.java +++ b/extensions/audit-event-configuration/src/main/java/org/upm/inesdata/auditevent/AuditEventSubscriptionExtension.java @@ -7,15 +7,24 @@ import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; +/** + * Service extension for subscribing to audit events. + * Registers the {@link AuditEventSubscriber} with the event router for both asynchronous and synchronous event handling. + */ public class AuditEventSubscriptionExtension implements ServiceExtension { @Inject private EventRouter eventRouter; @Inject private Monitor monitor; + /** + * Initializes the service extension by registering the {@link AuditEventSubscriber} with the event router. + * + * @param context the service extension context providing configuration and services + */ @Override public void initialize(ServiceExtensionContext context) { - eventRouter.register(Event.class, new AuditEventSubscriber(monitor,context.getParticipantId())); + eventRouter.register(Event.class, new AuditEventSubscriber(monitor, context.getParticipantId())); eventRouter.registerSync(Event.class, new AuditEventSubscriber(monitor, context.getParticipantId())); } -} \ No newline at end of file +} From 4df735f52259793ffe09080162b646d832734e6e Mon Sep 17 00:00:00 2001 From: "GRUPOGMV\\ssis" Date: Fri, 5 Jul 2024 11:14:29 +0200 Subject: [PATCH 10/10] audit comment --- launchers/connector/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launchers/connector/build.gradle.kts b/launchers/connector/build.gradle.kts index abc1da3..232b27c 100644 --- a/launchers/connector/build.gradle.kts +++ b/launchers/connector/build.gradle.kts @@ -93,7 +93,7 @@ dependencies { //Data plane public api implementation(project(":extensions:extended-data-plane-public-api")) - // Storage assets + // Audit implementation(project(":extensions:audit-configuration")) implementation(project(":extensions:audit-event-configuration"))