wip - /view-pdf not loading properly

This commit is contained in:
DarioGii 2025-07-25 19:28:14 +01:00
parent 6a7328ff3d
commit 017b737b72
7 changed files with 71 additions and 22 deletions

View File

@ -9,7 +9,9 @@
"Bash(find:*)",
"Bash(grep:*)",
"Bash(rg:*)",
"Bash(strings:*)"
"Bash(strings:*)",
"Bash(pkill:*)",
"Bash(true)"
],
"deny": []
}

View File

@ -31,7 +31,7 @@ security:
google:
clientId: '' # client ID for Google OAuth2
clientSecret: '' # client secret for Google OAuth2
scopes: email, profile # scopes for Google OAuth2
scopes: https://www.googleapis.com/auth/userinfo.email, https://www.googleapis.com/auth/userinfo.profile # scopes for Google OAuth2
useAsUsername: email # field to use as the username for Google OAuth2. Available options are: [email | name | given_name | family_name]
github:
clientId: '' # client ID for GitHub OAuth2
@ -51,20 +51,20 @@ security:
provider: '' # The name of your Provider
autoCreateUser: true # set to 'true' to allow auto-creation of non-existing users
blockRegistration: false # set to 'true' to deny login with SSO without prior registration by an admin
registrationId: stirling # The name of your Service Provider (SP) app name. Should match the name in the path for your SSO & SLO URLs
idpMetadataUri: https://dev-XXXXXXXX.okta.com/app/externalKey/sso/saml/metadata # The uri for your Provider's metadata
idpSingleLoginUrl: https://dev-XXXXXXXX.okta.com/app/dev-XXXXXXXX_stirlingpdf_1/externalKey/sso/saml # The URL for initiating SSO. Provided by your Provider
idpSingleLogoutUrl: https://dev-XXXXXXXX.okta.com/app/dev-XXXXXXXX_stirlingpdf_1/externalKey/slo/saml # The URL for initiating SLO. Provided by your Provider
idpIssuer: '' # The ID of your Provider
idpCert: classpath:okta.cert # The certificate your Provider will use to authenticate your app's SAML authentication requests. Provided by your Provider
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
registrationId: stirlingpdf-dario-saml # The name of your Service Provider (SP) app name. Should match the name in the path for your SSO & SLO URLs
idpMetadataUri: https://authentik.dev.stirlingpdf.com/api/v3/providers/saml/5/metadata/ # The uri for your Provider's metadata
idpSingleLoginUrl: https://authentik.dev.stirlingpdf.com/application/saml/stirlingpdf-dario-saml/sso/binding/post/ # The URL for initiating SSO. Provided by your Provider
idpSingleLogoutUrl: https://authentik.dev.stirlingpdf.com/application/saml/stirlingpdf-dario-saml/slo/binding/post/ # The URL for initiating SLO. Provided by your Provider
idpIssuer: authentik # The ID of your Provider
idpCert: classpath:authentik-Self-signed_Certificate_certificate.pem # The certificate your Provider will use to authenticate your app's SAML authentication requests. Provided by your Provider
privateKey: classpath:private_key.key # Your private key. Generated from your keypair
spCert: classpath:certificate.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
premium:
key: 00000000-0000-0000-0000-000000000000
key: 3R3T-WFPY-UNRW-LJFA-MMXM-YVJK-WCKY-PCRT # fixme: remove
enabled: false # Enable license key checks for pro/enterprise features
proFeatures:
SSOAutoLogin: false

View File

