diff --git a/ReleaseNotes.md b/ReleaseNotes.md
index b98d301..f1f654d 100644
--- a/ReleaseNotes.md
+++ b/ReleaseNotes.md
@@ -1,3 +1,7 @@
+# Release 3.0.4
+
+- fix missing iat and iss in signedJwks structure
+
# Release 3.0.2
- structure of signed Jwks of relying party fixed
diff --git a/gsi-coverage-report/pom.xml b/gsi-coverage-report/pom.xml
index 3c49a6e..762db6a 100644
--- a/gsi-coverage-report/pom.xml
+++ b/gsi-coverage-report/pom.xml
@@ -6,7 +6,7 @@
de.gematik.idp
gemSekIdp-global
- 3.0.2
+ 3.0.4
../pom.xml
diff --git a/gsi-server/pom.xml b/gsi-server/pom.xml
index dcaef7f..23e56d0 100644
--- a/gsi-server/pom.xml
+++ b/gsi-server/pom.xml
@@ -7,13 +7,13 @@
de.gematik.idp
gemSekIdp-global
- 3.0.2
+ 3.0.4
../pom.xml
gsi-server
- 3.0.2
+ 3.0.4
jar
gsi-server
diff --git a/gsi-server/src/main/java/de/gematik/idp/gsi/server/FlowBeanCreation.java b/gsi-server/src/main/java/de/gematik/idp/gsi/server/FlowBeanCreation.java
index b6ed4b7..f81ba57 100644
--- a/gsi-server/src/main/java/de/gematik/idp/gsi/server/FlowBeanCreation.java
+++ b/gsi-server/src/main/java/de/gematik/idp/gsi/server/FlowBeanCreation.java
@@ -17,6 +17,7 @@
package de.gematik.idp.gsi.server;
import de.gematik.idp.gsi.server.services.EntityStatementBuilder;
+import de.gematik.idp.gsi.server.services.JwksBuilder;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -29,4 +30,9 @@ public class FlowBeanCreation {
public EntityStatementBuilder entityStatementBuilder() {
return new EntityStatementBuilder();
}
+
+ @Bean
+ public JwksBuilder jwksBuilder() {
+ return new JwksBuilder();
+ }
}
diff --git a/gsi-server/src/main/java/de/gematik/idp/gsi/server/KeyConfiguration.java b/gsi-server/src/main/java/de/gematik/idp/gsi/server/KeyConfiguration.java
index 280a57f..03afd98 100644
--- a/gsi-server/src/main/java/de/gematik/idp/gsi/server/KeyConfiguration.java
+++ b/gsi-server/src/main/java/de/gematik/idp/gsi/server/KeyConfiguration.java
@@ -41,23 +41,22 @@ public class KeyConfiguration implements KeyConfigurationBase {
private final GsiConfiguration gsiConfiguration;
@Bean
- public FederationPrivKey entityStatementSigKey() {
- return getFederationPrivKey(gsiConfiguration.getSigKeyConfig());
+ public FederationPrivKey esSigKey() {
+ return getFederationPrivKey(gsiConfiguration.getEsSigKeyConfig());
}
@Bean
public FederationPrivKey tokenSigKey() {
- return getFederationPrivKey(gsiConfiguration.getTokenKeyConfig());
+ return getFederationPrivKey(gsiConfiguration.getTokenSigKeyConfig());
}
@Bean
- public IdpJwtProcessor jwtProcessorSigKey() {
- return new IdpJwtProcessor(
- entityStatementSigKey().getIdentity(), entityStatementSigKey().getKeyId());
+ public IdpJwtProcessor jwtProcessorEsSigKey() {
+ return new IdpJwtProcessor(esSigKey().getIdentity(), esSigKey().getKeyId());
}
@Bean
- public IdpJwtProcessor jwtProcessorTokenKey() {
+ public IdpJwtProcessor jwtProcessorTokenSigKey() {
return new IdpJwtProcessor(tokenSigKey().getIdentity(), tokenSigKey().getKeyId());
}
diff --git a/gsi-server/src/main/java/de/gematik/idp/gsi/server/configuration/GsiConfiguration.java b/gsi-server/src/main/java/de/gematik/idp/gsi/server/configuration/GsiConfiguration.java
index 37bb007..ee1149d 100644
--- a/gsi-server/src/main/java/de/gematik/idp/gsi/server/configuration/GsiConfiguration.java
+++ b/gsi-server/src/main/java/de/gematik/idp/gsi/server/configuration/GsiConfiguration.java
@@ -36,7 +36,7 @@ public class GsiConfiguration {
private String serverUrl;
private String fedmasterUrl;
- private KeyConfig sigKeyConfig;
- private KeyConfig tokenKeyConfig;
+ private KeyConfig esSigKeyConfig;
+ private KeyConfig tokenSigKeyConfig;
private String loglevel;
}
diff --git a/gsi-server/src/main/java/de/gematik/idp/gsi/server/controller/FedIdpController.java b/gsi-server/src/main/java/de/gematik/idp/gsi/server/controller/FedIdpController.java
index 19e3c67..b043079 100644
--- a/gsi-server/src/main/java/de/gematik/idp/gsi/server/controller/FedIdpController.java
+++ b/gsi-server/src/main/java/de/gematik/idp/gsi/server/controller/FedIdpController.java
@@ -54,6 +54,7 @@
import de.gematik.idp.gsi.server.services.AuthenticationService;
import de.gematik.idp.gsi.server.services.EntityStatementBuilder;
import de.gematik.idp.gsi.server.services.EntityStatementRpService;
+import de.gematik.idp.gsi.server.services.JwksBuilder;
import de.gematik.idp.gsi.server.services.SektoralIdpAuthenticator;
import de.gematik.idp.gsi.server.services.ServerUrlService;
import de.gematik.idp.gsi.server.token.IdTokenBuilder;
@@ -75,7 +76,6 @@
import lombok.extern.slf4j.Slf4j;
import org.jose4j.lang.JoseException;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.io.ResourceLoader;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
@@ -103,13 +103,13 @@ public class FedIdpController {
private final SektoralIdpAuthenticator sektoralIdpAuthenticator;
private final AuthenticationService authenticationService;
private final ServerUrlService serverUrlService;
- private final IdpJwtProcessor jwtProcessorSigKey;
- private final IdpJwtProcessor jwtProcessorTokenKey;
+ private final IdpJwtProcessor jwtProcessorEsSigKey;
+ private final IdpJwtProcessor jwtProcessorTokenSigKey;
private final ObjectMapper objectMapper;
private final GsiConfiguration gsiConfiguration;
- private final ResourceLoader resourceLoader;
+ private final JwksBuilder jwksBuilder;
- @Autowired FederationPrivKey entityStatementSigKey;
+ @Autowired FederationPrivKey esSigKey;
@Autowired FederationPrivKey tokenSigKey;
// TODO: delete oldest entry
@@ -127,7 +127,7 @@ private static void setNoCacheHeader(final HttpServletResponse response) {
produces = "application/entity-statement+jwt;charset=UTF-8")
public String getEntityStatement() {
return JwtHelper.signJson(
- jwtProcessorSigKey,
+ jwtProcessorEsSigKey,
objectMapper,
entityStatementBuilder.buildEntityStatement(
serverUrlService.determineServerUrl(), gsiConfiguration.getFedmasterUrl()),
@@ -138,9 +138,9 @@ public String getEntityStatement() {
@GetMapping(value = FED_SIGNED_JWKS_ENDPOINT, produces = "application/jwk-set+json;charset=UTF-8")
public String getSignedJwks() {
return JwtHelper.signJson(
- jwtProcessorSigKey,
+ jwtProcessorEsSigKey,
objectMapper,
- JwtHelper.getJwks(entityStatementSigKey, tokenSigKey),
+ jwksBuilder.build(serverUrlService.determineServerUrl()),
"jwk-set+json");
}
@@ -300,7 +300,7 @@ public TokenResponse getTokensForCode(
final IdTokenBuilder idTokenBuilder =
new IdTokenBuilder(
- jwtProcessorTokenKey,
+ jwtProcessorTokenSigKey,
serverUrlService.determineServerUrl(),
session.getRequestedScopes(),
session.getFachdienstNonce(),
diff --git a/gsi-server/src/main/java/de/gematik/idp/gsi/server/data/SignedJwksBody.java b/gsi-server/src/main/java/de/gematik/idp/gsi/server/data/SignedJwksBody.java
new file mode 100644
index 0000000..d6d03a9
--- /dev/null
+++ b/gsi-server/src/main/java/de/gematik/idp/gsi/server/data/SignedJwksBody.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2023 gematik GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://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.
+ */
+
+package de.gematik.idp.gsi.server.data;
+
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+import de.gematik.idp.data.IdpKeyDescriptor;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@Getter
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
+public class SignedJwksBody {
+
+ private String iss;
+ private long iat;
+ private List keys;
+}
diff --git a/gsi-server/src/main/java/de/gematik/idp/gsi/server/services/EntityStatementBuilder.java b/gsi-server/src/main/java/de/gematik/idp/gsi/server/services/EntityStatementBuilder.java
index 6384630..db73381 100644
--- a/gsi-server/src/main/java/de/gematik/idp/gsi/server/services/EntityStatementBuilder.java
+++ b/gsi-server/src/main/java/de/gematik/idp/gsi/server/services/EntityStatementBuilder.java
@@ -37,7 +37,7 @@
public class EntityStatementBuilder {
private static final int ENTITY_STATEMENT_TTL_DAYS = 7;
- @Autowired FederationPrivKey entityStatementSigKey;
+ @Autowired FederationPrivKey esSigKey;
@Autowired FederationPrivKey tokenSigKey;
public EntityStatement buildEntityStatement(final String serverUrl, final String fedmasterUrl) {
@@ -47,7 +47,7 @@ public EntityStatement buildEntityStatement(final String serverUrl, final String
.iat(currentTime.toEpochSecond())
.iss(serverUrl)
.sub(serverUrl)
- .jwks(JwtHelper.getJwks(entityStatementSigKey, tokenSigKey))
+ .jwks(JwtHelper.getJwks(esSigKey, tokenSigKey))
.authorityHints(new String[] {fedmasterUrl})
.metadata(getMetadata(serverUrl))
.build();
diff --git a/gsi-server/src/main/java/de/gematik/idp/gsi/server/services/JwksBuilder.java b/gsi-server/src/main/java/de/gematik/idp/gsi/server/services/JwksBuilder.java
new file mode 100644
index 0000000..85bc05e
--- /dev/null
+++ b/gsi-server/src/main/java/de/gematik/idp/gsi/server/services/JwksBuilder.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2023 gematik GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://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.
+ */
+
+package de.gematik.idp.gsi.server.services;
+
+import de.gematik.idp.data.FederationPrivKey;
+import de.gematik.idp.data.JwtHelper;
+import de.gematik.idp.gsi.server.data.SignedJwksBody;
+import java.time.ZonedDateTime;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+
+@RequiredArgsConstructor
+@Slf4j
+public class JwksBuilder {
+
+ @Autowired FederationPrivKey esSigKey;
+ @Autowired FederationPrivKey tokenSigKey;
+
+ public SignedJwksBody build(final String serverUrl) {
+ final ZonedDateTime currentTime = ZonedDateTime.now();
+ return SignedJwksBody.builder()
+ .iat(currentTime.toEpochSecond())
+ .iss(serverUrl)
+ .keys(JwtHelper.getJwks(esSigKey, tokenSigKey).getKeys())
+ .build();
+ }
+}
diff --git a/gsi-server/src/main/resources/application.yml b/gsi-server/src/main/resources/application.yml
index 3982f9f..86f5729 100644
--- a/gsi-server/src/main/resources/application.yml
+++ b/gsi-server/src/main/resources/application.yml
@@ -1,9 +1,9 @@
gsi:
- sigKeyConfig:
+ esSigKeyConfig:
fileName: classpath:cert/ref-es-sig.p12
keyId: puk_idp_sig
use: sig
- tokenKeyConfig:
+ tokenSigKeyConfig:
fileName: classpath:cert/ref-es-sig.p12
keyId: puk_fed_idp_token
use: sig
diff --git a/gsi-server/src/test/java/de/gematik/idp/gsi/server/configuration/GsiConfigurationTest.java b/gsi-server/src/test/java/de/gematik/idp/gsi/server/configuration/GsiConfigurationTest.java
index 02cf8cc..fb94d5f 100644
--- a/gsi-server/src/test/java/de/gematik/idp/gsi/server/configuration/GsiConfigurationTest.java
+++ b/gsi-server/src/test/java/de/gematik/idp/gsi/server/configuration/GsiConfigurationTest.java
@@ -36,27 +36,26 @@ class GsiConfigurationTest {
@Test
void fullIntTestComponent() {
assertThat(gsiConfiguration).isNotNull();
- assertThat(gsiConfiguration.getSigKeyConfig()).isNotNull();
- assertThat(gsiConfiguration.getTokenKeyConfig()).isNotNull();
+ assertThat(gsiConfiguration.getEsSigKeyConfig()).isNotNull();
+ assertThat(gsiConfiguration.getTokenSigKeyConfig()).isNotNull();
}
@Test
void testBuildComponent() {
final GsiConfiguration gsiConfig =
GsiConfiguration.builder()
- .sigKeyConfig(new KeyConfig("a", "b", "c", false))
- .tokenKeyConfig(new KeyConfig("d", "e", "f", false))
+ .esSigKeyConfig(new KeyConfig("a", "b", "c", false))
+ .tokenSigKeyConfig(new KeyConfig("d", "e", "f", false))
.serverUrl("serverurl")
.build();
gsiConfig.setServerUrl("newUrl");
assertThat(gsiConfig).isNotNull();
assertThat(gsiConfig.getServerUrl()).isEqualTo("newUrl");
- assertThat(gsiConfig.getSigKeyConfig()).isNotNull();
- assertThat(gsiConfig.getTokenKeyConfig()).isNotNull();
+ assertThat(gsiConfig.getEsSigKeyConfig()).isNotNull();
+ assertThat(gsiConfig.getTokenSigKeyConfig()).isNotNull();
assertThat(GsiConfiguration.builder().toString()).hasSizeGreaterThan(0);
- assertThatThrownBy(
- () -> new KeyConfiguration(resourceLoader, gsiConfig).entityStatementSigKey())
+ assertThatThrownBy(() -> new KeyConfiguration(resourceLoader, gsiConfig).esSigKey())
.isInstanceOf(GsiException.class);
}
}
diff --git a/gsi-server/src/test/java/de/gematik/idp/gsi/server/controller/FedIdpControllerTest.java b/gsi-server/src/test/java/de/gematik/idp/gsi/server/controller/FedIdpControllerTest.java
index 352e6c3..2ebc4fd 100644
--- a/gsi-server/src/test/java/de/gematik/idp/gsi/server/controller/FedIdpControllerTest.java
+++ b/gsi-server/src/test/java/de/gematik/idp/gsi/server/controller/FedIdpControllerTest.java
@@ -248,7 +248,7 @@ void signedJwksResponse_JoseHeader() {
@Test
void signedJwksResponse_BodyClaims() {
- assertThat(sigendJwks.extractBodyClaims()).containsOnlyKeys("keys");
+ assertThat(sigendJwks.extractBodyClaims()).containsOnlyKeys("keys", "iss", "iat");
}
@Test
diff --git a/gsi-testsuite/pom.xml b/gsi-testsuite/pom.xml
index 537164c..3525570 100644
--- a/gsi-testsuite/pom.xml
+++ b/gsi-testsuite/pom.xml
@@ -7,12 +7,12 @@
de.gematik.idp
gemSekIdp-global
- 3.0.2
+ 3.0.4
../pom.xml
gsi-testsuite
- 3.0.2
+ 3.0.4
jar
Testsuite fuer sektorale IDPs
diff --git a/gsi-testsuite/src/test/resources/features/idpsektoralSignedJwks.feature b/gsi-testsuite/src/test/resources/features/idpsektoralSignedJwks.feature
index c0b9d8e..62fb4c9 100644
--- a/gsi-testsuite/src/test/resources/features/idpsektoralSignedJwks.feature
+++ b/gsi-testsuite/src/test/resources/features/idpsektoralSignedJwks.feature
@@ -84,6 +84,14 @@ Feature: Test signed Jwks of IdpSektoral
Given TGR clear recorded messages
And Send Get Request to "${signed_jwks_uri}"
And TGR find request to path ".*"
+ Then TGR current response at "$.body.body" matches as JSON:
+ """
+ {
+ iss: '.*',
+ iat: "${json-unit.ignore}",
+ keys: "${json-unit.ignore}"
+ }
+ """
Then TGR current response at "$.body.body.keys.0" matches as JSON:
"""
{
diff --git a/pom.xml b/pom.xml
index d6e8eb9..529b1c2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -12,7 +12,7 @@
de.gematik.idp
gemSekIdp-global
- 3.0.2
+ 3.0.4
pom
gsi - gematik sektoraler IDP