-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(IdentityService): implements first skeleton of the SSI identity …
…service (#459) * feat(IdentityService): implements first skeleton of the SSI identity service * pr remarks * pr remarks
- Loading branch information
Showing
36 changed files
with
1,594 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# SSI Core Identity Service Module | ||
|
||
This module contains an implementation of the EDC identity service for SSI. | ||
The SsiIdentityService contains a `SsiTokenValidationService` for validating the `JWT` token, | ||
that uses an implementation of `SsiCredentialClient` for validating the JWT token and then check custom rules registered in the `SsiValidationRuleRegistry` | ||
|
||
For obtaining the `JWT` token, the identity service also delegate to the `SsiCredentialClient` . | ||
|
||
The default implementation according to the first milestone [here](https://github.com/eclipse-tractusx/ssi-docu/tree/main/docs/architecture/cx-3-2) | ||
will rely on an MIW and the implementations in available in the module `:edc-extensions:ssi:ssi-miw-credential-client`. | ||
|
||
The implementation also provide a rule registry `SsiValidationRuleRegistry` where custom rule can be registered for validating the `ClaimToken` extracted from the `JWT` token. | ||
|
||
Custom rule could be like: | ||
|
||
- Audience validation | ||
- VP/VC validation | ||
- Expiration | ||
- ..etc | ||
|
||
This module it's still in development, but it will likely to contain also the Identity extractor from the `ClaimToken` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/* | ||
* Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) | ||
* | ||
* 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 | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Contributors: | ||
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation | ||
* | ||
*/ | ||
|
||
plugins { | ||
`java-library` | ||
`maven-publish` | ||
} | ||
|
||
dependencies { | ||
implementation(project(":spi:ssi-spi")) | ||
implementation(libs.edc.spi.core) | ||
implementation(libs.edc.spi.jwt) | ||
implementation(libs.edc.jwt.core) | ||
implementation(libs.nimbus.jwt) | ||
testImplementation(testFixtures(libs.edc.junit)) | ||
} |
45 changes: 45 additions & 0 deletions
45
...tity-core/src/main/java/org/eclipse/tractusx/edc/iam/ssi/identity/SsiIdentityService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* | ||
* Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) | ||
* | ||
* 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 | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Contributors: | ||
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation | ||
* | ||
*/ | ||
|
||
package org.eclipse.tractusx.edc.iam.ssi.identity; | ||
|
||
import org.eclipse.edc.jwt.spi.TokenValidationService; | ||
import org.eclipse.edc.spi.iam.ClaimToken; | ||
import org.eclipse.edc.spi.iam.IdentityService; | ||
import org.eclipse.edc.spi.iam.TokenParameters; | ||
import org.eclipse.edc.spi.iam.TokenRepresentation; | ||
import org.eclipse.edc.spi.result.Result; | ||
import org.eclipse.tractusx.edc.iam.ssi.spi.SsiCredentialClient; | ||
|
||
public class SsiIdentityService implements IdentityService { | ||
|
||
private final TokenValidationService tokenValidationService; | ||
|
||
private final SsiCredentialClient client; | ||
|
||
public SsiIdentityService(TokenValidationService tokenValidationService, SsiCredentialClient client) { | ||
this.tokenValidationService = tokenValidationService; | ||
this.client = client; | ||
} | ||
|
||
@Override | ||
public Result<TokenRepresentation> obtainClientCredentials(TokenParameters parameters) { | ||
return client.obtainClientCredentials(parameters); | ||
} | ||
|
||
@Override | ||
public Result<ClaimToken> verifyJwtToken(TokenRepresentation tokenRepresentation, String audience) { | ||
return tokenValidationService.validate(tokenRepresentation); | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
.../src/main/java/org/eclipse/tractusx/edc/iam/ssi/identity/SsiIdentityServiceExtension.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
* Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) | ||
* | ||
* 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 | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Contributors: | ||
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation | ||
* | ||
*/ | ||
|
||
package org.eclipse.tractusx.edc.iam.ssi.identity; | ||
|
||
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.iam.IdentityService; | ||
import org.eclipse.edc.spi.system.ServiceExtension; | ||
import org.eclipse.edc.spi.system.ServiceExtensionContext; | ||
import org.eclipse.tractusx.edc.iam.ssi.spi.SsiCredentialClient; | ||
import org.eclipse.tractusx.edc.iam.ssi.spi.SsiValidationRuleRegistry; | ||
|
||
@Provides({IdentityService.class, SsiValidationRuleRegistry.class}) | ||
@Extension(SsiIdentityServiceExtension.EXTENSION_NAME) | ||
public class SsiIdentityServiceExtension implements ServiceExtension { | ||
|
||
public static final String EXTENSION_NAME = "SSI Identity Service"; | ||
|
||
@Inject | ||
private SsiCredentialClient credentialClient; | ||
|
||
@Override | ||
public String name() { | ||
return EXTENSION_NAME; | ||
} | ||
|
||
@Override | ||
public void initialize(ServiceExtensionContext context) { | ||
var validationRulesRegistry = new SsiValidationRulesRegistryImpl(); | ||
context.registerService(SsiValidationRuleRegistry.class, validationRulesRegistry); | ||
|
||
var identityService = new SsiIdentityService(new SsiTokenValidationService(validationRulesRegistry, credentialClient), credentialClient); | ||
|
||
context.registerService(IdentityService.class, identityService); | ||
} | ||
|
||
} |
58 changes: 58 additions & 0 deletions
58
...re/src/main/java/org/eclipse/tractusx/edc/iam/ssi/identity/SsiTokenValidationService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) | ||
* | ||
* 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 | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Contributors: | ||
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation | ||
* | ||
*/ | ||
|
||
package org.eclipse.tractusx.edc.iam.ssi.identity; | ||
|
||
import org.eclipse.edc.jwt.spi.TokenValidationRulesRegistry; | ||
import org.eclipse.edc.jwt.spi.TokenValidationService; | ||
import org.eclipse.edc.spi.iam.ClaimToken; | ||
import org.eclipse.edc.spi.iam.TokenRepresentation; | ||
import org.eclipse.edc.spi.result.Result; | ||
import org.eclipse.tractusx.edc.iam.ssi.spi.SsiCredentialClient; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
import java.util.Collection; | ||
import java.util.Map; | ||
import java.util.stream.Collectors; | ||
|
||
public class SsiTokenValidationService implements TokenValidationService { | ||
|
||
private final TokenValidationRulesRegistry rulesRegistry; | ||
private final SsiCredentialClient credentialClient; | ||
|
||
public SsiTokenValidationService(TokenValidationRulesRegistry rulesRegistry, SsiCredentialClient credentialClient) { | ||
this.rulesRegistry = rulesRegistry; | ||
this.credentialClient = credentialClient; | ||
} | ||
|
||
@Override | ||
public Result<ClaimToken> validate(TokenRepresentation tokenRepresentation) { | ||
return credentialClient.validate(tokenRepresentation) | ||
.compose(claimToken -> checkRules(claimToken, tokenRepresentation.getAdditional())); | ||
} | ||
|
||
private Result<ClaimToken> checkRules(ClaimToken claimToken, @Nullable Map<String, Object> additional) { | ||
var errors = rulesRegistry.getRules().stream() | ||
.map(r -> r.checkRule(claimToken, additional)) | ||
.filter(Result::failed) | ||
.map(Result::getFailureMessages) | ||
.flatMap(Collection::stream) | ||
.collect(Collectors.toList()); | ||
|
||
if (!errors.isEmpty()) { | ||
return Result.failure(errors); | ||
} | ||
return Result.success(claimToken); | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
...c/main/java/org/eclipse/tractusx/edc/iam/ssi/identity/SsiValidationRulesRegistryImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/* | ||
* Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) | ||
* | ||
* 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 | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Contributors: | ||
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation | ||
* | ||
*/ | ||
|
||
package org.eclipse.tractusx.edc.iam.ssi.identity; | ||
|
||
import org.eclipse.edc.jwt.TokenValidationRulesRegistryImpl; | ||
import org.eclipse.tractusx.edc.iam.ssi.spi.SsiValidationRuleRegistry; | ||
|
||
public class SsiValidationRulesRegistryImpl extends TokenValidationRulesRegistryImpl implements SsiValidationRuleRegistry { | ||
} |
15 changes: 15 additions & 0 deletions
15
...ity-core/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# | ||
# Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) | ||
# | ||
# 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 | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
# | ||
# Contributors: | ||
# Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation | ||
# | ||
# | ||
|
||
org.eclipse.tractusx.edc.iam.ssi.identity.SsiIdentityServiceExtension |
52 changes: 52 additions & 0 deletions
52
.../test/java/org/eclipse/tractusx/edc/iam/ssi/identity/SsiIdentityServiceExtensionTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/* | ||
* Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) | ||
* | ||
* 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 | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Contributors: | ||
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation | ||
* | ||
*/ | ||
|
||
package org.eclipse.tractusx.edc.iam.ssi.identity; | ||
|
||
import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; | ||
import org.eclipse.edc.spi.iam.IdentityService; | ||
import org.eclipse.edc.spi.system.ServiceExtensionContext; | ||
import org.eclipse.edc.spi.system.injection.ObjectFactory; | ||
import org.eclipse.tractusx.edc.iam.ssi.spi.SsiCredentialClient; | ||
import org.eclipse.tractusx.edc.iam.ssi.spi.SsiValidationRuleRegistry; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.extension.ExtendWith; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.mockito.Mockito.mock; | ||
import static org.mockito.Mockito.spy; | ||
|
||
@ExtendWith(DependencyInjectionExtension.class) | ||
public class SsiIdentityServiceExtensionTest { | ||
|
||
SsiIdentityServiceExtension extension; | ||
|
||
ServiceExtensionContext context; | ||
|
||
@BeforeEach | ||
void setup(ObjectFactory factory, ServiceExtensionContext context) { | ||
this.context = spy(context); | ||
context.registerService(SsiCredentialClient.class, mock(SsiCredentialClient.class)); | ||
extension = factory.constructInstance(SsiIdentityServiceExtension.class); | ||
} | ||
|
||
@Test | ||
void initialize() { | ||
extension.initialize(context); | ||
|
||
assertThat(context.getService(IdentityService.class)).isNotNull().isInstanceOf(SsiIdentityService.class); | ||
assertThat(context.getService(SsiValidationRuleRegistry.class)).isNotNull().isInstanceOf(SsiValidationRulesRegistryImpl.class); | ||
} | ||
} |
Oops, something went wrong.