mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-08-02 18:45:21 +00:00
wip
This commit is contained in:
parent
d197285a56
commit
71513ba762
@ -60,11 +60,12 @@ security:
|
||||
privateKey: classpath:saml-private-key.key # Your private key. Generated from your keypair
|
||||
spCert: classpath:saml-public-cert.crt # Your signing certificate. Generated from your keypair
|
||||
jwt:
|
||||
enableKeyStore: true # Set to 'true' to enable JWT key store
|
||||
enableKeyRotation: true # Set to 'true' to enable JWT key rotation
|
||||
enableKeyCleanup: true # Set to 'true' to enable JWT key cleanup
|
||||
persistence: true # Set to 'true' to enable JWT key store
|
||||
enableKeyRotation: true # Set to 'true' to enable key pair rotation
|
||||
enableKeyCleanup: true # Set to 'true' to enable key pair cleanup
|
||||
keyRetentionDays: 7 # Number of days to retain old keys. The default is 7 days.
|
||||
cleanupBatchSize: 100 # Number of keys to clean up in each batch. The default is 100.
|
||||
secureCookie: false # Set to 'true' to use secure cookies for JWTs
|
||||
|
||||
premium:
|
||||
key: 00000000-0000-0000-0000-000000000000
|
||||
|
@ -10,6 +10,7 @@ import java.util.function.Function;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.ResponseCookie;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
@ -43,6 +44,9 @@ public class JwtService implements JwtServiceInterface {
|
||||
private static final String ISSUER = "Stirling PDF";
|
||||
private static final long EXPIRATION = 3600000;
|
||||
|
||||
@Value("${stirling.security.jwt.secureCookie:true}")
|
||||
private boolean secureCookie;
|
||||
|
||||
private final KeystoreServiceInterface keystoreService;
|
||||
private final boolean v2Enabled;
|
||||
|
||||
@ -198,7 +202,7 @@ public class JwtService implements JwtServiceInterface {
|
||||
ResponseCookie cookie =
|
||||
ResponseCookie.from(JWT_COOKIE_NAME, Newlines.stripAll(token))
|
||||
.httpOnly(true)
|
||||
// .secure(true) // todo: fix, make configurable
|
||||
.secure(secureCookie)
|
||||
.sameSite("Strict")
|
||||
.maxAge(EXPIRATION / 1000)
|
||||
.path("/")
|
||||
@ -214,7 +218,7 @@ public class JwtService implements JwtServiceInterface {
|
||||
ResponseCookie cookie =
|
||||
ResponseCookie.from(JWT_COOKIE_NAME, "")
|
||||
.httpOnly(true)
|
||||
.secure(true)
|
||||
.secure(secureCookie)
|
||||
.sameSite("None")
|
||||
.maxAge(0)
|
||||
.path("/")
|
||||
|
@ -11,6 +11,8 @@ import java.util.Optional;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
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.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.security.core.Authentication;
|
||||
@ -201,19 +203,10 @@ class JwtServiceTest {
|
||||
assertThrows(AuthenticationFailureException.class, () -> jwtService.extractClaims("invalid-token"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExtractTokenWithAuthorizationHeader() {
|
||||
String token = "test-token";
|
||||
when(request.getHeader("Authorization")).thenReturn("Bearer " + token);
|
||||
|
||||
assertEquals(token, jwtService.extractToken(request));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExtractTokenWithCookie() {
|
||||
String token = "test-token";
|
||||
Cookie[] cookies = { new Cookie("stirling_jwt", token) };
|
||||
when(request.getHeader("Authorization")).thenReturn(null);
|
||||
when(request.getCookies()).thenReturn(cookies);
|
||||
|
||||
assertEquals(token, jwtService.extractToken(request));
|
||||
@ -221,7 +214,6 @@ class JwtServiceTest {
|
||||
|
||||
@Test
|
||||
void testExtractTokenWithNoCookies() {
|
||||
when(request.getHeader("Authorization")).thenReturn(null);
|
||||
when(request.getCookies()).thenReturn(null);
|
||||
|
||||
assertNull(jwtService.extractToken(request));
|
||||
@ -230,7 +222,6 @@ class JwtServiceTest {
|
||||
@Test
|
||||
void testExtractTokenWithWrongCookie() {
|
||||
Cookie[] cookies = {new Cookie("OTHER_COOKIE", "value")};
|
||||
when(request.getHeader("Authorization")).thenReturn(null);
|
||||
when(request.getCookies()).thenReturn(cookies);
|
||||
|
||||
assertNull(jwtService.extractToken(request));
|
||||
@ -238,22 +229,30 @@ class JwtServiceTest {
|
||||
|
||||
@Test
|
||||
void testExtractTokenWithInvalidAuthorizationHeader() {
|
||||
when(request.getHeader("Authorization")).thenReturn("Basic token");
|
||||
when(request.getCookies()).thenReturn(null);
|
||||
|
||||
assertNull(jwtService.extractToken(request));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAddToken() {
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
void testAddToken(boolean secureCookie) throws Exception {
|
||||
String token = "test-token";
|
||||
|
||||
jwtService.addToken(response, token);
|
||||
// Create new JwtService instance with the secureCookie parameter
|
||||
JwtService testJwtService = createJwtServiceWithSecureCookie(secureCookie);
|
||||
|
||||
testJwtService.addToken(response, token);
|
||||
|
||||
verify(response).setHeader("Authorization", "Bearer " + token);
|
||||
verify(response).addHeader(eq("Set-Cookie"), contains("stirling_jwt=" + token));
|
||||
verify(response).addHeader(eq("Set-Cookie"), contains("HttpOnly"));
|
||||
verify(response).addHeader(eq("Set-Cookie"), contains("Secure"));
|
||||
|
||||
if (secureCookie) {
|
||||
verify(response).addHeader(eq("Set-Cookie"), contains("Secure"));
|
||||
} else {
|
||||
verify(response, org.mockito.Mockito.never()).addHeader(eq("Set-Cookie"), contains("Secure"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -327,4 +326,16 @@ class JwtServiceTest {
|
||||
// Verify fallback to active keypair was used (called multiple times during token operations)
|
||||
verify(keystoreService, atLeast(1)).getActiveKeyPair();
|
||||
}
|
||||
|
||||
private JwtService createJwtServiceWithSecureCookie(boolean secureCookie) throws Exception {
|
||||
// Use reflection to create JwtService with custom secureCookie value
|
||||
JwtService testService = new JwtService(true, keystoreService);
|
||||
|
||||
// Set the secureCookie field using reflection
|
||||
java.lang.reflect.Field secureCookieField = JwtService.class.getDeclaredField("secureCookie");
|
||||
secureCookieField.setAccessible(true);
|
||||
secureCookieField.set(testService, secureCookie);
|
||||
|
||||
return testService;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user