From e2b9ff2a9a33fda569f1a7f8526679a8c95f0be0 Mon Sep 17 00:00:00 2001 From: Thomas Richner Date: Mon, 5 Feb 2024 19:38:36 +0100 Subject: [PATCH] ARC-1234: Added Keygen & fixed logging --- .gitignore | 1 + README.md | 19 ++++ esgen/pom.xml | 59 +++++++++++ .../com/oviva/gesundheitsid/esgen/Main.java | 94 ++++++++++++++++++ esgen/src/main/resources/logback.xml | 11 +++ gen_keys.sh | 3 + .../src/test/resources/log4j.properties | 4 - oidc-server/pom.xml | 46 ++++++--- .../gesundheitsid/relyingparty/Main.java | 98 ++++++++++++------- .../{Config.java => RelyingPartyConfig.java} | 2 +- .../gesundheitsid/relyingparty/ws/App.java | 12 +-- .../relyingparty/ws/AuthEndpoint.java | 14 +-- .../relyingparty/ws/OpenIdEndpoint.java | 18 ++-- oidc-server/src/main/resources/logback.xml | 32 ++++++ .../relyingparty/ws/AuthEndpointTest.java | 24 ++--- .../relyingparty/ws/OpenIdEndpointTest.java | 4 +- pom.xml | 18 ++-- start.sh | 6 ++ 18 files changed, 367 insertions(+), 98 deletions(-) create mode 100644 esgen/pom.xml create mode 100755 esgen/src/main/java/com/oviva/gesundheitsid/esgen/Main.java create mode 100644 esgen/src/main/resources/logback.xml create mode 100755 gen_keys.sh delete mode 100644 gesundheitsid/src/test/resources/log4j.properties rename oidc-server/src/main/java/com/oviva/gesundheitsid/relyingparty/cfg/{Config.java => RelyingPartyConfig.java} (84%) create mode 100644 oidc-server/src/main/resources/logback.xml create mode 100755 start.sh diff --git a/.gitignore b/.gitignore index ed4d3d0..b52028b 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ gesundheitsid/dependency-reduced-pom.xml .flattened-pom.xml *_jwks.json env.properties +*.pem diff --git a/README.md b/README.md index 372f40b..fa57129 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,25 @@ Setting up a proxy with a header filter can get around that limitation though. /~q & ~d gsi.dev.gematik.solutions/X-Authorization/ ``` +## Setup Test VM + +```shell + +sudo apt update +sudo apt install jq openjdk-17-jre-headless + +# install caddy +sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl +curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg +curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list +sudo apt update +sudo apt install caddy + +sudo systemctl disable --now caddy + +sudo caddy reverse-proxy --from=t.oviva.io --to=:1234 +``` + ## Helpful Links diff --git a/esgen/pom.xml b/esgen/pom.xml new file mode 100644 index 0000000..56dba18 --- /dev/null +++ b/esgen/pom.xml @@ -0,0 +1,59 @@ + + + 4.0.0 + + + com.oviva.gesundheitsid + gesundheitsid-parent + 0.0.1-SNAPSHOT + + + esgen + jar + + + + org.slf4j + slf4j-api + + + ch.qos.logback + logback-classic + + + + com.nimbusds + nimbus-jose-jwt + + + + org.junit.jupiter + junit-jupiter + test + + + org.junit.jupiter + junit-jupiter-params + test + + + org.hamcrest + hamcrest + test + + + org.mockito + mockito-junit-jupiter + test + + + org.mockito + mockito-core + test + + + + + diff --git a/esgen/src/main/java/com/oviva/gesundheitsid/esgen/Main.java b/esgen/src/main/java/com/oviva/gesundheitsid/esgen/Main.java new file mode 100755 index 0000000..e839c35 --- /dev/null +++ b/esgen/src/main/java/com/oviva/gesundheitsid/esgen/Main.java @@ -0,0 +1,94 @@ +package com.oviva.gesundheitsid.esgen; + +import com.nimbusds.jose.JOSEException; +import com.nimbusds.jose.jwk.Curve; +import com.nimbusds.jose.jwk.ECKey; +import com.nimbusds.jose.jwk.JWKSet; +import com.nimbusds.jose.jwk.KeyUse; +import com.nimbusds.jose.jwk.gen.ECKeyGenerator; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.security.Key; +import java.util.Base64; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Main { + + private static final Logger logger = LoggerFactory.getLogger(Main.class); + + public static void main(String[] args) { + + var main = new Main(); + try { + main.run(); + } catch (Exception e) { + logger.atError().setCause(e).log("key generator failed"); + System.exit(1); + } + } + + public void run() throws JOSEException, IOException { // your business logic goes here... + + logger.atInfo().log("generating ES256 keys"); + + var federationSigningKey = + new ECKeyGenerator(Curve.P_256) + .keyUse(KeyUse.SIGNATURE) + .keyIDFromThumbprint(true) + .generate(); + + var sigName = "sig"; + var encName = "enc"; + + saveJwks(sigName, new JWKSet(federationSigningKey)); + savePublicEncoded(sigName, federationSigningKey); + + var federationIdTokenEncryptionKey = + new ECKeyGenerator(Curve.P_256) + .keyUse(KeyUse.ENCRYPTION) + .keyIDFromThumbprint(true) + .generate(); + + saveJwks(encName, new JWKSet(federationIdTokenEncryptionKey)); + savePublicEncoded(encName, federationIdTokenEncryptionKey); + } + + private void saveJwks(String name, JWKSet set) throws IOException { + var jwks = set.toString(false); + writeString(Path.of("%s_jwks.json".formatted(name)), jwks); + } + + private void savePublicEncoded(String name, ECKey jwk) throws JOSEException, IOException { + + var publicEncodedPem = encodeAsPem(jwk.toPublicKey(), "PUBLIC KEY"); + var p = Path.of("%s_pub.pem".formatted(name)); + writeString(p, publicEncodedPem); + } + + private String encodeAsPem(Key k, String type) { + + var encoded = Base64.getEncoder().encodeToString(k.getEncoded()); + + var sb = new StringBuilder(); + sb.append("-----BEGIN %s-----%n".formatted(type)); + + while (!encoded.isEmpty()) { + var end = Math.min(64, encoded.length()); + var line = encoded.substring(0, end); + sb.append(line).append('\n'); + encoded = encoded.substring(end); + } + + sb.append("-----END %s-----%n".formatted(type)); + return sb.toString(); + } + + private void writeString(Path p, String contents) throws IOException { + + Files.writeString(p, contents, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE); + logger.atInfo().log("written '%s'".formatted(p)); + } +} diff --git a/esgen/src/main/resources/logback.xml b/esgen/src/main/resources/logback.xml new file mode 100644 index 0000000..accea20 --- /dev/null +++ b/esgen/src/main/resources/logback.xml @@ -0,0 +1,11 @@ + + + + + %d{HH:mm:ss} %highlight(%-5level) %msg %kvp%n + + + + + + \ No newline at end of file diff --git a/gen_keys.sh b/gen_keys.sh new file mode 100755 index 0000000..48e0823 --- /dev/null +++ b/gen_keys.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +mvn --quiet clean compile exec:java -Dexec.mainClass="com.oviva.gesundheitsid.esgen.Main" -f esgen \ No newline at end of file diff --git a/gesundheitsid/src/test/resources/log4j.properties b/gesundheitsid/src/test/resources/log4j.properties deleted file mode 100644 index ce0b86f..0000000 --- a/gesundheitsid/src/test/resources/log4j.properties +++ /dev/null @@ -1,4 +0,0 @@ -log4j.rootLogger=INFO, stdout -log4j.appender.stdout=org.apache.log4j.ConsoleAppender -log4j.appender.stdout.layout=org.apache.log4j.PatternLayout -log4j.appender.stdout.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n diff --git a/oidc-server/pom.xml b/oidc-server/pom.xml index 054c154..a0a378c 100644 --- a/oidc-server/pom.xml +++ b/oidc-server/pom.xml @@ -66,18 +66,9 @@ logback-classic - ch.qos.logback.contrib - logback-json-classic - - - ch.qos.logback - logback-core - - - - - ch.qos.logback.contrib - logback-jackson + net.logstash.logback + logstash-logback-encoder + 7.4 @@ -150,4 +141,35 @@ + + + + org.apache.maven.plugins + maven-assembly-plugin + + + + + com.oviva.gesundheitsid.relyingparty.Main + + + + jar-with-dependencies + + + + + + make-assembly + package + + single + + + + + + + + diff --git a/oidc-server/src/main/java/com/oviva/gesundheitsid/relyingparty/Main.java b/oidc-server/src/main/java/com/oviva/gesundheitsid/relyingparty/Main.java index 790a674..c5a02ad 100644 --- a/oidc-server/src/main/java/com/oviva/gesundheitsid/relyingparty/Main.java +++ b/oidc-server/src/main/java/com/oviva/gesundheitsid/relyingparty/Main.java @@ -1,5 +1,6 @@ package com.oviva.gesundheitsid.relyingparty; +import com.nimbusds.jose.jwk.JWKSet; import com.oviva.gesundheitsid.auth.AuthenticationFlow; import com.oviva.gesundheitsid.fedclient.FederationMasterClientImpl; import com.oviva.gesundheitsid.fedclient.api.CachedFederationApiClient; @@ -7,15 +8,16 @@ import com.oviva.gesundheitsid.fedclient.api.InMemoryCacheImpl; import com.oviva.gesundheitsid.fedclient.api.JavaHttpClient; import com.oviva.gesundheitsid.fedclient.api.OpenIdClient; -import com.oviva.gesundheitsid.relyingparty.cfg.Config; import com.oviva.gesundheitsid.relyingparty.cfg.ConfigProvider; import com.oviva.gesundheitsid.relyingparty.cfg.EnvConfigProvider; +import com.oviva.gesundheitsid.relyingparty.cfg.RelyingPartyConfig; import com.oviva.gesundheitsid.relyingparty.fed.FederationConfig; import com.oviva.gesundheitsid.relyingparty.poc.GematikHeaderDecoratorHttpClient; import com.oviva.gesundheitsid.relyingparty.svc.InMemoryCodeRepo; import com.oviva.gesundheitsid.relyingparty.svc.InMemorySessionRepo; import com.oviva.gesundheitsid.relyingparty.svc.KeyStore; import com.oviva.gesundheitsid.relyingparty.svc.TokenIssuerImpl; +import com.oviva.gesundheitsid.relyingparty.util.Strings; import com.oviva.gesundheitsid.relyingparty.ws.App; import com.oviva.gesundheitsid.util.JwksUtils; import jakarta.ws.rs.SeBootstrap; @@ -41,56 +43,50 @@ public class Main { \\____/|___/_/|___/\\_,_/ GesundheitsID OpenID Connect Relying-Party """; + private final ConfigProvider configProvider; + + public Main(ConfigProvider configProvider) { + this.configProvider = configProvider; + } public static void main(String[] args) throws ExecutionException, InterruptedException { - var main = new Main(); - main.run(new EnvConfigProvider("OIDC_SERVER", System::getenv)); + var main = new Main(new EnvConfigProvider("OIDC_SERVER", System::getenv)); + main.run(); } - public void run(ConfigProvider configProvider) throws ExecutionException, InterruptedException { + public void run() throws ExecutionException, InterruptedException { + logger.atInfo().log("\n" + BANNER); + var federationEncJwksPath = loadJwks("federation_enc_jwks_path"); + var federationSigJwksPath = loadJwks("federation_sig_jwks_path"); + + var validRedirectUris = loadAllowedRedirectUrls(); + + // TODO load from config var baseUri = URI.create("https://t.oviva.io"); - var validRedirectUris = - List.of(URI.create("https://idp-test.oviva.io/auth/realms/master/broker/oidc/endpoint")); var supportedResponseTypes = List.of("code"); - var port = - configProvider.get("port").stream().mapToInt(Integer::parseInt).findFirst().orElse(1234); - var config = - new Config( - port, - baseUri, // TOOD: hardcoded :) - // configProvider.get("base_uri").map(URI::create).orElse(URI.create("http://localhost:" - // + port)), - supportedResponseTypes, - validRedirectUris // TODO: hardcoded :) - - // configProvider.get("redirect_uris").stream() - // .flatMap(Strings::mustParseCommaList) - // .map(URI::create) - // .toList() - ); + var port = getPortConfig(); + + var config = new RelyingPartyConfig(port, baseUri, supportedResponseTypes, validRedirectUris); var keyStore = new KeyStore(); var tokenIssuer = new TokenIssuerImpl(config.baseUri(), keyStore, new InMemoryCodeRepo()); var sessionRepo = new InMemorySessionRepo(); + // TODO // setup your environment, your own issuer MUST serve a _valid_ and _trusted_ entity // configuration // see: https://wiki.gematik.de/pages/viewpage.action?pageId=544316583 var fedmaster = URI.create("https://app-test.federationmaster.de"); // TODO replace with `baseUri` - var self = URI.create("https://idp-test.oviva.io/auth/realms/master/ehealthid"); - - var authFlow = buildAuthFlow(baseUri, fedmaster); + var federationIssuer = URI.create("https://idp-test.oviva.io/auth/realms/master/ehealthid"); - // TODO make path configurable - var relyingPartyEncryptionJwks = JwksUtils.load(Path.of("./relying-party-enc_jwks.json")); - var relyingPartySigningJwks = JwksUtils.load(Path.of("./relying-party-sig_jwks.json")); + var authFlow = buildAuthFlow(baseUri, fedmaster, federationEncJwksPath); var federationConfig = FederationConfig.create() @@ -98,9 +94,9 @@ public void run(ConfigProvider configProvider) throws ExecutionException, Interr .iss(baseUri) .appName("Oviva Direkt") .federationMaster(fedmaster) - .entitySigningKey(relyingPartySigningJwks.getKeys().get(0).toECKey()) - .entitySigningKeys(relyingPartySigningJwks.toPublicJWKSet()) - .relyingPartyEncKeys(relyingPartyEncryptionJwks.toPublicJWKSet()) + .entitySigningKey(federationSigJwksPath.getKeys().get(0).toECKey()) + .entitySigningKeys(federationSigJwksPath.toPublicJWKSet()) + .relyingPartyEncKeys(federationEncJwksPath.toPublicJWKSet()) // TODO: bump up to hours, once we're confident it's correct ;) // the spec says ~1 day @@ -122,11 +118,25 @@ public void run(ConfigProvider configProvider) throws ExecutionException, Interr Thread.currentThread().join(); } - private AuthenticationFlow buildAuthFlow(URI selfIssuer, URI fedmaster) { + private int getPortConfig() { + return configProvider.get("port").stream().mapToInt(Integer::parseInt).findFirst().orElse(1234); + } + + private JWKSet loadJwks(String configName) { - // path to the JWKS containing the private keys to decrypt ID tokens, the public part - // is in your entity configuration - var relyingPartyEncryptionJwks = JwksUtils.load(Path.of("./relying-party-enc_jwks.json")); + var path = + configProvider + .get(configName) + .map(Path::of) + .orElseThrow( + () -> + new IllegalArgumentException( + "missing jwks path for '%s'".formatted(configName))); + + return JwksUtils.load(path); + } + + private AuthenticationFlow buildAuthFlow(URI selfIssuer, URI fedmaster, JWKSet encJwks) { // setup the file `.env.properties` to provide the X-Authorization header for the Gematik // test environment @@ -148,6 +158,22 @@ private AuthenticationFlow buildAuthFlow(URI selfIssuer, URI fedmaster) { var openIdClient = new OpenIdClient(httpClient); return new AuthenticationFlow( - selfIssuer, fedmasterClient, openIdClient, relyingPartyEncryptionJwks::getKeyByKeyId); + selfIssuer, fedmasterClient, openIdClient, encJwks::getKeyByKeyId); + } + + private List loadAllowedRedirectUrls() { + + var redirectUris = + configProvider.get("redirect_uris").stream() + .flatMap(Strings::mustParseCommaList) + .map(URI::create) + .toList(); + + if (!redirectUris.isEmpty()) { + return redirectUris; + } + + // TODO: hardcoded + return List.of(URI.create("https://idp-test.oviva.io/auth/realms/master/broker/oidc/endpoint")); } } diff --git a/oidc-server/src/main/java/com/oviva/gesundheitsid/relyingparty/cfg/Config.java b/oidc-server/src/main/java/com/oviva/gesundheitsid/relyingparty/cfg/RelyingPartyConfig.java similarity index 84% rename from oidc-server/src/main/java/com/oviva/gesundheitsid/relyingparty/cfg/Config.java rename to oidc-server/src/main/java/com/oviva/gesundheitsid/relyingparty/cfg/RelyingPartyConfig.java index d176a76..82a8cc5 100644 --- a/oidc-server/src/main/java/com/oviva/gesundheitsid/relyingparty/cfg/Config.java +++ b/oidc-server/src/main/java/com/oviva/gesundheitsid/relyingparty/cfg/RelyingPartyConfig.java @@ -3,5 +3,5 @@ import java.net.URI; import java.util.List; -public record Config( +public record RelyingPartyConfig( int port, URI baseUri, List supportedResponseTypes, List validRedirectUris) {} diff --git a/oidc-server/src/main/java/com/oviva/gesundheitsid/relyingparty/ws/App.java b/oidc-server/src/main/java/com/oviva/gesundheitsid/relyingparty/ws/App.java index ab290d3..1286e9f 100644 --- a/oidc-server/src/main/java/com/oviva/gesundheitsid/relyingparty/ws/App.java +++ b/oidc-server/src/main/java/com/oviva/gesundheitsid/relyingparty/ws/App.java @@ -4,7 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.jakarta.rs.json.JacksonJsonProvider; import com.oviva.gesundheitsid.auth.AuthenticationFlow; -import com.oviva.gesundheitsid.relyingparty.cfg.Config; +import com.oviva.gesundheitsid.relyingparty.cfg.RelyingPartyConfig; import com.oviva.gesundheitsid.relyingparty.fed.FederationConfig; import com.oviva.gesundheitsid.relyingparty.fed.FederationEndpoint; import com.oviva.gesundheitsid.relyingparty.svc.KeyStore; @@ -16,7 +16,7 @@ public class App extends Application { - private final Config config; + private final RelyingPartyConfig relyingPartyConfig; private final FederationConfig federationConfig; private final SessionRepo sessionRepo; @@ -26,13 +26,13 @@ public class App extends Application { private final AuthenticationFlow authenticationFlow; public App( - Config config, + RelyingPartyConfig relyingPartyConfig, FederationConfig federationConfig, SessionRepo sessionRepo, KeyStore keyStore, TokenIssuer tokenIssuer, AuthenticationFlow authenticationFlow) { - this.config = config; + this.relyingPartyConfig = relyingPartyConfig; this.federationConfig = federationConfig; this.sessionRepo = sessionRepo; this.keyStore = keyStore; @@ -45,8 +45,8 @@ public Set getSingletons() { return Set.of( new FederationEndpoint(federationConfig), - new AuthEndpoint(config, sessionRepo, tokenIssuer, authenticationFlow), - new OpenIdEndpoint(config, keyStore), + new AuthEndpoint(relyingPartyConfig, sessionRepo, tokenIssuer, authenticationFlow), + new OpenIdEndpoint(relyingPartyConfig, keyStore), new JacksonJsonProvider(configureObjectMapper())); } diff --git a/oidc-server/src/main/java/com/oviva/gesundheitsid/relyingparty/ws/AuthEndpoint.java b/oidc-server/src/main/java/com/oviva/gesundheitsid/relyingparty/ws/AuthEndpoint.java index 29686cf..ca647e0 100644 --- a/oidc-server/src/main/java/com/oviva/gesundheitsid/relyingparty/ws/AuthEndpoint.java +++ b/oidc-server/src/main/java/com/oviva/gesundheitsid/relyingparty/ws/AuthEndpoint.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.oviva.gesundheitsid.auth.AuthenticationFlow; -import com.oviva.gesundheitsid.relyingparty.cfg.Config; +import com.oviva.gesundheitsid.relyingparty.cfg.RelyingPartyConfig; import com.oviva.gesundheitsid.relyingparty.svc.SessionRepo; import com.oviva.gesundheitsid.relyingparty.svc.SessionRepo.Session; import com.oviva.gesundheitsid.relyingparty.svc.TokenIssuer; @@ -34,7 +34,7 @@ @Path("/auth") public class AuthEndpoint { - private final Config config; + private final RelyingPartyConfig relyingPartyConfig; private final SessionRepo sessionRepo; private final TokenIssuer tokenIssuer; @@ -42,11 +42,11 @@ public class AuthEndpoint { private final AuthenticationFlow authenticationFlow; public AuthEndpoint( - Config config, + RelyingPartyConfig relyingPartyConfig, SessionRepo sessionRepo, TokenIssuer tokenIssuer, AuthenticationFlow authenticationFlow) { - this.config = config; + this.relyingPartyConfig = relyingPartyConfig; this.sessionRepo = sessionRepo; this.tokenIssuer = tokenIssuer; this.authenticationFlow = authenticationFlow; @@ -98,7 +98,7 @@ public Response auth( .build(); } - if (!config.validRedirectUris().contains(parsedRedirect)) { + if (!relyingPartyConfig.validRedirectUris().contains(parsedRedirect)) { // TODO nice form return Response.status(Status.BAD_REQUEST) .entity("untrusted 'redirect_uri': %s".formatted(parsedRedirect)) @@ -113,7 +113,7 @@ public Response auth( "scope '%s' not supported".formatted(scope)); } - if (!config.supportedResponseTypes().contains(responseType)) { + if (!relyingPartyConfig.supportedResponseTypes().contains(responseType)) { return OpenIdErrorResponses.redirectWithError( parsedRedirect, ErrorCode.UNSUPPORTED_RESPONSE_TYPE, @@ -132,7 +132,7 @@ public Response auth( var codeChallenge = calculateS256CodeChallenge(verifier); // ==== 1) start a new flow - var relyingPartyCallback = config.baseUri().resolve("/auth/callback"); + var relyingPartyCallback = relyingPartyConfig.baseUri().resolve("/auth/callback"); var step1 = authenticationFlow.start( diff --git a/oidc-server/src/main/java/com/oviva/gesundheitsid/relyingparty/ws/OpenIdEndpoint.java b/oidc-server/src/main/java/com/oviva/gesundheitsid/relyingparty/ws/OpenIdEndpoint.java index b100bf9..e4a7d23 100644 --- a/oidc-server/src/main/java/com/oviva/gesundheitsid/relyingparty/ws/OpenIdEndpoint.java +++ b/oidc-server/src/main/java/com/oviva/gesundheitsid/relyingparty/ws/OpenIdEndpoint.java @@ -1,7 +1,7 @@ package com.oviva.gesundheitsid.relyingparty.ws; import com.nimbusds.jose.jwk.JWKSet; -import com.oviva.gesundheitsid.relyingparty.cfg.Config; +import com.oviva.gesundheitsid.relyingparty.cfg.RelyingPartyConfig; import com.oviva.gesundheitsid.relyingparty.svc.KeyStore; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; @@ -15,11 +15,11 @@ @Path("/") public class OpenIdEndpoint { - private final Config config; + private final RelyingPartyConfig relyingPartyConfig; private final KeyStore keyStore; - public OpenIdEndpoint(Config config, KeyStore keyStore) { - this.config = config; + public OpenIdEndpoint(RelyingPartyConfig relyingPartyConfig, KeyStore keyStore) { + this.relyingPartyConfig = relyingPartyConfig; this.keyStore = keyStore; } @@ -30,12 +30,12 @@ public Response openIdConfiguration() { var body = new OpenIdConfiguration( - config.baseUri().toString(), - config.baseUri().resolve("/auth").toString(), - config.baseUri().resolve("/token").toString(), - config.baseUri().resolve("/jwks.json").toString(), + relyingPartyConfig.baseUri().toString(), + relyingPartyConfig.baseUri().resolve("/auth").toString(), + relyingPartyConfig.baseUri().resolve("/token").toString(), + relyingPartyConfig.baseUri().resolve("/jwks.json").toString(), List.of("openid"), - config.supportedResponseTypes(), + relyingPartyConfig.supportedResponseTypes(), List.of("authorization_code"), List.of("public"), List.of("ES256"), diff --git a/oidc-server/src/main/resources/logback.xml b/oidc-server/src/main/resources/logback.xml new file mode 100644 index 0000000..ed111f4 --- /dev/null +++ b/oidc-server/src/main/resources/logback.xml @@ -0,0 +1,32 @@ + + + + + + + timestamp + yyyy-MM-dd'T'HH:mm:ss.SSSX + UTC + + + + + + + + + { + "logger": "%logger", + "severity": "%level", + "thread": "%thread", + "message": "%message" + } + + + + + + + + + \ No newline at end of file diff --git a/oidc-server/src/test/java/com/oviva/gesundheitsid/relyingparty/ws/AuthEndpointTest.java b/oidc-server/src/test/java/com/oviva/gesundheitsid/relyingparty/ws/AuthEndpointTest.java index ec8d323..f8840d9 100644 --- a/oidc-server/src/test/java/com/oviva/gesundheitsid/relyingparty/ws/AuthEndpointTest.java +++ b/oidc-server/src/test/java/com/oviva/gesundheitsid/relyingparty/ws/AuthEndpointTest.java @@ -8,7 +8,7 @@ import com.oviva.gesundheitsid.auth.AuthenticationFlow; import com.oviva.gesundheitsid.auth.steps.SelectSectoralIdpStep; import com.oviva.gesundheitsid.auth.steps.TrustedSectoralIdpStep; -import com.oviva.gesundheitsid.relyingparty.cfg.Config; +import com.oviva.gesundheitsid.relyingparty.cfg.RelyingPartyConfig; import com.oviva.gesundheitsid.relyingparty.svc.SessionRepo; import com.oviva.gesundheitsid.relyingparty.svc.TokenIssuer; import com.oviva.gesundheitsid.relyingparty.svc.TokenIssuer.Code; @@ -30,7 +30,7 @@ class AuthEndpointTest { @Test void auth_badScopes() { - var config = new Config(0, BASE_URI, null, List.of(REDIRECT_URI)); + var config = new RelyingPartyConfig(0, BASE_URI, null, List.of(REDIRECT_URI)); var sut = new AuthEndpoint(config, null, null, null); @@ -54,7 +54,7 @@ void auth_badScopes() { @Test void auth_malformedRedirect() { - var config = new Config(0, BASE_URI, null, List.of(REDIRECT_URI)); + var config = new RelyingPartyConfig(0, BASE_URI, null, List.of(REDIRECT_URI)); var sut = new AuthEndpoint(config, null, null, null); @@ -74,7 +74,7 @@ void auth_malformedRedirect() { @Test void auth_untrustedRedirect() { - var config = new Config(0, BASE_URI, null, List.of(REDIRECT_URI)); + var config = new RelyingPartyConfig(0, BASE_URI, null, List.of(REDIRECT_URI)); var sut = new AuthEndpoint(config, null, null, null); @@ -97,7 +97,7 @@ void auth_untrustedRedirect() { @Test void auth_badResponseType() { - var config = new Config(0, BASE_URI, List.of("code"), List.of(REDIRECT_URI)); + var config = new RelyingPartyConfig(0, BASE_URI, List.of("code"), List.of(REDIRECT_URI)); var sessionRepo = mock(SessionRepo.class); var sut = new AuthEndpoint(config, sessionRepo, null, null); @@ -126,7 +126,7 @@ void auth_badResponseType() { @Test void auth_success() { - var config = new Config(0, BASE_URI, List.of("code"), List.of(REDIRECT_URI)); + var config = new RelyingPartyConfig(0, BASE_URI, List.of("code"), List.of(REDIRECT_URI)); var idpRedirectUrl = URI.create("https://federated-idp.example.com"); @@ -170,7 +170,7 @@ void auth_success() { @ValueSource(strings = {" ", " \n\t"}) void callback_noSessionId(String sessionId) { - var config = new Config(0, null, null, null); + var config = new RelyingPartyConfig(0, null, null, null); var sut = new AuthEndpoint(config, null, null, null); @@ -185,7 +185,7 @@ void callback_noSessionId(String sessionId) { @Test void callback_unknownSession() { - var config = new Config(0, null, null, null); + var config = new RelyingPartyConfig(0, null, null, null); var sessionRepo = mock(SessionRepo.class); @@ -206,7 +206,7 @@ void callback_unknownSession() { @Test void callback() { - var config = new Config(0, BASE_URI, List.of("code"), List.of(REDIRECT_URI)); + var config = new RelyingPartyConfig(0, BASE_URI, List.of("code"), List.of(REDIRECT_URI)); var sessionRepo = mock(SessionRepo.class); var tokenIssuer = mock(TokenIssuer.class); @@ -246,7 +246,7 @@ void callback() { @Test void token_badGrantType() { - var config = new Config(0, BASE_URI, List.of("code"), List.of(REDIRECT_URI)); + var config = new RelyingPartyConfig(0, BASE_URI, List.of("code"), List.of(REDIRECT_URI)); var tokenIssuer = mock(TokenIssuer.class); @@ -271,7 +271,7 @@ void token_badGrantType() { @Test void token_badCode() { - var config = new Config(0, BASE_URI, List.of("code"), List.of(REDIRECT_URI)); + var config = new RelyingPartyConfig(0, BASE_URI, List.of("code"), List.of(REDIRECT_URI)); var tokenIssuer = mock(TokenIssuer.class); @@ -296,7 +296,7 @@ void token_badCode() { @Test void token() { - var config = new Config(0, BASE_URI, List.of("code"), List.of(REDIRECT_URI)); + var config = new RelyingPartyConfig(0, BASE_URI, List.of("code"), List.of(REDIRECT_URI)); var tokenIssuer = mock(TokenIssuer.class); diff --git a/oidc-server/src/test/java/com/oviva/gesundheitsid/relyingparty/ws/OpenIdEndpointTest.java b/oidc-server/src/test/java/com/oviva/gesundheitsid/relyingparty/ws/OpenIdEndpointTest.java index d9956ee..2197edb 100644 --- a/oidc-server/src/test/java/com/oviva/gesundheitsid/relyingparty/ws/OpenIdEndpointTest.java +++ b/oidc-server/src/test/java/com/oviva/gesundheitsid/relyingparty/ws/OpenIdEndpointTest.java @@ -6,7 +6,7 @@ import com.nimbusds.jose.jwk.ECKey; import com.nimbusds.jose.jwk.JWKSet; -import com.oviva.gesundheitsid.relyingparty.cfg.Config; +import com.oviva.gesundheitsid.relyingparty.cfg.RelyingPartyConfig; import com.oviva.gesundheitsid.relyingparty.svc.KeyStore; import java.net.URI; import java.text.ParseException; @@ -20,7 +20,7 @@ class OpenIdEndpointTest { @Test void openIdConfiguration() { - var config = new Config(0, BASE_URI, null, null); + var config = new RelyingPartyConfig(0, BASE_URI, null, null); var sut = new OpenIdEndpoint(config, null); // when diff --git a/pom.xml b/pom.xml index 5c6ec2b..3c6ec3c 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ 2.0.10 9.37.3 1.4.14 - 0.1.5 + 7.4 2.41.1 1.18.1 @@ -61,6 +61,7 @@ + esgen gesundheitsid oidc-server reports @@ -147,14 +148,9 @@ ${version.logback.classic} - ch.qos.logback.contrib - logback-json-classic - ${version.logback.json} - - - ch.qos.logback.contrib - logback-jackson - ${version.logback.json} + net.logstash.logback + logstash-logback-encoder + ${version.logback.encoder} com.google.auto.service @@ -329,6 +325,10 @@ maven-source-plugin 3.9.1 + + maven-assembly-plugin + 3.6.0 + diff --git a/start.sh b/start.sh new file mode 100755 index 0000000..df64dd9 --- /dev/null +++ b/start.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +export OIDC_SERVER_FEDERATION_ENC_JWKS_PATH=enc_jwks.json +export OIDC_SERVER_FEDERATION_SIG_JWKS_PATH=sig_jwks.json + +java -jar oidc-server/target/oidc-server-*-jar-with-dependencies.jar