Skip to content

Commit 393930e

Browse files
chore: remove auth from IssuerMetadata API (#738)
1 parent cb86fb0 commit 393930e

4 files changed

Lines changed: 19 additions & 168 deletions

File tree

e2e-tests/dcp-issuance-tests/src/test/java/org/eclipse/edc/identityhub/tests/dcp/api/DcpIssuerMetadataApiEndToEndTest.java

Lines changed: 0 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@
1515
package org.eclipse.edc.identityhub.tests.dcp.api;
1616

1717
import com.nimbusds.jose.JOSEException;
18-
import com.nimbusds.jose.jwk.Curve;
1918
import com.nimbusds.jose.jwk.ECKey;
20-
import com.nimbusds.jose.jwk.gen.ECKeyGenerator;
2119
import org.eclipse.edc.iam.did.spi.resolution.DidPublicKeyResolver;
2220
import org.eclipse.edc.iam.verifiablecredentials.spi.model.CredentialFormat;
2321
import org.eclipse.edc.identityhub.tests.fixtures.issuerservice.IssuerExtension;
@@ -42,16 +40,13 @@
4240
import org.junit.jupiter.api.extension.RegisterExtension;
4341

4442
import java.util.Base64;
45-
import java.util.Map;
4643
import java.util.UUID;
4744

4845
import static io.restassured.http.ContentType.JSON;
49-
import static jakarta.ws.rs.core.HttpHeaders.AUTHORIZATION;
5046
import static org.eclipse.edc.identityhub.tests.dcp.TestData.ISSUER_RUNTIME_ID;
5147
import static org.eclipse.edc.identityhub.tests.dcp.TestData.ISSUER_RUNTIME_MEM_MODULES;
5248
import static org.eclipse.edc.identityhub.tests.dcp.TestData.ISSUER_RUNTIME_NAME;
5349
import static org.eclipse.edc.identityhub.tests.dcp.TestData.ISSUER_RUNTIME_SQL_MODULES;
54-
import static org.eclipse.edc.identityhub.verifiablecredentials.testfixtures.JwtCreationUtil.generateJwt;
5550
import static org.eclipse.edc.identityhub.verifiablecredentials.testfixtures.VerifiableCredentialTestUtil.generateEcKey;
5651
import static org.hamcrest.Matchers.equalTo;
5752
import static org.mockito.ArgumentMatchers.eq;
@@ -106,13 +101,11 @@ void issuerMetadata(IssuerExtension issuerExtension, HolderService holderService
106101
credentialDefinitionService.createCredentialDefinition(credentialDefinition);
107102
holderService.createHolder(createHolder(PARTICIPANT_DID, PARTICIPANT_DID, "Participant"));
108103

109-
var token = "Bearer " + generateSiToken();
110104

111105
when(DID_PUBLIC_KEY_RESOLVER.resolveKey(eq(DID_WEB_PARTICIPANT_KEY_1))).thenReturn(Result.success(PARTICIPANT_KEY.toPublicKey()));
112106

113107
issuerExtension.getIssuerApiEndpoint().baseRequest()
114108
.contentType(JSON)
115-
.header(AUTHORIZATION, token)
116109
.get(issuanceMetadataUrl())
117110
.then()
118111
.log().ifValidationFails()
@@ -125,131 +118,6 @@ void issuerMetadata(IssuerExtension issuerExtension, HolderService holderService
125118

126119
}
127120

128-
@Test
129-
void issuerMetadata_tokenNotPresent_shouldReturn401(IssuerExtension issuerExtension) {
130-
issuerExtension.getIssuerApiEndpoint().baseRequest()
131-
.contentType(JSON)
132-
.get(issuanceMetadataUrl())
133-
.then()
134-
.log().ifValidationFails()
135-
.statusCode(401);
136-
137-
}
138-
139-
@Test
140-
void issuerMetadata_noBearerPrefix_shouldReturn401(IssuerExtension issuerExtension) {
141-
var token = generateSiToken();
142-
143-
issuerExtension.getIssuerApiEndpoint().baseRequest()
144-
.contentType(JSON)
145-
.header(AUTHORIZATION, token)
146-
.get(issuanceMetadataUrl())
147-
.then()
148-
.log().ifValidationFails()
149-
.statusCode(401);
150-
151-
}
152-
153-
@Test
154-
void issuerMetadata_participantNotFound_shouldReturn401(IssuerExtension issuerExtension) {
155-
var token = "Bearer " + generateSiToken();
156-
157-
issuerExtension.getIssuerApiEndpoint().baseRequest()
158-
.contentType(JSON)
159-
.header(AUTHORIZATION, token)
160-
.get(issuanceMetadataUrl())
161-
.then()
162-
.log().ifValidationFails()
163-
.statusCode(401);
164-
165-
}
166-
167-
@Test
168-
void issuerMetadata_tokenVerificationFails_shouldReturn401(IssuerExtension issuerExtension, HolderService holderService) throws JOSEException {
169-
170-
holderService.createHolder(createHolder(PARTICIPANT_DID, PARTICIPANT_DID, "Participant"));
171-
172-
holderService.createHolder(createHolder(PARTICIPANT_DID, PARTICIPANT_DID, "Participant"));
173-
174-
var spoofedKey = new ECKeyGenerator(Curve.P_256).keyID(DID_WEB_PARTICIPANT_KEY_1).generate();
175-
176-
var token = "Bearer " + generateSiToken();
177-
178-
when(DID_PUBLIC_KEY_RESOLVER.resolveKey(eq(DID_WEB_PARTICIPANT_KEY_1))).thenReturn(Result.success(spoofedKey.toPublicKey()));
179-
180-
issuerExtension.getIssuerApiEndpoint().baseRequest()
181-
.contentType(JSON)
182-
.header(AUTHORIZATION, token)
183-
.get(issuanceMetadataUrl())
184-
.then()
185-
.log().ifValidationFails()
186-
.statusCode(401);
187-
188-
}
189-
190-
@Test
191-
void issuerMetadata_spoofedKeyId_shouldReturn401(IssuerExtension issuerExtension, HolderService holderService) throws JOSEException {
192-
holderService.createHolder(createHolder(PARTICIPANT_DID, PARTICIPANT_DID, "Participant"));
193-
var spoofedKeyId = "did:web:spoofed#key1";
194-
var spoofedKey = new ECKeyGenerator(Curve.P_256).keyID(spoofedKeyId).generate();
195-
196-
var token = generateSiToken(spoofedKey);
197-
198-
when(DID_PUBLIC_KEY_RESOLVER.resolveKey(eq(spoofedKeyId))).thenReturn(Result.success(spoofedKey.toPublicKey()));
199-
200-
issuerExtension.getIssuerApiEndpoint().baseRequest()
201-
.contentType(JSON)
202-
.header(AUTHORIZATION, token)
203-
.get(issuanceMetadataUrl())
204-
.then()
205-
.log().ifValidationFails()
206-
.statusCode(401);
207-
208-
209-
}
210-
211-
@Test
212-
void issuerMetadata_wrongTokenAudience_shouldReturn401(IssuerExtension issuerExtension, HolderService holderService) throws JOSEException {
213-
214-
generateEcKey(DID_WEB_PARTICIPANT_KEY_1);
215-
216-
holderService.createHolder(createHolder(PARTICIPANT_DID, PARTICIPANT_DID, "Participant"));
217-
218-
var token = generateSiToken("wrong-audience");
219-
220-
when(DID_PUBLIC_KEY_RESOLVER.resolveKey(eq(DID_WEB_PARTICIPANT_KEY_1))).thenReturn(Result.success(PARTICIPANT_KEY.toPublicKey()));
221-
222-
issuerExtension.getIssuerApiEndpoint().baseRequest()
223-
.contentType(JSON)
224-
.header(AUTHORIZATION, token)
225-
.get(issuanceMetadataUrl())
226-
.then()
227-
.log().ifValidationFails()
228-
.statusCode(401);
229-
230-
}
231-
232-
233-
private String generateSiToken() {
234-
return generateSiToken(ISSUER_DID);
235-
}
236-
237-
private String generateSiToken(String audience) {
238-
return generateSiToken(audience, PARTICIPANT_DID, PARTICIPANT_KEY);
239-
}
240-
241-
private String generateSiToken(ECKey key) {
242-
return generateSiToken(ISSUER_DID, key);
243-
}
244-
245-
private String generateSiToken(String audience, ECKey key) {
246-
return generateJwt(audience, PARTICIPANT_DID, PARTICIPANT_DID, Map.of(), key);
247-
}
248-
249-
private String generateSiToken(String audience, String participantDid, ECKey participantKey) {
250-
return generateJwt(audience, participantDid, participantDid, Map.of(), participantKey);
251-
}
252-
253121

254122
private Holder createHolder(String id, String did, String name) {
255123
return Holder.Builder.newInstance()

protocols/dcp/dcp-issuer/dcp-issuer-api/src/main/java/org/eclipse/edc/identityhub/protocols/dcp/issuer/IssuerApiExtension.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ public void initialize(ServiceExtensionContext context) {
116116

117117
webService.registerResource(ISSUANCE_API, new CredentialRequestApiController(participantContextService, dcpIssuerService, dcpHolderTokenVerifier, validatorRegistry, dcpRegistry, DSPACE_DCP_NAMESPACE_V_1_0));
118118
webService.registerResource(ISSUANCE_API, new CredentialRequestStatusApiController(participantContextService, dcpHolderTokenVerifier, issuanceProcessService, dcpRegistry));
119-
webService.registerResource(ISSUANCE_API, new IssuerMetadataApiController(participantContextService, dcpHolderTokenVerifier, issuerMetadataService, dcpRegistry));
119+
webService.registerResource(ISSUANCE_API, new IssuerMetadataApiController(participantContextService, issuerMetadataService, dcpRegistry));
120120

121121
webService.registerResource(ISSUANCE_API, new ObjectMapperProvider(typeManager, JSON_LD));
122122
webService.registerResource(ISSUANCE_API, new JerseyJsonLdInterceptor(jsonLd, typeManager, JSON_LD, DCP_SCOPE_V_1_0));

protocols/dcp/dcp-issuer/dcp-issuer-api/src/main/java/org/eclipse/edc/identityhub/protocols/dcp/issuer/api/v1alpha/issuermetadata/IssuerMetadataApiController.java

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,8 @@
2222
import jakarta.ws.rs.PathParam;
2323
import jakarta.ws.rs.Produces;
2424
import org.eclipse.edc.identityhub.protocols.dcp.issuer.spi.DcpIssuerMetadataService;
25-
import org.eclipse.edc.identityhub.protocols.dcp.spi.DcpHolderTokenVerifier;
2625
import org.eclipse.edc.identityhub.spi.participantcontext.ParticipantContextService;
2726
import org.eclipse.edc.spi.EdcException;
28-
import org.eclipse.edc.spi.iam.TokenRepresentation;
2927
import org.eclipse.edc.transform.spi.TypeTransformerRegistry;
3028
import org.eclipse.edc.web.spi.exception.AuthenticationFailedException;
3129
import org.eclipse.edc.web.spi.exception.InvalidRequestException;
@@ -40,14 +38,12 @@
4038
public class IssuerMetadataApiController implements IssuerMetadataApi {
4139

4240
private final ParticipantContextService participantContextService;
43-
private final DcpHolderTokenVerifier tokenValidator;
4441
private final DcpIssuerMetadataService issuerMetadataService;
4542
private final TypeTransformerRegistry dcpRegistry;
4643

4744

48-
public IssuerMetadataApiController(ParticipantContextService participantContextService, DcpHolderTokenVerifier tokenValidator, DcpIssuerMetadataService issuerMetadataService, TypeTransformerRegistry dcpRegistry) {
45+
public IssuerMetadataApiController(ParticipantContextService participantContextService, DcpIssuerMetadataService issuerMetadataService, TypeTransformerRegistry dcpRegistry) {
4946
this.participantContextService = participantContextService;
50-
this.tokenValidator = tokenValidator;
5147
this.issuerMetadataService = issuerMetadataService;
5248
this.dcpRegistry = dcpRegistry;
5349
}
@@ -56,23 +52,11 @@ public IssuerMetadataApiController(ParticipantContextService participantContextS
5652
@Path("/")
5753
@Override
5854
public JsonObject getIssuerMetadata(@PathParam("participantContextId") String participantContextId, @HeaderParam(AUTHORIZATION) String authHeader) {
59-
if (authHeader == null) {
60-
throw new AuthenticationFailedException("Authorization header missing");
61-
}
62-
if (!authHeader.startsWith("Bearer ")) {
63-
throw new AuthenticationFailedException("Invalid authorization header, must start with 'Bearer'");
64-
}
65-
var token = authHeader.replace("Bearer", "").trim();
6655
var decodedParticipantContextId = onEncoded(participantContextId).orElseThrow(InvalidRequestException::new);
6756

6857
var participantContext = participantContextService.getParticipantContext(decodedParticipantContextId)
6958
.orElseThrow((f) -> new AuthenticationFailedException("Invalid issuer"));
7059

71-
var tokenRepresentation = TokenRepresentation.Builder.newInstance().token(token).build();
72-
73-
tokenValidator.verify(participantContext, tokenRepresentation)
74-
.orElseThrow((f) -> new AuthenticationFailedException("ID token verification failed: %s".formatted(f.getFailureDetail())));
75-
7660
var metadata = issuerMetadataService.getIssuerMetadata(participantContext)
7761
.orElseThrow(f -> new EdcException("Error creating response body: " + f.getFailureDetail()));
7862

protocols/dcp/dcp-issuer/dcp-issuer-api/src/test/java/org/eclipse/edc/identityhub/protocols/dcp/issuer/api/v1alpha/issuermetadata/IssuerMetadataApiControllerTest.java

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
import org.eclipse.edc.web.jersey.testfixtures.RestControllerTestBase;
3232
import org.eclipse.edc.web.spi.exception.AuthenticationFailedException;
3333
import org.junit.jupiter.api.Test;
34+
import org.junit.jupiter.params.ParameterizedTest;
35+
import org.junit.jupiter.params.provider.EmptySource;
36+
import org.junit.jupiter.params.provider.NullSource;
3437

3538
import java.sql.Date;
3639
import java.time.Instant;
@@ -59,26 +62,22 @@ public class IssuerMetadataApiControllerTest extends RestControllerTestBase {
5962
private final String participantContextId = "participantContextId";
6063
private final String participantContextIdEncoded = Base64.getEncoder().encodeToString(participantContextId.getBytes());
6164

62-
@Test
63-
void issuerMetadata_tokenNotPresent_shouldReturn401() {
64-
assertThatThrownBy(() -> controller().getIssuerMetadata(participantContextIdEncoded, null))
65-
.isInstanceOf(AuthenticationFailedException.class)
66-
.hasMessage("Authorization header missing");
67-
68-
verifyNoInteractions(issuerMetadataService, participantContextService, dcpIssuerTokenVerifier, typeTransformerRegistry);
69-
70-
}
65+
@ParameterizedTest
66+
@NullSource
67+
@EmptySource
68+
void issuerMetadata_noAuthToken_success(String emptyAuthHeader) {
69+
var participant = createHolder("id", "did", "name");
70+
var ctx = new DcpRequestContext(participant, Map.of());
71+
var object = Json.createObjectBuilder().build();
7172

72-
@Test
73-
void issuerMetadata_tokenVerificationFails_shouldReturn401() {
74-
when(dcpIssuerTokenVerifier.verify(any(), any())).thenReturn(ServiceResult.unauthorized("unauthorized"));
73+
var metadata = IssuerMetadata.Builder.newInstance().build();
74+
when(dcpIssuerTokenVerifier.verify(any(), any())).thenReturn(ServiceResult.success(ctx));
7575
when(participantContextService.getParticipantContext(eq(participantContextId))).thenReturn(ServiceResult.success(createParticipantContext()));
76+
when(issuerMetadataService.getIssuerMetadata(argThat(p -> p.getParticipantContextId().equals(participantContextId)))).thenReturn(ServiceResult.success(metadata));
77+
when(typeTransformerRegistry.transform(eq(metadata), eq(JsonObject.class))).thenReturn(Result.success(object));
78+
var response = controller().getIssuerMetadata(participantContextIdEncoded, emptyAuthHeader);
7679

77-
assertThatThrownBy(() -> controller().getIssuerMetadata(participantContextIdEncoded, generateJwt()))
78-
.isExactlyInstanceOf(AuthenticationFailedException.class)
79-
.hasMessageContaining("unauthorized");
80-
81-
verifyNoInteractions(issuerMetadataService);
80+
assertThat(response).isEqualTo(object);
8281
}
8382

8483
@Test
@@ -112,7 +111,7 @@ void issuerMetadata() {
112111

113112
@Override
114113
protected IssuerMetadataApiController controller() {
115-
return new IssuerMetadataApiController(participantContextService, dcpIssuerTokenVerifier, issuerMetadataService, typeTransformerRegistry);
114+
return new IssuerMetadataApiController(participantContextService, issuerMetadataService, typeTransformerRegistry);
116115
}
117116

118117
private ParticipantContext createParticipantContext() {

0 commit comments

Comments
 (0)