Code development platform for open source projects from the European Union institutions

Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • simpl/simpl-open/development/iaa/tier2-gateway
1 result
Show changes
Commits on Source (45)
Showing
with 169 additions and 150 deletions
File added
...@@ -2,3 +2,4 @@ ...@@ -2,3 +2,4 @@
Refer to [licence description](https://eupl.eu/1.2/en/) Refer to [licence description](https://eupl.eu/1.2/en/)
SIMPL is granting credits to open source projects referred in the CREDITS.pdf file.
\ No newline at end of file
...@@ -16,8 +16,6 @@ data: ...@@ -16,8 +16,6 @@ data:
USERS_ROLES_URL: {{ .Values.microservices.usersRolesUrl }} USERS_ROLES_URL: {{ .Values.microservices.usersRolesUrl }}
SPRING_PROFILES_ACTIVE: {{ .Values.global.profile }} SPRING_PROFILES_ACTIVE: {{ .Values.global.profile }}
CORS_ALLOWED_HEADERS: Access-Control-Allow-Headers,Access-Control-Allow-Credentials,Access-Control-Allow-Origin,Access-Control-Allow-Methods,Keep-Alive,User-Agent,Content-Type,Authorization,Tenant,Channel,Platform,Set-Cookie,geolocation,x-mobility-mode,device,Cache-Control,X-Request-With,Accept,Origin
CORS_ALLOWED_ORIGINS: {{ .Values.global.cors.allowOrigin }}
SPRING_DATA_REDIS_HOST: "{{ .Values.redis.host }}" SPRING_DATA_REDIS_HOST: "{{ .Values.redis.host }}"
SPRING_DATA_REDIS_PORT: "{{ .Values.redis.port }}" SPRING_DATA_REDIS_PORT: "{{ .Values.redis.port }}"
......
PROJECT_VERSION_NUMBER="1.0.0" PROJECT_VERSION_NUMBER="1.0.2"
\ No newline at end of file \ No newline at end of file
...@@ -5,12 +5,12 @@ ...@@ -5,12 +5,12 @@
<parent> <parent>
<groupId>eu.europa.ec.simpl</groupId> <groupId>eu.europa.ec.simpl</groupId>
<artifactId>simpl-parent</artifactId> <artifactId>simpl-parent</artifactId>
<version>1.0.0-RC</version> <version>1.0.1</version>
<relativePath/> <!-- lookup parent from repository --> <relativePath/> <!-- lookup parent from repository -->
</parent> </parent>
<artifactId>tls-gateway</artifactId> <artifactId>tls-gateway</artifactId>
<version>1.0.0-RC</version> <version>1.0.2</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>tls-gateway</name> <name>tls-gateway</name>
......
package eu.europa.ec.simpl.tlsgateway.configurations; package eu.europa.ec.simpl.tlsgateway.configurations;
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(value = "cors") @ConfigurationProperties(prefix = "keypair")
public record CorsProperties(List<String> allowedOrigins, List<String> allowedHeaders) {} public record AuthorityKeypairProperties(String algorithm) {}
package eu.europa.ec.simpl.tlsgateway.configurations;
import eu.europa.ec.simpl.tlsgateway.filters.OrderedGlobalFilter;
import java.util.List;
import java.util.Optional;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.Ordered;
@ConfigurationProperties(prefix = "global-filters")
public class GlobalFilterProperties {
private final List<Class<? extends OrderedGlobalFilter>> order;
public GlobalFilterProperties(List<Class<? extends OrderedGlobalFilter>> order) {
this.order = order;
}
public int getOrder(Class<? extends OrderedGlobalFilter> filterClass) {
return Optional.ofNullable(filterClass)
.map(order::indexOf)
.map(i -> Ordered.HIGHEST_PRECEDENCE + i)
.orElse(Ordered.LOWEST_PRECEDENCE);
}
}
...@@ -44,7 +44,7 @@ public record LoggingRule( ...@@ -44,7 +44,7 @@ public record LoggingRule(
.map(isMatch -> isMatch && matchQuery(exchange) && matchHeaders(exchange)); .map(isMatch -> isMatch && matchQuery(exchange) && matchHeaders(exchange));
} }
private boolean matchQuery(ServerWebExchange exchange) { protected boolean matchQuery(ServerWebExchange exchange) {
return Optional.ofNullable(query()) return Optional.ofNullable(query())
.map(Collection::stream) .map(Collection::stream)
.map(query -> query.map(q -> q.matches(exchange.getRequest().getQueryParams())) .map(query -> query.map(q -> q.matches(exchange.getRequest().getQueryParams()))
...@@ -53,7 +53,7 @@ public record LoggingRule( ...@@ -53,7 +53,7 @@ public record LoggingRule(
.orElse(true); .orElse(true);
} }
private boolean matchHeaders(ServerWebExchange exchange) { protected boolean matchHeaders(ServerWebExchange exchange) {
return Optional.ofNullable(header()) return Optional.ofNullable(header())
.map(Collection::stream) .map(Collection::stream)
.map(header -> header.map(h -> h.matches(exchange.getRequest().getHeaders())) .map(header -> header.map(h -> h.matches(exchange.getRequest().getHeaders()))
......
...@@ -19,6 +19,6 @@ public class ParticipantPublicKeyProducer extends AbstractPublicKeyProducer { ...@@ -19,6 +19,6 @@ public class ParticipantPublicKeyProducer extends AbstractPublicKeyProducer {
@Override @Override
protected String getAuthorityPublicKeyBaseUrl() { protected String getAuthorityPublicKeyBaseUrl() {
return "%s/public/user-api".formatted(clientProperties.authorityUrl()); return "%s/user-api".formatted(clientProperties.authorityUrl());
} }
} }
package eu.europa.ec.simpl.tlsgateway.configurations.security;
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
public class NoMtlsMatcher implements ServerWebExchangeMatcher {
@Override
public Mono<MatchResult> matches(ServerWebExchange exchange) {
var path = exchange.getRequest().getURI().getPath();
return path.contains("mtls") ? MatchResult.notMatch() : MatchResult.match();
}
}
package eu.europa.ec.simpl.tlsgateway.configurations.security; package eu.europa.ec.simpl.tlsgateway.configurations.security;
import eu.europa.ec.simpl.common.model.constants.SimplHeaders; import eu.europa.ec.simpl.common.constants.SimplHeaders;
import eu.europa.ec.simpl.tlsgateway.exceptions.AbacException; import eu.europa.ec.simpl.tlsgateway.exceptions.AbacException;
import java.util.*; import java.util.*;
import java.util.function.Predicate; import java.util.function.Predicate;
......
package eu.europa.ec.simpl.tlsgateway.configurations.security; package eu.europa.ec.simpl.tlsgateway.configurations.security;
import eu.europa.ec.simpl.tlsgateway.configurations.CorsProperties;
import java.util.List; import java.util.List;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
...@@ -12,9 +11,6 @@ import org.springframework.security.web.server.SecurityWebFilterChain; ...@@ -12,9 +11,6 @@ import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher; import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher;
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers; import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsConfigurationSource;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
@Log4j2 @Log4j2
@Configuration @Configuration
...@@ -62,15 +58,4 @@ public class SecurityConfig { ...@@ -62,15 +58,4 @@ public class SecurityConfig {
.map(rule -> ServerWebExchangeMatchers.pathMatchers(rule.method(), rule.path())) .map(rule -> ServerWebExchangeMatchers.pathMatchers(rule.method(), rule.path()))
.toList(); .toList();
} }
@Bean
public CorsConfigurationSource corsConfigurationSource(CorsProperties corsProperties) {
var configuration = new CorsConfiguration();
configuration.setAllowedOrigins(corsProperties.allowedOrigins());
configuration.setAllowedHeaders(corsProperties.allowedHeaders());
configuration.setAllowedMethods(List.of("*"));
var source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
} }
package eu.europa.ec.simpl.tlsgateway.configurations.ssl;
import eu.europa.ec.simpl.common.model.dto.KeyPairDTO;
import eu.europa.ec.simpl.common.utils.CredentialUtil;
import eu.europa.ec.simpl.tlsgateway.configurations.AuthorityKeypairProperties;
import eu.europa.ec.simpl.tlsgateway.configurations.microservices.AuthenticationProviderProperties;
import eu.europa.ec.simpl.tlsgateway.exceptions.InvalidPrivateKeyException;
import java.security.PrivateKey;
import lombok.SneakyThrows;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
@Component
public class AuthenticationProviderClient {
private final AuthorityKeypairProperties authorityKeypairProperties;
private final AuthenticationProviderProperties authenticationProviderProperties;
public AuthenticationProviderClient(
AuthenticationProviderProperties authenticationProviderProperties,
AuthorityKeypairProperties authorityKeypairProperties) {
this.authenticationProviderProperties = authenticationProviderProperties;
this.authorityKeypairProperties = authorityKeypairProperties;
}
@SneakyThrows
public PrivateKey loadPrivateKey() {
return WebClient.builder()
.baseUrl("%s/keypair".formatted(authenticationProviderProperties.url()))
.build()
.get()
.retrieve()
.bodyToMono(KeyPairDTO.class)
.map(KeyPairDTO::getPrivateKey)
.map(privateKey -> CredentialUtil.loadPrivateKey(privateKey, authorityKeypairProperties.algorithm()))
.doOnError(e -> {
throw new InvalidPrivateKeyException(
"Failed to load private key from %s".formatted(authenticationProviderProperties.url()));
})
.block();
}
}
package eu.europa.ec.simpl.tlsgateway.configurations.ssl; package eu.europa.ec.simpl.tlsgateway.configurations.ssl;
import eu.europa.ec.simpl.common.model.dto.KeyPairDTO;
import eu.europa.ec.simpl.common.utils.CredentialUtil; import eu.europa.ec.simpl.common.utils.CredentialUtil;
import eu.europa.ec.simpl.tlsgateway.configurations.microservices.AuthenticationProviderProperties;
import eu.europa.ec.simpl.tlsgateway.configurations.microservices.UsersRolesProperties;
import eu.europa.ec.simpl.tlsgateway.exceptions.InvalidCertificateException;
import eu.europa.ec.simpl.tlsgateway.exceptions.InvalidPrivateKeyException;
import java.io.*; import java.io.*;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.*; import java.nio.file.*;
import java.security.*; import java.security.*;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.util.Optional; import java.util.Optional;
import lombok.SneakyThrows; import lombok.extern.log4j.Log4j2;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
import org.springframework.boot.web.server.Ssl; import org.springframework.boot.web.server.Ssl;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;
@Log4j2
@Configuration @Configuration
public class SslConfig { public class SslConfig {
private static final Logger log = LogManager.getLogger(SslConfig.class);
private final SslProperties sslProperties; private final SslProperties sslProperties;
private final UsersRolesProperties usersRolesProperties; private final UsersRolesClient usersRolesClient;
private final String keyPairAlgorithm; private final AuthenticationProviderClient authenticationProviderClient;
private final AuthenticationProviderProperties authenticationProviderProperties;
public SslConfig( public SslConfig(
SslProperties sslProperties, SslProperties sslProperties,
UsersRolesProperties usersRolesProperties, UsersRolesClient usersRolesClient,
@Value("${keypair.algorithm}") String keyPairAlgorithm, AuthenticationProviderClient authenticationProviderClient) {
AuthenticationProviderProperties authenticationProviderProperties) {
this.sslProperties = sslProperties; this.sslProperties = sslProperties;
this.usersRolesProperties = usersRolesProperties; this.usersRolesClient = usersRolesClient;
this.keyPairAlgorithm = keyPairAlgorithm; this.authenticationProviderClient = authenticationProviderClient;
this.authenticationProviderProperties = authenticationProviderProperties;
} }
@Bean @Bean
...@@ -52,9 +39,9 @@ public class SslConfig { ...@@ -52,9 +39,9 @@ public class SslConfig {
if (ssl.isEnabled()) { if (ssl.isEnabled()) {
ssl.setClientAuth(sslProperties.clientAuth()); ssl.setClientAuth(sslProperties.clientAuth());
var rawKeyStore = loadPemCertificates(); var rawKeyStore = usersRolesClient.loadPemCertificates();
var privateKey = loadPrivateKey(); var privateKey = authenticationProviderClient.loadPrivateKey();
var keyStore = CredentialUtil.loadCredential( var keyStore = CredentialUtil.loadCredential(
new ByteArrayInputStream(rawKeyStore.getBytes(StandardCharsets.UTF_8)), privateKey); new ByteArrayInputStream(rawKeyStore.getBytes(StandardCharsets.UTF_8)), privateKey);
...@@ -70,23 +57,6 @@ public class SslConfig { ...@@ -70,23 +57,6 @@ public class SslConfig {
return ssl; return ssl;
} }
@SneakyThrows
private PrivateKey loadPrivateKey() {
return WebClient.builder()
.baseUrl("%s/keypair".formatted(authenticationProviderProperties.url()))
.build()
.get()
.retrieve()
.bodyToMono(KeyPairDTO.class)
.map(KeyPairDTO::getPrivateKey)
.map(privateKey -> CredentialUtil.loadPrivateKey(privateKey, keyPairAlgorithm))
.doOnError(e -> {
throw new InvalidPrivateKeyException(
"Failed to load private key from %s".formatted(authenticationProviderProperties.url()));
})
.block();
}
@Bean @Bean
public NettyReactiveWebServerFactory reactiveWebServerFactory(Ssl ssl) { public NettyReactiveWebServerFactory reactiveWebServerFactory(Ssl ssl) {
NettyReactiveWebServerFactory factory = new NettyReactiveWebServerFactory(); NettyReactiveWebServerFactory factory = new NettyReactiveWebServerFactory();
...@@ -94,22 +64,6 @@ public class SslConfig { ...@@ -94,22 +64,6 @@ public class SslConfig {
return factory; return factory;
} }
private String loadPemCertificates() {
return WebClient.builder()
.baseUrl("%s/credential/download".formatted(usersRolesProperties.url()))
.defaultHeader("Content-Type", MediaType.APPLICATION_OCTET_STREAM_VALUE)
.build()
.get()
.retrieve()
.bodyToMono(byte[].class)
.map(res -> new String(res, StandardCharsets.UTF_8))
.doOnError(e -> {
throw new InvalidCertificateException(
"Failed to load certificate from %s".formatted(usersRolesProperties.url()));
})
.block();
}
private void writeKeyStore(KeyStore keyStore) private void writeKeyStore(KeyStore keyStore)
throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException { throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
......
package eu.europa.ec.simpl.tlsgateway.configurations.ssl;
import eu.europa.ec.simpl.tlsgateway.configurations.microservices.UsersRolesProperties;
import eu.europa.ec.simpl.tlsgateway.exceptions.InvalidCertificateException;
import java.nio.charset.StandardCharsets;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
@Component
public class UsersRolesClient {
private final UsersRolesProperties usersRolesProperties;
public UsersRolesClient(UsersRolesProperties usersRolesProperties) {
this.usersRolesProperties = usersRolesProperties;
}
public String loadPemCertificates() {
return WebClient.builder()
.baseUrl("%s/credential/download".formatted(usersRolesProperties.url()))
.defaultHeader("Content-Type", MediaType.APPLICATION_OCTET_STREAM_VALUE)
.build()
.get()
.retrieve()
.bodyToMono(byte[].class)
.map(res -> new String(res, StandardCharsets.UTF_8))
.doOnError(e -> {
throw new InvalidCertificateException(
"Failed to load certificate from %s".formatted(usersRolesProperties.url()));
})
.block();
}
}
package eu.europa.ec.simpl.tlsgateway.filters; package eu.europa.ec.simpl.tlsgateway.filters;
import eu.europa.ec.simpl.tlsgateway.configurations.GlobalFilterProperties;
import eu.europa.ec.simpl.tlsgateway.configurations.security.RouteConfig; import eu.europa.ec.simpl.tlsgateway.configurations.security.RouteConfig;
import eu.europa.ec.simpl.tlsgateway.configurations.security.Rule; import eu.europa.ec.simpl.tlsgateway.configurations.security.Rule;
import java.util.function.Predicate; import java.util.function.Predicate;
import org.slf4j.Logger; import lombok.extern.log4j.Log4j2;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
@Log4j2
@Component @Component
public class AbacFilter implements GlobalFilter, Ordered { public class AbacFilter extends OrderedGlobalFilter {
private static final Logger log = LoggerFactory.getLogger(AbacFilter.class);
private final RouteConfig routeConfig; private final RouteConfig routeConfig;
public AbacFilter(RouteConfig routeConfig) { public AbacFilter(RouteConfig routeConfig, GlobalFilterProperties globalFilterProperties) {
super(globalFilterProperties);
this.routeConfig = routeConfig; this.routeConfig = routeConfig;
} }
...@@ -41,9 +40,4 @@ public class AbacFilter implements GlobalFilter, Ordered { ...@@ -41,9 +40,4 @@ public class AbacFilter implements GlobalFilter, Ordered {
.flatMap(rule -> rule.checkPrivilege(exchange)) .flatMap(rule -> rule.checkPrivilege(exchange))
.then(chain.filter(exchange)); .then(chain.filter(exchange));
} }
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE + 3;
}
} }
...@@ -2,13 +2,15 @@ package eu.europa.ec.simpl.tlsgateway.filters; ...@@ -2,13 +2,15 @@ package eu.europa.ec.simpl.tlsgateway.filters;
import com.nimbusds.jose.JOSEException; import com.nimbusds.jose.JOSEException;
import com.nimbusds.jwt.SignedJWT; import com.nimbusds.jwt.SignedJWT;
import eu.europa.ec.simpl.common.ephemeralproof.EphemeralProofAbstractParser;
import eu.europa.ec.simpl.common.exceptions.EphemeralProofNotFoundException; import eu.europa.ec.simpl.common.exceptions.EphemeralProofNotFoundException;
import eu.europa.ec.simpl.common.exceptions.InvalidEphemeralProofException; import eu.europa.ec.simpl.common.exceptions.InvalidEphemeralProofException;
import eu.europa.ec.simpl.common.exceptions.RuntimeWrapperException; import eu.europa.ec.simpl.common.exceptions.RuntimeWrapperException;
import eu.europa.ec.simpl.common.model.dto.CredentialDTO; import eu.europa.ec.simpl.common.model.dto.CredentialDTO;
import eu.europa.ec.simpl.common.model.ephemeralproof.EphemeralProofAbstractParser; import eu.europa.ec.simpl.common.redis.entity.EphemeralProof;
import eu.europa.ec.simpl.common.redis.model.entity.EphemeralProof;
import eu.europa.ec.simpl.common.utils.Sha384Converter; import eu.europa.ec.simpl.common.utils.Sha384Converter;
import eu.europa.ec.simpl.tlsgateway.configurations.AuthorityKeypairProperties;
import eu.europa.ec.simpl.tlsgateway.configurations.GlobalFilterProperties;
import eu.europa.ec.simpl.tlsgateway.configurations.security.RouteConfig; import eu.europa.ec.simpl.tlsgateway.configurations.security.RouteConfig;
import eu.europa.ec.simpl.tlsgateway.configurations.security.Rule; import eu.europa.ec.simpl.tlsgateway.configurations.security.Rule;
import eu.europa.ec.simpl.tlsgateway.repositories.EphemeralProofRepository; import eu.europa.ec.simpl.tlsgateway.repositories.EphemeralProofRepository;
...@@ -28,8 +30,6 @@ import lombok.extern.log4j.Log4j2; ...@@ -28,8 +30,6 @@ import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
...@@ -38,7 +38,7 @@ import reactor.core.publisher.Mono; ...@@ -38,7 +38,7 @@ import reactor.core.publisher.Mono;
@Log4j2 @Log4j2
@Component @Component
public class EphemeralProofFilter implements GlobalFilter, Ordered { public class EphemeralProofFilter extends OrderedGlobalFilter {
protected static final String MANAGE_EPHEMERAL_PROOF = "MANAGE_EPHEMERAL_PROOF"; protected static final String MANAGE_EPHEMERAL_PROOF = "MANAGE_EPHEMERAL_PROOF";
protected static final String VALID_EPHEMERAL_PROOF = "VALID_EPHEMERAL_PROOF"; protected static final String VALID_EPHEMERAL_PROOF = "VALID_EPHEMERAL_PROOF";
...@@ -48,17 +48,22 @@ public class EphemeralProofFilter implements GlobalFilter, Ordered { ...@@ -48,17 +48,22 @@ public class EphemeralProofFilter implements GlobalFilter, Ordered {
private final Function<String, JwtEphemeralProofVerifier> ephemeralProofValidatorFactory; private final Function<String, JwtEphemeralProofVerifier> ephemeralProofValidatorFactory;
private final EphemeralProofRepository ephemeralProofRepository; private final EphemeralProofRepository ephemeralProofRepository;
private final CredentialDTO authorityKey; private final CredentialDTO authorityKey;
private final AuthorityKeypairProperties authorityKeypairProperties;
public EphemeralProofFilter( public EphemeralProofFilter(
RouteConfig routeConfig, RouteConfig routeConfig,
EphemeralProofRepository ephemeralProofRepository, EphemeralProofRepository ephemeralProofRepository,
@Autowired(required = false) Function<String, JwtEphemeralProofVerifier> ephemeralProofVerifierFactory, @Autowired(required = false) Function<String, JwtEphemeralProofVerifier> ephemeralProofVerifierFactory,
@Qualifier("authorityPublicKey") CredentialDTO authorityKey) { @Qualifier("authorityPublicKey") CredentialDTO authorityKey,
GlobalFilterProperties globalFilterProperties,
AuthorityKeypairProperties authorityKeypairProperties) {
super(globalFilterProperties);
this.routeConfig = routeConfig; this.routeConfig = routeConfig;
this.ephemeralProofRepository = ephemeralProofRepository; this.ephemeralProofRepository = ephemeralProofRepository;
this.ephemeralProofValidatorFactory = this.ephemeralProofValidatorFactory =
Objects.requireNonNullElse(ephemeralProofVerifierFactory, JwtEphemeralProofVerifier::new); Objects.requireNonNullElse(ephemeralProofVerifierFactory, JwtEphemeralProofVerifier::new);
this.authorityKey = authorityKey; this.authorityKey = authorityKey;
this.authorityKeypairProperties = authorityKeypairProperties;
} }
@Override @Override
...@@ -151,14 +156,10 @@ public class EphemeralProofFilter implements GlobalFilter, Ordered { ...@@ -151,14 +156,10 @@ public class EphemeralProofFilter implements GlobalFilter, Ordered {
var publicKey = Base64.getDecoder().decode(authorityKey.getPublicKey()); var publicKey = Base64.getDecoder().decode(authorityKey.getPublicKey());
try { try {
return (ECPublicKey) KeyFactory.getInstance("EC").generatePublic(new X509EncodedKeySpec(publicKey)); return (ECPublicKey) KeyFactory.getInstance(authorityKeypairProperties.algorithm())
.generatePublic(new X509EncodedKeySpec(publicKey));
} catch (InvalidKeySpecException | NoSuchAlgorithmException e) { } catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
throw new RuntimeWrapperException(e); throw new RuntimeWrapperException(e);
} }
} }
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
} }
...@@ -4,9 +4,10 @@ import static eu.europa.ec.simpl.tlsgateway.filters.EphemeralProofFilter.EPHEMER ...@@ -4,9 +4,10 @@ import static eu.europa.ec.simpl.tlsgateway.filters.EphemeralProofFilter.EPHEMER
import static eu.europa.ec.simpl.tlsgateway.filters.EphemeralProofFilter.MANAGE_EPHEMERAL_PROOF; import static eu.europa.ec.simpl.tlsgateway.filters.EphemeralProofFilter.MANAGE_EPHEMERAL_PROOF;
import com.nimbusds.jwt.SignedJWT; import com.nimbusds.jwt.SignedJWT;
import eu.europa.ec.simpl.common.model.constants.SimplHeaders; import eu.europa.ec.simpl.common.constants.SimplHeaders;
import eu.europa.ec.simpl.common.model.dto.IdentityAttributeDTO; import eu.europa.ec.simpl.common.model.dto.IdentityAttributeDTO;
import eu.europa.ec.simpl.common.utils.JwtUtil; import eu.europa.ec.simpl.common.utils.JwtUtil;
import eu.europa.ec.simpl.tlsgateway.configurations.GlobalFilterProperties;
import eu.europa.ec.simpl.tlsgateway.services.TierOneSessionValidator; import eu.europa.ec.simpl.tlsgateway.services.TierOneSessionValidator;
import eu.europa.ec.simpl.tlsgateway.utils.ExchangeUtil; import eu.europa.ec.simpl.tlsgateway.utils.ExchangeUtil;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -19,19 +20,19 @@ import java.util.stream.Stream; ...@@ -19,19 +20,19 @@ import java.util.stream.Stream;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
@Log4j2 @Log4j2
@Component @Component
public class HeadersFilter implements GlobalFilter, Ordered { public class HeadersFilter extends OrderedGlobalFilter {
private final TierOneSessionValidator tierOneSessionValidator; private final TierOneSessionValidator tierOneSessionValidator;
public HeadersFilter(TierOneSessionValidator tierOneSessionValidator) { public HeadersFilter(
TierOneSessionValidator tierOneSessionValidator, GlobalFilterProperties globalFilterProperties) {
super(globalFilterProperties);
this.tierOneSessionValidator = tierOneSessionValidator; this.tierOneSessionValidator = tierOneSessionValidator;
} }
...@@ -126,9 +127,4 @@ public class HeadersFilter implements GlobalFilter, Ordered { ...@@ -126,9 +127,4 @@ public class HeadersFilter implements GlobalFilter, Ordered {
.filter(Predicate.not(IdentityAttributeDTO::isAssignableToRoles)) .filter(Predicate.not(IdentityAttributeDTO::isAssignableToRoles))
.map(IdentityAttributeDTO::getCode); .map(IdentityAttributeDTO::getCode);
} }
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE + 2;
}
} }
...@@ -5,6 +5,7 @@ import static eu.simpl.MessageBuilder.buildMessage; ...@@ -5,6 +5,7 @@ import static eu.simpl.MessageBuilder.buildMessage;
import eu.europa.ec.simpl.common.model.dto.CredentialDTO; import eu.europa.ec.simpl.common.model.dto.CredentialDTO;
import eu.europa.ec.simpl.common.utils.JwtUtil; import eu.europa.ec.simpl.common.utils.JwtUtil;
import eu.europa.ec.simpl.common.utils.Sha384Converter; import eu.europa.ec.simpl.common.utils.Sha384Converter;
import eu.europa.ec.simpl.tlsgateway.configurations.GlobalFilterProperties;
import eu.europa.ec.simpl.tlsgateway.configurations.LoggingRule; import eu.europa.ec.simpl.tlsgateway.configurations.LoggingRule;
import eu.europa.ec.simpl.tlsgateway.configurations.security.RouteConfig; import eu.europa.ec.simpl.tlsgateway.configurations.security.RouteConfig;
import eu.europa.ec.simpl.tlsgateway.utils.ExchangeUtil; import eu.europa.ec.simpl.tlsgateway.utils.ExchangeUtil;
...@@ -17,8 +18,6 @@ import org.apache.logging.log4j.Level; ...@@ -17,8 +18,6 @@ import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.lookup.StrSubstitutor; import org.apache.logging.log4j.core.lookup.StrSubstitutor;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
...@@ -27,12 +26,16 @@ import reactor.core.publisher.Mono; ...@@ -27,12 +26,16 @@ import reactor.core.publisher.Mono;
@Log4j2 @Log4j2
@Component @Component
public class LoggingFilter implements GlobalFilter, Ordered { public class LoggingFilter extends OrderedGlobalFilter {
private final CredentialDTO myPublicKey; private final CredentialDTO myPublicKey;
private final List<LoggingRule> loggingRules; private final List<LoggingRule> loggingRules;
public LoggingFilter(@Qualifier("myPublicKey") CredentialDTO myPublicKey, RouteConfig routeConfig) { public LoggingFilter(
@Qualifier("myPublicKey") CredentialDTO myPublicKey,
RouteConfig routeConfig,
GlobalFilterProperties globalFilterProperties) {
super(globalFilterProperties);
this.myPublicKey = myPublicKey; this.myPublicKey = myPublicKey;
this.loggingRules = Optional.ofNullable(routeConfig) this.loggingRules = Optional.ofNullable(routeConfig)
.map(RouteConfig::logging) .map(RouteConfig::logging)
...@@ -54,7 +57,12 @@ public class LoggingFilter implements GlobalFilter, Ordered { ...@@ -54,7 +57,12 @@ public class LoggingFilter implements GlobalFilter, Ordered {
return loggingRule -> new BusinessLogger(loggingRule.config(), exchange, chain); return loggingRule -> new BusinessLogger(loggingRule.config(), exchange, chain);
} }
private class BusinessLogger { protected BusinessLogger newBusinessLogger(
LoggingRule.Config config, ServerWebExchange exchange, GatewayFilterChain chain) {
return new BusinessLogger(config, exchange, chain);
}
protected class BusinessLogger {
private final LoggingRule.Config config; private final LoggingRule.Config config;
private final ServerWebExchange exchange; private final ServerWebExchange exchange;
...@@ -139,9 +147,4 @@ public class LoggingFilter implements GlobalFilter, Ordered { ...@@ -139,9 +147,4 @@ public class LoggingFilter implements GlobalFilter, Ordered {
} }
} }
} }
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE + 4;
}
} }
...@@ -2,29 +2,29 @@ package eu.europa.ec.simpl.tlsgateway.filters; ...@@ -2,29 +2,29 @@ package eu.europa.ec.simpl.tlsgateway.filters;
import eu.europa.ec.simpl.client.util.CertificateRevocation; import eu.europa.ec.simpl.client.util.CertificateRevocation;
import eu.europa.ec.simpl.client.util.DaggerCertificateRevocationFactory; import eu.europa.ec.simpl.client.util.DaggerCertificateRevocationFactory;
import eu.europa.ec.simpl.tlsgateway.configurations.GlobalFilterProperties;
import eu.europa.ec.simpl.tlsgateway.exceptions.InvalidCertificateException; import eu.europa.ec.simpl.tlsgateway.exceptions.InvalidCertificateException;
import eu.europa.ec.simpl.tlsgateway.utils.ExchangeUtil; import eu.europa.ec.simpl.tlsgateway.utils.ExchangeUtil;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.util.Objects; import java.util.Objects;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.slf4j.Logger; import lombok.extern.log4j.Log4j2;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
@Log4j2
@Component @Component
public class OcspFilter implements GlobalFilter, Ordered { public class OcspFilter extends OrderedGlobalFilter {
private static final Logger log = LoggerFactory.getLogger(OcspFilter.class);
private final Supplier<CertificateRevocation> certificateRevocationFactory; private final Supplier<CertificateRevocation> certificateRevocationFactory;
public OcspFilter(@Autowired(required = false) Supplier<CertificateRevocation> certificateRevocationFactory) { public OcspFilter(
@Autowired(required = false) Supplier<CertificateRevocation> certificateRevocationFactory,
GlobalFilterProperties globalFilterProperties) {
super(globalFilterProperties);
this.certificateRevocationFactory = Objects.requireNonNullElse( this.certificateRevocationFactory = Objects.requireNonNullElse(
certificateRevocationFactory, certificateRevocationFactory,
() -> DaggerCertificateRevocationFactory.create().get()); () -> DaggerCertificateRevocationFactory.create().get());
...@@ -48,9 +48,4 @@ public class OcspFilter implements GlobalFilter, Ordered { ...@@ -48,9 +48,4 @@ public class OcspFilter implements GlobalFilter, Ordered {
private boolean shouldSkip(ServerWebExchange exchange) { private boolean shouldSkip(ServerWebExchange exchange) {
return Objects.equals(Boolean.TRUE, exchange.getAttribute(EphemeralProofFilter.VALID_EPHEMERAL_PROOF)); return Objects.equals(Boolean.TRUE, exchange.getAttribute(EphemeralProofFilter.VALID_EPHEMERAL_PROOF));
} }
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE + 1;
}
} }