wip - configuring resource server

This commit is contained in:
Dario Ghunney Ware 2025-08-14 18:59:16 +01:00 committed by DarioGii
parent 0b224c8547
commit 41dfb1c4f6
18 changed files with 211 additions and 232 deletions

2
.gitignore vendored
View File

@ -18,6 +18,7 @@ version.properties
#### Stirling-PDF Files ### #### Stirling-PDF Files ###
pipeline/watchedFolders/ pipeline/watchedFolders/
pipeline/defaultWebUIConfigs/
pipeline/finishedFolders/ pipeline/finishedFolders/
customFiles/ customFiles/
configs/ configs/
@ -200,3 +201,4 @@ id_ed25519.pub
# node_modules # node_modules
node_modules/ node_modules/
app/core/src/main/resources/application-saas.yml

View File

@ -372,7 +372,7 @@ public class ApplicationProperties {
public String getBaseTmpDir() { public String getBaseTmpDir() {
return baseTmpDir != null && !baseTmpDir.isEmpty() return baseTmpDir != null && !baseTmpDir.isEmpty()
? baseTmpDir ? baseTmpDir
: java.lang.System.getProperty("java.io.tmpdir") + "/stirling-pdf"; : java.lang.System.getProperty("java.io.tmpdir") + "stirling-pdf";
} }
@JsonIgnore @JsonIgnore

View File

@ -1,72 +0,0 @@
spring:
main.allow-bean-definition-overriding: true
web.resources.mime-mappings.webmanifest: application/manifest+json
mvc.async.request-timeout: ${SYSTEM_CONNECTIONTIMEOUTMILLISECONDS:1200000}
thymeleaf.encoding: UTF-8
jpa.open-in-view: false
servlet.multipart:
max-file-size: 2000MB
max-request-size: 2000MB
devtools:
restart:
enabled: true
exclude: stirling.software.proprietary.security/**
livereload.enabled: true
datasource:
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://db.nrlkjfznsavsbmweiyqu.supabase.co:5432/postgres?sslmode=require
username: postgres
password: ${SAAS_DB_PASSWORD}
jpa:
hibernate.ddl-auto: update
database-platform: org.hibernate.dialect.PostgreSQLDialect
security:
oauth2:
res
multipart.enabled: true
logging.level:
org:
springframework: WARN
hibernate: WARN
jetty: WARN
# springframework.security.saml2: TRACE
# springframework.security: DEBUG
# opensaml: DEBUG
# stirling.software.SPDF.config.security: DEBUG
com.zaxxer.hikari: WARN
server:
forward-headers-strategy: NATIVE
error:
path: /error
whitelabel.enabled: false
include-stacktrace: always
include-exception: true
include-message: always
servlet:
session:
timeout: 30m
tracking-modes: cookie
context-path: ${SYSTEM_ROOTURIPATH:/}
# Change the default URL path for OpenAPI JSON
springdoc:
api-docs.path: /v1/api-docs
swagger-ui:
url: /v1/api-docs
path: /index.html
posthog:
api:
key: ${POSTHOG_API_KEY:phc_fiR65u5j6qmXTYL56MNrLZSWqLaDW74OrZH0Insd2xq}
host: ${POSTHOG_HOST:https://eu.i.posthog.com}
supabase:
id: ${SUPABASE_PROJECT_ID:nrlkjfznsavsbmweiyqu}
publishable-key: ${SUPABASE_PUBLISHABLE_KEY:rp7EBq9Dk-ZPCSe7EMWD7JZ6rMulReSUmJ4WIHowMl1AlCC6m1xA3UsBctHRbFkttik9pReYltrWzt7Ft1aap36_S2tKRzEN9qngJM1D7yd2s0Ok0kLeC54DxBvuqQVKe4dk6g_XC7ElV8w6JUQBN9xMLbnMQG49qvq2syugk-Ujj1M9VGsNr85HdgAFymODW3vI4w1hrz4rCDOU_uuDDGHoEvChnFVZ_tmO80IUKUCiWIIzkBn8k8mnmbnC0vCRMV-YT1J7DS-pznuqcEZhotJ3DnD3TwNJevVklo7QfZGL6hyIK-t5DNMBc3uujS1bZ9bLA3RMqXWgD9ZTmjcutw}
jwks:
url: https://nrlkjfznsavsbmweiyqu.supabase.co/auth/v1/.well-known/jwks.json
# Set up a consistent temporary directory location
java.io.tmpdir: ${stirling.tempfiles.directory:${java.io.tmpdir}/stirling-pdf}

View File

@ -40,8 +40,11 @@ dependencies {
api 'org.springframework:spring-jdbc' api 'org.springframework:spring-jdbc'
api 'org.springframework:spring-webmvc' api 'org.springframework:spring-webmvc'
api 'org.springframework.session:spring-session-core' api 'org.springframework.session:spring-session-core'
api "org.springframework.security:spring-security-core:$springSecuritySamlVersion" api "org.springframework.security:spring-security-core:$springSecurityVersion"
api "org.springframework.security:spring-security-saml2-service-provider:$springSecuritySamlVersion" api "org.springframework.security:spring-security-saml2-service-provider:$springSecurityVersion"
api "org.springframework.security:spring-security-oauth2-resource-server:$springSecurityVersion"
api "org.springframework.security:spring-security-oauth2-jose:$springSecurityVersion"
api 'org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.6.8'
api 'org.springframework.boot:spring-boot-starter-jetty' api 'org.springframework.boot:spring-boot-starter-jetty'
api 'org.springframework.boot:spring-boot-starter-security' api 'org.springframework.boot:spring-boot-starter-security'
api 'org.springframework.boot:spring-boot-starter-data-jpa' api 'org.springframework.boot:spring-boot-starter-data-jpa'

View File

@ -0,0 +1,38 @@
package stirling.software.proprietary.controller;
import java.time.Instant;
import java.util.List;
import java.util.Map;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MeController {
@GetMapping("/me")
public Map<String, Object> me(@AuthenticationPrincipal Jwt jwt, Authentication authentication) {
List<String> authorities =
authentication.getAuthorities().stream()
.map(GrantedAuthority::getAuthority)
.toList();
return Map.of(
"subject", jwt.getSubject(),
"issuer", jwt.getIssuer() != null ? jwt.getIssuer().toString() : null,
"audience", jwt.getAudience(),
"issuedAt", toEpoch(jwt.getIssuedAt()),
"expiresAt", toEpoch(jwt.getExpiresAt()),
"authorities", authorities,
"claims", jwt.getClaims() // full map of claims from the token
);
}
private Long toEpoch(Instant i) {
return i == null ? null : i.getEpochSecond();
}
}

View File

@ -1,8 +1,8 @@
package stirling.software.proprietary.security; package stirling.software.proprietary.security;
import java.io.IOException; import java.io.IOException;
import java.util.Map;
import java.util.Map;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.savedrequest.SavedRequest; import org.springframework.security.web.savedrequest.SavedRequest;
@ -53,12 +53,13 @@ public class CustomAuthenticationSuccessHandler
} }
loginAttemptService.loginSucceeded(userName); loginAttemptService.loginSucceeded(userName);
if (jwtService.isJwtEnabled()) { if (true) {
String jwt = String jwt =
jwtService.generateToken( jwtService.generateToken(
authentication, Map.of("authType", AuthenticationType.WEB)); authentication, Map.of("authType",
jwtService.addToken(response, jwt); AuthenticationType.WEB));
log.debug("JWT generated for user: {}", userName); jwtService.addToken(response, jwt);
log.debug("JWT generated for user: {}", userName);
getRedirectStrategy().sendRedirect(request, response, "/"); getRedirectStrategy().sendRedirect(request, response, "/");
} else { } else {

View File

@ -7,9 +7,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProp
import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.jdbc.DatabaseDriver; import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import lombok.Getter; import lombok.Getter;
@ -58,18 +56,18 @@ public class DatabaseConfig {
* @return a <code>DataSource</code> using the configuration settings in the settings.yml * @return a <code>DataSource</code> using the configuration settings in the settings.yml
* @throws UnsupportedProviderException if the type of database selected is not supported * @throws UnsupportedProviderException if the type of database selected is not supported
*/ */
@Bean // @Bean
@Qualifier("dataSource") // @Qualifier("dataSource")
@Primary // @Primary
public DataSource dataSource() throws UnsupportedProviderException { // public DataSource dataSource() throws UnsupportedProviderException {
DataSourceBuilder<?> dataSourceBuilder = DataSourceBuilder.create(); // DataSourceBuilder<?> dataSourceBuilder = DataSourceBuilder.create();
//
if (!runningProOrHigher || !datasource.isEnableCustomDatabase()) { // if (!runningProOrHigher || !datasource.isEnableCustomDatabase()) {
return useDefaultDataSource(dataSourceBuilder); // return useDefaultDataSource(dataSourceBuilder);
} // }
//
return useCustomDataSource(dataSourceBuilder); // return useCustomDataSource(dataSourceBuilder);
} // }
private DataSource useDefaultDataSource(DataSourceBuilder<?> dataSourceBuilder) { private DataSource useDefaultDataSource(DataSourceBuilder<?> dataSourceBuilder) {
log.info("Using default H2 database"); log.info("Using default H2 database");

View File

@ -18,6 +18,7 @@ import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.server.resource.web.authentication.BearerTokenAuthenticationFilter;
import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider; import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider;
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
import org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver; import org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver;
@ -132,20 +133,24 @@ public class SecurityConfiguration {
if (loginEnabledValue) { if (loginEnabledValue) {
boolean v2Enabled = appConfig.v2Enabled(); boolean v2Enabled = appConfig.v2Enabled();
if (v2Enabled) {
http.addFilterBefore(
jwtAuthenticationFilter(),
UsernamePasswordAuthenticationFilter.class)
.exceptionHandling(
exceptionHandling ->
exceptionHandling.authenticationEntryPoint(
jwtAuthenticationEntryPoint));
}
http.addFilterBefore( http.addFilterBefore(
userAuthenticationFilter, UsernamePasswordAuthenticationFilter.class) userAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
.addFilterAfter(rateLimitingFilter(), UserAuthenticationFilter.class) .addFilterAfter(rateLimitingFilter(), UserAuthenticationFilter.class)
.addFilterAfter(firstLoginFilter, UsernamePasswordAuthenticationFilter.class); .addFilterAfter(firstLoginFilter, UsernamePasswordAuthenticationFilter.class);
// if (v2Enabled) {
http.oauth2ResourceServer(
oauth2 ->
oauth2.jwt(
jwtConfigurer ->
jwtConfigurer.jwkSetUri(
"https://nrlkjfznsavsbmweiyqu.supabase.co/auth/v1/.well-known/jwks.json")));
http.addFilterBefore(jwtAuthenticationFilter(), BearerTokenAuthenticationFilter.class)
.exceptionHandling(
exceptionHandling ->
exceptionHandling.authenticationEntryPoint(
jwtAuthenticationEntryPoint));
// }
if (!securityProperties.getCsrfDisabled()) { if (!securityProperties.getCsrfDisabled()) {
CookieCsrfTokenRepository cookieRepo = CookieCsrfTokenRepository cookieRepo =
CookieCsrfTokenRepository.withHttpOnlyFalse(); CookieCsrfTokenRepository.withHttpOnlyFalse();

View File

@ -111,7 +111,9 @@ public class UserAuthenticationFilter extends OncePerRequestFilter {
String contextPath = request.getContextPath(); String contextPath = request.getContextPath();
if ("GET".equalsIgnoreCase(method) && !requestURI.startsWith(contextPath + "/login")) { if ("GET".equalsIgnoreCase(method) && !requestURI.startsWith(contextPath + "/login")) {
response.sendRedirect(contextPath + "/login"); // redirect to the login page // response.sendRedirect(contextPath + "/login"); // redirect to the
// login page
filterChain.doFilter(request, response);
} else { } else {
response.setStatus(HttpStatus.UNAUTHORIZED.value()); response.setStatus(HttpStatus.UNAUTHORIZED.value());
response.getWriter() response.getWriter()

View File

@ -4,6 +4,9 @@ import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
@ -15,19 +18,27 @@ import lombok.ToString;
@NoArgsConstructor @NoArgsConstructor
@ToString(onlyExplicitlyIncluded = true) @ToString(onlyExplicitlyIncluded = true)
@EqualsAndHashCode(onlyExplicitlyIncluded = true) @EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class JwtVerificationKey implements Serializable { @JsonIgnoreProperties(ignoreUnknown = true)
public class JwtSigningKey implements Serializable {
@Serial private static final long serialVersionUID = 1L; @Serial private static final long serialVersionUID = 1L;
@ToString.Include private String keyId; @JsonAlias("kid")
@ToString.Include
private String keyId;
private String verifyingKey; @JsonAlias("n")
private String key;
@JsonAlias("alg")
private String algorithm;
@ToString.Include private LocalDateTime createdAt; @ToString.Include private LocalDateTime createdAt;
public JwtVerificationKey(String keyId, String verifyingKey) { public JwtSigningKey(String keyId, String key) {
this.keyId = keyId; this.keyId = keyId;
this.verifyingKey = verifyingKey; this.key = key;
this.algorithm = "RS256";
this.createdAt = LocalDateTime.now(); this.createdAt = LocalDateTime.now();
} }
} }

View File

@ -35,7 +35,7 @@ import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import stirling.software.proprietary.security.model.JwtVerificationKey; import stirling.software.proprietary.security.model.JwtSigningKey;
import stirling.software.proprietary.security.model.exception.AuthenticationFailureException; import stirling.software.proprietary.security.model.exception.AuthenticationFailureException;
import stirling.software.proprietary.security.saml2.CustomSaml2AuthenticatedPrincipal; import stirling.software.proprietary.security.saml2.CustomSaml2AuthenticatedPrincipal;
@ -80,7 +80,7 @@ public class JwtService implements JwtServiceInterface {
@Override @Override
public String generateToken(String username, Map<String, Object> claims) { public String generateToken(String username, Map<String, Object> claims) {
try { try {
JwtVerificationKey activeKey = keyPersistenceService.getActiveKey(); JwtSigningKey activeKey = keyPersistenceService.getActiveKey();
Optional<KeyPair> keyPairOpt = keyPersistenceService.getKeyPair(activeKey.getKeyId()); Optional<KeyPair> keyPairOpt = keyPersistenceService.getKeyPair(activeKey.getKeyId());
if (keyPairOpt.isEmpty()) { if (keyPairOpt.isEmpty()) {
@ -159,7 +159,7 @@ public class JwtService implements JwtServiceInterface {
keyId); keyId);
if (keyId.equals(keyPersistenceService.getActiveKey().getKeyId())) { if (keyId.equals(keyPersistenceService.getActiveKey().getKeyId())) {
JwtVerificationKey verificationKey = JwtSigningKey verificationKey =
keyPersistenceService.refreshActiveKeyPair(); keyPersistenceService.refreshActiveKeyPair();
Optional<KeyPair> refreshedKeyPair = Optional<KeyPair> refreshedKeyPair =
keyPersistenceService.getKeyPair(verificationKey.getKeyId()); keyPersistenceService.getKeyPair(verificationKey.getKeyId());
@ -171,7 +171,7 @@ public class JwtService implements JwtServiceInterface {
} }
} else { } else {
// Try to use active key as fallback // Try to use active key as fallback
JwtVerificationKey activeKey = keyPersistenceService.getActiveKey(); JwtSigningKey activeKey = keyPersistenceService.getActiveKey();
Optional<KeyPair> activeKeyPair = Optional<KeyPair> activeKeyPair =
keyPersistenceService.getKeyPair(activeKey.getKeyId()); keyPersistenceService.getKeyPair(activeKey.getKeyId());
if (activeKeyPair.isPresent()) { if (activeKeyPair.isPresent()) {
@ -214,9 +214,8 @@ public class JwtService implements JwtServiceInterface {
private Claims tryAllKeys(String token) throws AuthenticationFailureException { private Claims tryAllKeys(String token) throws AuthenticationFailureException {
// First try the active key // First try the active key
try { try {
JwtVerificationKey activeKey = keyPersistenceService.getActiveKey(); JwtSigningKey activeKey = keyPersistenceService.getActiveKey();
PublicKey publicKey = PublicKey publicKey = keyPersistenceService.decodePublicKey(activeKey.getKey());
keyPersistenceService.decodePublicKey(activeKey.getVerifyingKey());
return Jwts.parser() return Jwts.parser()
.verifyWith(publicKey) .verifyWith(publicKey)
.build() .build()
@ -228,15 +227,14 @@ public class JwtService implements JwtServiceInterface {
log.debug("Active key failed, trying all available keys from cache"); log.debug("Active key failed, trying all available keys from cache");
// If active key fails, try all available keys from cache // If active key fails, try all available keys from cache
List<JwtVerificationKey> allKeys = List<JwtSigningKey> allKeys =
keyPersistenceService.getKeysEligibleForCleanup( keyPersistenceService.getKeysEligibleForCleanup(
LocalDateTime.now().plusDays(1)); LocalDateTime.now().plusDays(1));
for (JwtVerificationKey verificationKey : allKeys) { for (JwtSigningKey verificationKey : allKeys) {
try { try {
PublicKey publicKey = PublicKey publicKey =
keyPersistenceService.decodePublicKey( keyPersistenceService.decodePublicKey(verificationKey.getKey());
verificationKey.getVerifyingKey());
return Jwts.parser() return Jwts.parser()
.verifyWith(publicKey) .verifyWith(publicKey)
.build() .build()
@ -310,7 +308,7 @@ public class JwtService implements JwtServiceInterface {
try { try {
PublicKey signingKey = PublicKey signingKey =
keyPersistenceService.decodePublicKey( keyPersistenceService.decodePublicKey(
keyPersistenceService.getActiveKey().getVerifyingKey()); keyPersistenceService.getActiveKey().getKey());
String keyId = String keyId =
(String) (String)

View File

@ -20,7 +20,7 @@ import lombok.extern.slf4j.Slf4j;
import stirling.software.common.configuration.InstallationPathConfig; import stirling.software.common.configuration.InstallationPathConfig;
import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.ApplicationProperties;
import stirling.software.proprietary.security.model.JwtVerificationKey; import stirling.software.proprietary.security.model.JwtSigningKey;
@Slf4j @Slf4j
@Service @Service
@ -49,7 +49,7 @@ public class KeyPairCleanupService {
LocalDateTime cutoffDate = LocalDateTime cutoffDate =
LocalDateTime.now().minusDays(jwtProperties.getKeyRetentionDays()); LocalDateTime.now().minusDays(jwtProperties.getKeyRetentionDays());
List<JwtVerificationKey> eligibleKeys = List<JwtSigningKey> eligibleKeys =
keyPersistenceService.getKeysEligibleForCleanup(cutoffDate); keyPersistenceService.getKeysEligibleForCleanup(cutoffDate);
if (eligibleKeys.isEmpty()) { if (eligibleKeys.isEmpty()) {
return; return;
@ -60,7 +60,7 @@ public class KeyPairCleanupService {
keyPersistenceService.refreshActiveKeyPair(); keyPersistenceService.refreshActiveKeyPair();
} }
private void removeKeys(List<JwtVerificationKey> keys) { private void removeKeys(List<JwtSigningKey> keys) {
keys.forEach( keys.forEach(
key -> { key -> {
try { try {

View File

@ -34,7 +34,7 @@ import lombok.extern.slf4j.Slf4j;
import stirling.software.common.configuration.InstallationPathConfig; import stirling.software.common.configuration.InstallationPathConfig;
import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.ApplicationProperties;
import stirling.software.proprietary.security.model.JwtVerificationKey; import stirling.software.proprietary.security.model.JwtSigningKey;
@Slf4j @Slf4j
@Service @Service
@ -46,7 +46,7 @@ public class KeyPersistenceService implements KeyPersistenceServiceInterface {
private final CacheManager cacheManager; private final CacheManager cacheManager;
private final Cache verifyingKeyCache; private final Cache verifyingKeyCache;
private volatile JwtVerificationKey activeKey; private volatile JwtSigningKey activeKey;
@Autowired @Autowired
public KeyPersistenceService( public KeyPersistenceService(
@ -77,15 +77,15 @@ public class KeyPersistenceService implements KeyPersistenceServiceInterface {
} }
@Transactional @Transactional
private JwtVerificationKey generateAndStoreKeypair() { private JwtSigningKey generateAndStoreKeypair() {
JwtVerificationKey verifyingKey = null; JwtSigningKey verifyingKey = null;
try { try {
KeyPair keyPair = generateRSAKeypair(); KeyPair keyPair = generateRSAKeypair();
String keyId = generateKeyId(); String keyId = generateKeyId();
storePrivateKey(keyId, keyPair.getPrivate()); storePrivateKey(keyId, keyPair.getPrivate());
verifyingKey = new JwtVerificationKey(keyId, encodePublicKey(keyPair.getPublic())); verifyingKey = new JwtSigningKey(keyId, encodePublicKey(keyPair.getPublic()));
verifyingKeyCache.put(keyId, verifyingKey); verifyingKeyCache.put(keyId, verifyingKey);
activeKey = verifyingKey; activeKey = verifyingKey;
} catch (IOException e) { } catch (IOException e) {
@ -96,7 +96,7 @@ public class KeyPersistenceService implements KeyPersistenceServiceInterface {
} }
@Override @Override
public JwtVerificationKey getActiveKey() { public JwtSigningKey getActiveKey() {
if (activeKey == null) { if (activeKey == null) {
return generateAndStoreKeypair(); return generateAndStoreKeypair();
} }
@ -110,8 +110,7 @@ public class KeyPersistenceService implements KeyPersistenceServiceInterface {
} }
try { try {
JwtVerificationKey verifyingKey = JwtSigningKey verifyingKey = verifyingKeyCache.get(keyId, JwtSigningKey.class);
verifyingKeyCache.get(keyId, JwtVerificationKey.class);
if (verifyingKey == null) { if (verifyingKey == null) {
log.warn("No signing key found in database for keyId: {}", keyId); log.warn("No signing key found in database for keyId: {}", keyId);
@ -119,7 +118,7 @@ public class KeyPersistenceService implements KeyPersistenceServiceInterface {
} }
PrivateKey privateKey = loadPrivateKey(keyId); PrivateKey privateKey = loadPrivateKey(keyId);
PublicKey publicKey = decodePublicKey(verifyingKey.getVerifyingKey()); PublicKey publicKey = decodePublicKey(verifyingKey.getKey());
return Optional.of(new KeyPair(publicKey, privateKey)); return Optional.of(new KeyPair(publicKey, privateKey));
} catch (Exception e) { } catch (Exception e) {
@ -134,7 +133,7 @@ public class KeyPersistenceService implements KeyPersistenceServiceInterface {
} }
@Override @Override
public JwtVerificationKey refreshActiveKeyPair() { public JwtSigningKey refreshActiveKeyPair() {
return generateAndStoreKeypair(); return generateAndStoreKeypair();
} }
@ -148,7 +147,7 @@ public class KeyPersistenceService implements KeyPersistenceServiceInterface {
} }
@Override @Override
public List<JwtVerificationKey> getKeysEligibleForCleanup(LocalDateTime cutoffDate) { public List<JwtSigningKey> getKeysEligibleForCleanup(LocalDateTime cutoffDate) {
CaffeineCache caffeineCache = (CaffeineCache) verifyingKeyCache; CaffeineCache caffeineCache = (CaffeineCache) verifyingKeyCache;
com.github.benmanes.caffeine.cache.Cache<Object, Object> nativeCache = com.github.benmanes.caffeine.cache.Cache<Object, Object> nativeCache =
caffeineCache.getNativeCache(); caffeineCache.getNativeCache();
@ -159,8 +158,8 @@ public class KeyPersistenceService implements KeyPersistenceServiceInterface {
nativeCache.asMap().size()); nativeCache.asMap().size());
return nativeCache.asMap().values().stream() return nativeCache.asMap().values().stream()
.filter(value -> value instanceof JwtVerificationKey) .filter(value -> value instanceof JwtSigningKey)
.map(value -> (JwtVerificationKey) value) .map(value -> (JwtSigningKey) value)
.filter( .filter(
key -> { key -> {
boolean eligible = key.getCreatedAt().isBefore(cutoffDate); boolean eligible = key.getCreatedAt().isBefore(cutoffDate);

View File

@ -8,19 +8,19 @@ import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import stirling.software.proprietary.security.model.JwtVerificationKey; import stirling.software.proprietary.security.model.JwtSigningKey;
public interface KeyPersistenceServiceInterface { public interface KeyPersistenceServiceInterface {
JwtVerificationKey getActiveKey(); JwtSigningKey getActiveKey();
Optional<KeyPair> getKeyPair(String keyId); Optional<KeyPair> getKeyPair(String keyId);
boolean isKeystoreEnabled(); boolean isKeystoreEnabled();
JwtVerificationKey refreshActiveKeyPair(); JwtSigningKey refreshActiveKeyPair();
List<JwtVerificationKey> getKeysEligibleForCleanup(LocalDateTime cutoffDate); List<JwtSigningKey> getKeysEligibleForCleanup(LocalDateTime cutoffDate);
void removeKey(String keyId); void removeKey(String keyId);

View File

@ -1,20 +1,13 @@
package stirling.software.proprietary.security.configuration; package stirling.software.proprietary.security.configuration;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.when;
import javax.sql.DataSource;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoExtension;
import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.ApplicationProperties;
import stirling.software.common.model.exception.UnsupportedProviderException;
@ExtendWith(MockitoExtension.class) @ExtendWith(MockitoExtension.class)
class DatabaseConfigTest { class DatabaseConfigTest {
@ -28,59 +21,60 @@ class DatabaseConfigTest {
databaseConfig = new DatabaseConfig(datasource, true); databaseConfig = new DatabaseConfig(datasource, true);
} }
@Test // @Test
void testDataSource_whenRunningEEIsFalse() throws UnsupportedProviderException { // void testDataSource_whenRunningEEIsFalse() throws UnsupportedProviderException {
databaseConfig = new DatabaseConfig(datasource, false); // databaseConfig = new DatabaseConfig(datasource, false);
//
var result = databaseConfig.dataSource(); // var result = databaseConfig.dataSource();
//
assertInstanceOf(DataSource.class, result); // assertInstanceOf(DataSource.class, result);
} // }
//
@Test // @Test
void testDefaultConfigurationForDataSource() throws UnsupportedProviderException { // void testDefaultConfigurationForDataSource() throws UnsupportedProviderException {
when(datasource.isEnableCustomDatabase()).thenReturn(false); // when(datasource.isEnableCustomDatabase()).thenReturn(false);
//
var result = databaseConfig.dataSource(); // var result = databaseConfig.dataSource();
//
assertInstanceOf(DataSource.class, result); // assertInstanceOf(DataSource.class, result);
} // }
//
@Test // @Test
void testCustomUrlForDataSource() throws UnsupportedProviderException { // void testCustomUrlForDataSource() throws UnsupportedProviderException {
when(datasource.isEnableCustomDatabase()).thenReturn(true); // when(datasource.isEnableCustomDatabase()).thenReturn(true);
when(datasource.getCustomDatabaseUrl()).thenReturn("jdbc:postgresql://mockUrl"); // when(datasource.getCustomDatabaseUrl()).thenReturn("jdbc:postgresql://mockUrl");
when(datasource.getUsername()).thenReturn("test"); // when(datasource.getUsername()).thenReturn("test");
when(datasource.getPassword()).thenReturn("pass"); // when(datasource.getPassword()).thenReturn("pass");
//
var result = databaseConfig.dataSource(); // var result = databaseConfig.dataSource();
//
assertInstanceOf(DataSource.class, result); // assertInstanceOf(DataSource.class, result);
} // }
//
@Test // @Test
void testCustomConfigurationForDataSource() throws UnsupportedProviderException { // void testCustomConfigurationForDataSource() throws UnsupportedProviderException {
when(datasource.isEnableCustomDatabase()).thenReturn(true); // when(datasource.isEnableCustomDatabase()).thenReturn(true);
when(datasource.getCustomDatabaseUrl()).thenReturn(""); // when(datasource.getCustomDatabaseUrl()).thenReturn("");
when(datasource.getType()).thenReturn("postgresql"); // when(datasource.getType()).thenReturn("postgresql");
when(datasource.getHostName()).thenReturn("test"); // when(datasource.getHostName()).thenReturn("test");
when(datasource.getPort()).thenReturn(1234); // when(datasource.getPort()).thenReturn(1234);
when(datasource.getName()).thenReturn("test_db"); // when(datasource.getName()).thenReturn("test_db");
when(datasource.getUsername()).thenReturn("test"); // when(datasource.getUsername()).thenReturn("test");
when(datasource.getPassword()).thenReturn("pass"); // when(datasource.getPassword()).thenReturn("pass");
//
var result = databaseConfig.dataSource(); // var result = databaseConfig.dataSource();
//
assertInstanceOf(DataSource.class, result); // assertInstanceOf(DataSource.class, result);
} // }
//
@ParameterizedTest(name = "Exception thrown when the DB type [{arguments}] is not supported") // @ParameterizedTest(name = "Exception thrown when the DB type [{arguments}] is not
@ValueSource(strings = {"oracle", "mysql", "mongoDb"}) // supported")
void exceptionThrown_whenDBTypeIsUnsupported(String datasourceType) { // @ValueSource(strings = {"oracle", "mysql", "mongoDb"})
when(datasource.isEnableCustomDatabase()).thenReturn(true); // void exceptionThrown_whenDBTypeIsUnsupported(String datasourceType) {
when(datasource.getCustomDatabaseUrl()).thenReturn(""); // when(datasource.isEnableCustomDatabase()).thenReturn(true);
when(datasource.getType()).thenReturn(datasourceType); // when(datasource.getCustomDatabaseUrl()).thenReturn("");
// when(datasource.getType()).thenReturn(datasourceType);
assertThrows(UnsupportedProviderException.class, () -> databaseConfig.dataSource()); //
} // assertThrows(UnsupportedProviderException.class, () -> databaseConfig.dataSource());
// }
} }

View File

@ -37,7 +37,7 @@ import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import stirling.software.proprietary.security.model.JwtVerificationKey; import stirling.software.proprietary.security.model.JwtSigningKey;
import stirling.software.proprietary.security.model.User; import stirling.software.proprietary.security.model.User;
import stirling.software.proprietary.security.model.exception.AuthenticationFailureException; import stirling.software.proprietary.security.model.exception.AuthenticationFailureException;
@ -56,7 +56,7 @@ class JwtServiceTest {
private JwtService jwtService; private JwtService jwtService;
private KeyPair testKeyPair; private KeyPair testKeyPair;
private JwtVerificationKey testVerificationKey; private JwtSigningKey testVerificationKey;
@BeforeEach @BeforeEach
void setUp() throws NoSuchAlgorithmException { void setUp() throws NoSuchAlgorithmException {
@ -68,7 +68,7 @@ class JwtServiceTest {
// Create test verification key // Create test verification key
String encodedPublicKey = String encodedPublicKey =
Base64.getEncoder().encodeToString(testKeyPair.getPublic().getEncoded()); Base64.getEncoder().encodeToString(testKeyPair.getPublic().getEncoded());
testVerificationKey = new JwtVerificationKey("test-key-id", encodedPublicKey); testVerificationKey = new JwtSigningKey("test-key-id", encodedPublicKey);
jwtService = new JwtService(true, keystoreService); jwtService = new JwtService(true, keystoreService);
} }
@ -79,7 +79,7 @@ class JwtServiceTest {
when(keystoreService.getActiveKey()).thenReturn(testVerificationKey); when(keystoreService.getActiveKey()).thenReturn(testVerificationKey);
when(keystoreService.getKeyPair("test-key-id")).thenReturn(Optional.of(testKeyPair)); when(keystoreService.getKeyPair("test-key-id")).thenReturn(Optional.of(testKeyPair));
when(keystoreService.decodePublicKey(testVerificationKey.getVerifyingKey())) when(keystoreService.decodePublicKey(testVerificationKey.getKey()))
.thenReturn(testKeyPair.getPublic()); .thenReturn(testKeyPair.getPublic());
when(authentication.getPrincipal()).thenReturn(userDetails); when(authentication.getPrincipal()).thenReturn(userDetails);
when(userDetails.getUsername()).thenReturn(username); when(userDetails.getUsername()).thenReturn(username);
@ -100,7 +100,7 @@ class JwtServiceTest {
when(keystoreService.getActiveKey()).thenReturn(testVerificationKey); when(keystoreService.getActiveKey()).thenReturn(testVerificationKey);
when(keystoreService.getKeyPair("test-key-id")).thenReturn(Optional.of(testKeyPair)); when(keystoreService.getKeyPair("test-key-id")).thenReturn(Optional.of(testKeyPair));
when(keystoreService.decodePublicKey(testVerificationKey.getVerifyingKey())) when(keystoreService.decodePublicKey(testVerificationKey.getKey()))
.thenReturn(testKeyPair.getPublic()); .thenReturn(testKeyPair.getPublic());
when(authentication.getPrincipal()).thenReturn(userDetails); when(authentication.getPrincipal()).thenReturn(userDetails);
when(userDetails.getUsername()).thenReturn(username); when(userDetails.getUsername()).thenReturn(username);
@ -120,7 +120,7 @@ class JwtServiceTest {
void testValidateTokenSuccess() throws Exception { void testValidateTokenSuccess() throws Exception {
when(keystoreService.getActiveKey()).thenReturn(testVerificationKey); when(keystoreService.getActiveKey()).thenReturn(testVerificationKey);
when(keystoreService.getKeyPair("test-key-id")).thenReturn(Optional.of(testKeyPair)); when(keystoreService.getKeyPair("test-key-id")).thenReturn(Optional.of(testKeyPair));
when(keystoreService.decodePublicKey(testVerificationKey.getVerifyingKey())) when(keystoreService.decodePublicKey(testVerificationKey.getKey()))
.thenReturn(testKeyPair.getPublic()); .thenReturn(testKeyPair.getPublic());
when(authentication.getPrincipal()).thenReturn(userDetails); when(authentication.getPrincipal()).thenReturn(userDetails);
when(userDetails.getUsername()).thenReturn("testuser"); when(userDetails.getUsername()).thenReturn("testuser");
@ -133,7 +133,7 @@ class JwtServiceTest {
@Test @Test
void testValidateTokenWithInvalidToken() throws Exception { void testValidateTokenWithInvalidToken() throws Exception {
when(keystoreService.getActiveKey()).thenReturn(testVerificationKey); when(keystoreService.getActiveKey()).thenReturn(testVerificationKey);
when(keystoreService.decodePublicKey(testVerificationKey.getVerifyingKey())) when(keystoreService.decodePublicKey(testVerificationKey.getKey()))
.thenReturn(testKeyPair.getPublic()); .thenReturn(testKeyPair.getPublic());
assertThrows( assertThrows(
@ -146,7 +146,7 @@ class JwtServiceTest {
@Test @Test
void testValidateTokenWithMalformedToken() throws Exception { void testValidateTokenWithMalformedToken() throws Exception {
when(keystoreService.getActiveKey()).thenReturn(testVerificationKey); when(keystoreService.getActiveKey()).thenReturn(testVerificationKey);
when(keystoreService.decodePublicKey(testVerificationKey.getVerifyingKey())) when(keystoreService.decodePublicKey(testVerificationKey.getKey()))
.thenReturn(testKeyPair.getPublic()); .thenReturn(testKeyPair.getPublic());
AuthenticationFailureException exception = AuthenticationFailureException exception =
@ -162,7 +162,7 @@ class JwtServiceTest {
@Test @Test
void testValidateTokenWithEmptyToken() throws Exception { void testValidateTokenWithEmptyToken() throws Exception {
when(keystoreService.getActiveKey()).thenReturn(testVerificationKey); when(keystoreService.getActiveKey()).thenReturn(testVerificationKey);
when(keystoreService.decodePublicKey(testVerificationKey.getVerifyingKey())) when(keystoreService.decodePublicKey(testVerificationKey.getKey()))
.thenReturn(testKeyPair.getPublic()); .thenReturn(testKeyPair.getPublic());
AuthenticationFailureException exception = AuthenticationFailureException exception =
@ -185,7 +185,7 @@ class JwtServiceTest {
when(keystoreService.getActiveKey()).thenReturn(testVerificationKey); when(keystoreService.getActiveKey()).thenReturn(testVerificationKey);
when(keystoreService.getKeyPair("test-key-id")).thenReturn(Optional.of(testKeyPair)); when(keystoreService.getKeyPair("test-key-id")).thenReturn(Optional.of(testKeyPair));
when(keystoreService.decodePublicKey(testVerificationKey.getVerifyingKey())) when(keystoreService.decodePublicKey(testVerificationKey.getKey()))
.thenReturn(testKeyPair.getPublic()); .thenReturn(testKeyPair.getPublic());
when(authentication.getPrincipal()).thenReturn(user); when(authentication.getPrincipal()).thenReturn(user);
when(user.getUsername()).thenReturn(username); when(user.getUsername()).thenReturn(username);
@ -198,7 +198,7 @@ class JwtServiceTest {
@Test @Test
void testExtractUsernameWithInvalidToken() throws Exception { void testExtractUsernameWithInvalidToken() throws Exception {
when(keystoreService.getActiveKey()).thenReturn(testVerificationKey); when(keystoreService.getActiveKey()).thenReturn(testVerificationKey);
when(keystoreService.decodePublicKey(testVerificationKey.getVerifyingKey())) when(keystoreService.decodePublicKey(testVerificationKey.getKey()))
.thenReturn(testKeyPair.getPublic()); .thenReturn(testKeyPair.getPublic());
assertThrows( assertThrows(
@ -213,7 +213,7 @@ class JwtServiceTest {
when(keystoreService.getActiveKey()).thenReturn(testVerificationKey); when(keystoreService.getActiveKey()).thenReturn(testVerificationKey);
when(keystoreService.getKeyPair("test-key-id")).thenReturn(Optional.of(testKeyPair)); when(keystoreService.getKeyPair("test-key-id")).thenReturn(Optional.of(testKeyPair));
when(keystoreService.decodePublicKey(testVerificationKey.getVerifyingKey())) when(keystoreService.decodePublicKey(testVerificationKey.getKey()))
.thenReturn(testKeyPair.getPublic()); .thenReturn(testKeyPair.getPublic());
when(authentication.getPrincipal()).thenReturn(userDetails); when(authentication.getPrincipal()).thenReturn(userDetails);
when(userDetails.getUsername()).thenReturn(username); when(userDetails.getUsername()).thenReturn(username);
@ -230,7 +230,7 @@ class JwtServiceTest {
@Test @Test
void testExtractClaimsWithInvalidToken() throws Exception { void testExtractClaimsWithInvalidToken() throws Exception {
when(keystoreService.getActiveKey()).thenReturn(testVerificationKey); when(keystoreService.getActiveKey()).thenReturn(testVerificationKey);
when(keystoreService.decodePublicKey(testVerificationKey.getVerifyingKey())) when(keystoreService.decodePublicKey(testVerificationKey.getKey()))
.thenReturn(testKeyPair.getPublic()); .thenReturn(testKeyPair.getPublic());
assertThrows( assertThrows(
@ -321,7 +321,7 @@ class JwtServiceTest {
when(keystoreService.getActiveKey()).thenReturn(testVerificationKey); when(keystoreService.getActiveKey()).thenReturn(testVerificationKey);
when(keystoreService.getKeyPair("test-key-id")).thenReturn(Optional.of(testKeyPair)); when(keystoreService.getKeyPair("test-key-id")).thenReturn(Optional.of(testKeyPair));
when(keystoreService.decodePublicKey(testVerificationKey.getVerifyingKey())) when(keystoreService.decodePublicKey(testVerificationKey.getKey()))
.thenReturn(testKeyPair.getPublic()); .thenReturn(testKeyPair.getPublic());
when(authentication.getPrincipal()).thenReturn(userDetails); when(authentication.getPrincipal()).thenReturn(userDetails);
when(userDetails.getUsername()).thenReturn(username); when(userDetails.getUsername()).thenReturn(username);
@ -347,7 +347,7 @@ class JwtServiceTest {
// First, generate a token successfully // First, generate a token successfully
when(keystoreService.getActiveKey()).thenReturn(testVerificationKey); when(keystoreService.getActiveKey()).thenReturn(testVerificationKey);
when(keystoreService.getKeyPair("test-key-id")).thenReturn(Optional.of(testKeyPair)); when(keystoreService.getKeyPair("test-key-id")).thenReturn(Optional.of(testKeyPair));
when(keystoreService.decodePublicKey(testVerificationKey.getVerifyingKey())) when(keystoreService.decodePublicKey(testVerificationKey.getKey()))
.thenReturn(testKeyPair.getPublic()); .thenReturn(testKeyPair.getPublic());
when(authentication.getPrincipal()).thenReturn(userDetails); when(authentication.getPrincipal()).thenReturn(userDetails);
when(userDetails.getUsername()).thenReturn(username); when(userDetails.getUsername()).thenReturn(username);
@ -356,8 +356,8 @@ class JwtServiceTest {
// Now mock the scenario for validation - key not found, but fallback works // Now mock the scenario for validation - key not found, but fallback works
// Create a fallback key pair that can be used // Create a fallback key pair that can be used
JwtVerificationKey fallbackKey = JwtSigningKey fallbackKey =
new JwtVerificationKey( new JwtSigningKey(
"fallback-key", "fallback-key",
Base64.getEncoder().encodeToString(testKeyPair.getPublic().getEncoded())); Base64.getEncoder().encodeToString(testKeyPair.getPublic().getEncoded()));

View File

@ -31,7 +31,7 @@ import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import stirling.software.common.configuration.InstallationPathConfig; import stirling.software.common.configuration.InstallationPathConfig;
import stirling.software.common.model.ApplicationProperties; import stirling.software.common.model.ApplicationProperties;
import stirling.software.proprietary.security.model.JwtVerificationKey; import stirling.software.proprietary.security.model.JwtSigningKey;
@ExtendWith(MockitoExtension.class) @ExtendWith(MockitoExtension.class)
class KeyPersistenceServiceInterfaceTest { class KeyPersistenceServiceInterfaceTest {
@ -87,11 +87,11 @@ class KeyPersistenceServiceInterfaceTest {
keyPersistenceService = new KeyPersistenceService(applicationProperties, cacheManager); keyPersistenceService = new KeyPersistenceService(applicationProperties, cacheManager);
keyPersistenceService.initializeKeystore(); keyPersistenceService.initializeKeystore();
JwtVerificationKey result = keyPersistenceService.getActiveKey(); JwtSigningKey result = keyPersistenceService.getActiveKey();
assertNotNull(result); assertNotNull(result);
assertNotNull(result.getKeyId()); assertNotNull(result.getKeyId());
assertNotNull(result.getVerifyingKey()); assertNotNull(result.getKey());
} }
} }
@ -103,7 +103,7 @@ class KeyPersistenceServiceInterfaceTest {
String privateKeyBase64 = String privateKeyBase64 =
Base64.getEncoder().encodeToString(testKeyPair.getPrivate().getEncoded()); Base64.getEncoder().encodeToString(testKeyPair.getPrivate().getEncoded());
JwtVerificationKey existingKey = new JwtVerificationKey(keyId, publicKeyBase64); JwtSigningKey existingKey = new JwtSigningKey(keyId, publicKeyBase64);
Path keyFile = tempDir.resolve(keyId + ".key"); Path keyFile = tempDir.resolve(keyId + ".key");
Files.writeString(keyFile, privateKeyBase64); Files.writeString(keyFile, privateKeyBase64);
@ -116,7 +116,7 @@ class KeyPersistenceServiceInterfaceTest {
keyPersistenceService = new KeyPersistenceService(applicationProperties, cacheManager); keyPersistenceService = new KeyPersistenceService(applicationProperties, cacheManager);
keyPersistenceService.initializeKeystore(); keyPersistenceService.initializeKeystore();
JwtVerificationKey result = keyPersistenceService.getActiveKey(); JwtSigningKey result = keyPersistenceService.getActiveKey();
assertNotNull(result); assertNotNull(result);
assertNotNull(result.getKeyId()); assertNotNull(result.getKeyId());
@ -131,7 +131,7 @@ class KeyPersistenceServiceInterfaceTest {
String privateKeyBase64 = String privateKeyBase64 =
Base64.getEncoder().encodeToString(testKeyPair.getPrivate().getEncoded()); Base64.getEncoder().encodeToString(testKeyPair.getPrivate().getEncoded());
JwtVerificationKey signingKey = new JwtVerificationKey(keyId, publicKeyBase64); JwtSigningKey signingKey = new JwtSigningKey(keyId, publicKeyBase64);
Path keyFile = tempDir.resolve(keyId + ".key"); Path keyFile = tempDir.resolve(keyId + ".key");
Files.writeString(keyFile, privateKeyBase64); Files.writeString(keyFile, privateKeyBase64);
@ -213,7 +213,7 @@ class KeyPersistenceServiceInterfaceTest {
String publicKeyBase64 = String publicKeyBase64 =
Base64.getEncoder().encodeToString(testKeyPair.getPublic().getEncoded()); Base64.getEncoder().encodeToString(testKeyPair.getPublic().getEncoded());
JwtVerificationKey existingKey = new JwtVerificationKey(keyId, publicKeyBase64); JwtSigningKey existingKey = new JwtSigningKey(keyId, publicKeyBase64);
try (MockedStatic<InstallationPathConfig> mockedStatic = try (MockedStatic<InstallationPathConfig> mockedStatic =
mockStatic(InstallationPathConfig.class)) { mockStatic(InstallationPathConfig.class)) {
@ -223,10 +223,10 @@ class KeyPersistenceServiceInterfaceTest {
keyPersistenceService = new KeyPersistenceService(applicationProperties, cacheManager); keyPersistenceService = new KeyPersistenceService(applicationProperties, cacheManager);
keyPersistenceService.initializeKeystore(); keyPersistenceService.initializeKeystore();
JwtVerificationKey result = keyPersistenceService.getActiveKey(); JwtSigningKey result = keyPersistenceService.getActiveKey();
assertNotNull(result); assertNotNull(result);
assertNotNull(result.getKeyId()); assertNotNull(result.getKeyId());
assertNotNull(result.getVerifyingKey()); assertNotNull(result.getKey());
} }
} }
} }

View File

@ -26,7 +26,7 @@ ext {
imageioVersion = "3.12.0" imageioVersion = "3.12.0"
lombokVersion = "1.18.38" lombokVersion = "1.18.38"
bouncycastleVersion = "1.81" bouncycastleVersion = "1.81"
springSecuritySamlVersion = "6.5.2" springSecurityVersion = "6.5.2"
openSamlVersion = "4.3.2" openSamlVersion = "4.3.2"
commonmarkVersion = "0.25.1" commonmarkVersion = "0.25.1"
googleJavaFormatVersion = "1.28.0" googleJavaFormatVersion = "1.28.0"