@ -135,7 +135,7 @@ public class SecurityConfiguration {
boolean v2Enabled = appConfig.v2Enabled();
if (v2Enabled) {
http.addFilterAt(
http.addFilterBefore(
jwtAuthenticationFilter(),
UsernamePasswordAuthenticationFilter.class)
.exceptionHandling(
@ -145,8 +145,8 @@ public class SecurityConfiguration {
}
http.addFilterBefore(
userAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
.addFilterAfter(rateLimitingFilter(), userAuthenticationFilter.getClass())
.addFilterAfter(firstLoginFilter, rateLimitingFilter().getClass());
.addFilterAfter(rateLimitingFilter(), UserAuthenticationFilter.class)
.addFilterAfter(firstLoginFilter, UsernamePasswordAuthenticationFilter.class);
if (!securityProperties.getCsrfDisabled()) {
CookieCsrfTokenRepository cookieRepo =

View File

@ -88,6 +88,8 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
try {
jwtService.validateToken(jwtToken);
} catch (AuthenticationFailureException e) {
// Clear invalid tokens from response
jwtService.clearTokenFromResponse(response);
handleAuthenticationFailure(request, response, e);
return;
}
@ -129,7 +131,9 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authToken);
log.debug("JWT authentication successful for user: {}", username);
log.info(
"JWT authentication successful for user: {} - Authentication set in SecurityContext",
username);
} else {
throw new UsernameNotFoundException("User not found: " + username);

View File

@ -63,7 +63,15 @@ public class UserAuthenticationFilter extends OncePerRequestFilter {
return;
}
String requestURI = request.getRequestURI();
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
log.info(
"UserAuthenticationFilter - Authentication from SecurityContext: {}",
authentication != null
? authentication.getClass().getSimpleName()
+ " for "
+ authentication.getName()
: "null");
// Check for session expiration (unsure if needed)
// if (authentication != null && authentication.isAuthenticated()) {
@ -218,4 +226,37 @@ public class UserAuthenticationFilter extends OncePerRequestFilter {
return method;
}
}
@Override
protected boolean shouldNotFilter(HttpServletRequest request) {
String uri = request.getRequestURI();
String contextPath = request.getContextPath();
String[] permitAllPatterns = {
contextPath + "/login",
contextPath + "/signup",
contextPath + "/register",
contextPath + "/error",
contextPath + "/images/",
contextPath + "/public/",
contextPath + "/css/",
contextPath + "/fonts/",
contextPath + "/js/",
contextPath + "/pdfjs/",
contextPath + "/pdfjs-legacy/",
contextPath + "/api/v1/info/status",
contextPath + "/site.webmanifest"
};
for (String pattern : permitAllPatterns) {
if (uri.startsWith(pattern)
|| uri.endsWith(".svg")
|| uri.endsWith(".mjs")
|| uri.endsWith(".png")
|| uri.endsWith(".ico")) {
return true;
}
}
return false;
}
}

View File

@ -37,7 +37,7 @@ public class JwtKeystoreService implements JwtKeystoreServiceInterface {
public static final String KEY_SUFFIX = ".key";
private final JwtSigningKeyRepository repository;
private final ApplicationProperties.Security.Jwt jwtConfig;
private final ApplicationProperties.Security.Jwt jwtProperties;
private final Path privateKeyDirectory;
private volatile KeyPair currentKeyPair;
@ -47,7 +47,7 @@ public class JwtKeystoreService implements JwtKeystoreServiceInterface {
public JwtKeystoreService(
JwtSigningKeyRepository repository, ApplicationProperties applicationProperties) {
this.repository = repository;
this.jwtConfig = applicationProperties.getSecurity().getJwt();
this.jwtProperties = applicationProperties.getSecurity().getJwt();
this.privateKeyDirectory = Paths.get(InstallationPathConfig.getConfigPath(), "jwt-keys");
}
@ -128,7 +128,7 @@ public class JwtKeystoreService implements JwtKeystoreServiceInterface {
@Override
public boolean isKeystoreEnabled() {
return jwtConfig.isEnableKeystore();
return jwtProperties.isEnableKeystore();
}
private void loadOrGenerateKeypair() {

View File

@ -82,7 +82,6 @@ public class JwtService implements JwtServiceInterface {
.expiration(new Date(System.currentTimeMillis() + EXPIRATION))
.signWith(keyPair.getPrivate(), Jwts.SIG.RS256);
// Add key ID to header if keystore is enabled
String keyId = keystoreService.getActiveKeyId();
if (keyId != null) {
builder.header().keyId(keyId);
@ -136,8 +135,11 @@ public class JwtService implements JwtServiceInterface {
if (specificKeyPair.isPresent()) {
keyPair = specificKeyPair.get();
} else {
log.warn("Key ID {} not found in keystore, using active keypair", keyId);
keyPair = keystoreService.getActiveKeypair();
log.warn(
"Key ID {} not found in keystore, token may have been signed with a rotated key",
keyId);
throw new AuthenticationFailureException(
"JWT token signed with unknown key ID: " + keyId);
}
} else {
keyPair = keystoreService.getActiveKeypair();
@ -233,7 +235,7 @@ public class JwtService implements JwtServiceInterface {
.getHeader()
.get("kid");
} catch (Exception e) {
// Token might not have a key ID or be malformed
log.debug("Failed to extract key ID from token header: {}", e.getMessage());
return null;
}
}