mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-05-19 01:16:41 +02:00
Fix csrf (#2126)
* apply fix * Fixes empty th:action * Update build.gradle * fix * formatting --------- Co-authored-by: Dimitrios Kaitantzidis <james_k23@hotmail.gr>
This commit is contained in:
parent
c39b111edc
commit
903dc7638c
@ -137,7 +137,7 @@ dependencies {
|
|||||||
|
|
||||||
if (System.getenv("DOCKER_ENABLE_SECURITY") != "false") {
|
if (System.getenv("DOCKER_ENABLE_SECURITY") != "false") {
|
||||||
implementation "org.springframework.boot:spring-boot-starter-security:$springBootVersion"
|
implementation "org.springframework.boot:spring-boot-starter-security:$springBootVersion"
|
||||||
runtimeOnly "org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.1.2.RELEASE"
|
implementation "org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.1.2.RELEASE"
|
||||||
implementation "org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion"
|
implementation "org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion"
|
||||||
implementation "org.springframework.boot:spring-boot-starter-oauth2-client:$springBootVersion"
|
implementation "org.springframework.boot:spring-boot-starter-oauth2-client:$springBootVersion"
|
||||||
|
|
||||||
@ -154,6 +154,8 @@ dependencies {
|
|||||||
implementation "org.springframework.security:spring-security-saml2-service-provider"
|
implementation "org.springframework.security:spring-security-saml2-service-provider"
|
||||||
|
|
||||||
implementation 'com.coveo:saml-client:5.0.0'
|
implementation 'com.coveo:saml-client:5.0.0'
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
testImplementation "org.springframework.boot:spring-boot-starter-test:$springBootVersion"
|
testImplementation "org.springframework.boot:spring-boot-starter-test:$springBootVersion"
|
||||||
|
@ -36,6 +36,8 @@ import org.springframework.security.saml2.provider.service.web.authentication.Sa
|
|||||||
import org.springframework.security.web.SecurityFilterChain;
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
|
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
|
||||||
|
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
|
||||||
|
import org.springframework.security.web.csrf.CsrfTokenRequestAttributeHandler;
|
||||||
import org.springframework.security.web.savedrequest.NullRequestCache;
|
import org.springframework.security.web.savedrequest.NullRequestCache;
|
||||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||||
|
|
||||||
@ -94,6 +96,16 @@ public class SecurityConfiguration {
|
|||||||
userAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
|
userAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
|
||||||
if (applicationProperties.getSecurity().getCsrfDisabled()) {
|
if (applicationProperties.getSecurity().getCsrfDisabled()) {
|
||||||
http.csrf(csrf -> csrf.disable());
|
http.csrf(csrf -> csrf.disable());
|
||||||
|
} else {
|
||||||
|
CookieCsrfTokenRepository cookieRepo =
|
||||||
|
CookieCsrfTokenRepository.withHttpOnlyFalse();
|
||||||
|
CsrfTokenRequestAttributeHandler requestHandler =
|
||||||
|
new CsrfTokenRequestAttributeHandler();
|
||||||
|
requestHandler.setCsrfRequestAttributeName(null);
|
||||||
|
http.csrf(
|
||||||
|
csrf ->
|
||||||
|
csrf.csrfTokenRepository(cookieRepo)
|
||||||
|
.csrfTokenRequestHandler(requestHandler));
|
||||||
}
|
}
|
||||||
http.addFilterBefore(rateLimitingFilter(), UsernamePasswordAuthenticationFilter.class);
|
http.addFilterBefore(rateLimitingFilter(), UsernamePasswordAuthenticationFilter.class);
|
||||||
http.addFilterAfter(firstLoginFilter, UsernamePasswordAuthenticationFilter.class);
|
http.addFilterAfter(firstLoginFilter, UsernamePasswordAuthenticationFilter.class);
|
||||||
@ -113,6 +125,7 @@ public class SecurityConfiguration {
|
|||||||
logout.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
|
logout.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
|
||||||
.logoutSuccessHandler(
|
.logoutSuccessHandler(
|
||||||
new CustomLogoutSuccessHandler(applicationProperties))
|
new CustomLogoutSuccessHandler(applicationProperties))
|
||||||
|
.clearAuthentication(true)
|
||||||
.invalidateHttpSession(true) // Invalidate session
|
.invalidateHttpSession(true) // Invalidate session
|
||||||
.deleteCookies("JSESSIONID", "remember-me"));
|
.deleteCookies("JSESSIONID", "remember-me"));
|
||||||
http.rememberMe(
|
http.rememberMe(
|
||||||
@ -223,6 +236,16 @@ public class SecurityConfiguration {
|
|||||||
} else {
|
} else {
|
||||||
if (applicationProperties.getSecurity().getCsrfDisabled()) {
|
if (applicationProperties.getSecurity().getCsrfDisabled()) {
|
||||||
http.csrf(csrf -> csrf.disable());
|
http.csrf(csrf -> csrf.disable());
|
||||||
|
} else {
|
||||||
|
CookieCsrfTokenRepository cookieRepo =
|
||||||
|
CookieCsrfTokenRepository.withHttpOnlyFalse();
|
||||||
|
CsrfTokenRequestAttributeHandler requestHandler =
|
||||||
|
new CsrfTokenRequestAttributeHandler();
|
||||||
|
requestHandler.setCsrfRequestAttributeName(null);
|
||||||
|
http.csrf(
|
||||||
|
csrf ->
|
||||||
|
csrf.csrfTokenRepository(cookieRepo)
|
||||||
|
.csrfTokenRequestHandler(requestHandler));
|
||||||
}
|
}
|
||||||
http.authorizeHttpRequests(authz -> authz.anyRequest().permitAll());
|
http.authorizeHttpRequests(authz -> authz.anyRequest().permitAll());
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
<!-- Change Username Form -->
|
<!-- Change Username Form -->
|
||||||
<h4 th:text="#{changeCreds.changePassword}">Change password</h4>
|
<h4 th:text="#{changeCreds.changePassword}">Change password</h4>
|
||||||
<form action="api/v1/user/change-password-on-login" method="post" id="formsavechangecreds">
|
<form th:action="@{'api/v1/user/change-password-on-login'}" method="post" id="formsavechangecreds">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="currentPassword" th:text="#{changeCreds.oldPassword}">Old Password</label>
|
<label for="currentPassword" th:text="#{changeCreds.oldPassword}">Old Password</label>
|
||||||
<input type="password" class="form-control" name="currentPassword" id="currentPassword" th:placeholder="#{changeCreds.oldPassword}">
|
<input type="password" class="form-control" name="currentPassword" id="currentPassword" th:placeholder="#{changeCreds.oldPassword}">
|
||||||
|
@ -351,7 +351,7 @@
|
|||||||
</a>
|
</a>
|
||||||
<div class="dropdown-menu dropdown-menu-tp" aria-labelledby="searchDropdown">
|
<div class="dropdown-menu dropdown-menu-tp" aria-labelledby="searchDropdown">
|
||||||
<div class="dropdown-menu-wrapper px-xl-2 px-2">
|
<div class="dropdown-menu-wrapper px-xl-2 px-2">
|
||||||
<form class="d-flex p-2 search-form" id="searchForm">
|
<form th:action="@{''}" class="d-flex p-2 search-form" id="searchForm">
|
||||||
<input class="form-control search-input" type="search" placeholder="Search" aria-label="Search" id="navbarSearchInput">
|
<input class="form-control search-input" type="search" placeholder="Search" aria-label="Search" id="navbarSearchInput">
|
||||||
</form>
|
</form>
|
||||||
<!-- Search Results -->
|
<!-- Search Results -->
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
<span class="material-symbols-rounded tool-header-icon organize">add_to_photos</span>
|
<span class="material-symbols-rounded tool-header-icon organize">add_to_photos</span>
|
||||||
<span class="tool-header-text" th:text="#{merge.header}"></span>
|
<span class="tool-header-text" th:text="#{merge.header}"></span>
|
||||||
</div>
|
</div>
|
||||||
<form action="api/v1/general/merge-pdfs" method="post" enctype="multipart/form-data">
|
<form th:action="@{'api/v1/general/merge-pdfs'}" method="post" enctype="multipart/form-data">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label th:text="#{multiPdfDropPrompt}" for="fileInput-input"></label>
|
<label th:text="#{multiPdfDropPrompt}" for="fileInput-input"></label>
|
||||||
<div
|
<div
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row justify-content-center">
|
<div class="row justify-content-center">
|
||||||
<div class="col-md-12 bg-card">
|
<div class="col-md-12 bg-card">
|
||||||
<form>
|
<form th:action="@{''}">
|
||||||
<div class="row justify-content-center">
|
<div class="row justify-content-center">
|
||||||
|
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
<span class="material-symbols-rounded tool-header-icon other">thread_unread</span>
|
<span class="material-symbols-rounded tool-header-icon other">thread_unread</span>
|
||||||
<span class="tool-header-text" th:text="#{removeAnnotations.header}"></span>
|
<span class="tool-header-text" th:text="#{removeAnnotations.header}"></span>
|
||||||
</div>
|
</div>
|
||||||
<form id="pdfForm" class="mb-3">
|
<form id="pdfForm" th:action="@{''}" class="mb-3">
|
||||||
<div class="custom-file">
|
<div class="custom-file">
|
||||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf', remoteCall='false')}"></div>
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf', remoteCall='false')}"></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
<span class="material-symbols-rounded tool-header-icon word">remove_selection</span>
|
<span class="material-symbols-rounded tool-header-icon word">remove_selection</span>
|
||||||
<span class="tool-header-text" th:text="#{removeImage.header}"></span>
|
<span class="tool-header-text" th:text="#{removeImage.header}"></span>
|
||||||
</div>
|
</div>
|
||||||
<form action="api/v1/general/remove-image-pdf" method="post" enctype="multipart/form-data">
|
<form th:action="@{'api/v1/general/remove-image-pdf'}" method="post" enctype="multipart/form-data">
|
||||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}"></div>
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}"></div>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
<span class="material-symbols-rounded tool-header-icon security">lock</span>
|
<span class="material-symbols-rounded tool-header-icon security">lock</span>
|
||||||
<span class="tool-header-text" th:text="#{addPassword.header}"></span>
|
<span class="tool-header-text" th:text="#{addPassword.header}"></span>
|
||||||
</div>
|
</div>
|
||||||
<form action="api/v1/security/add-password" method="post" enctype="multipart/form-data">
|
<form th:action="@{'api/v1/security/add-password'}" method="post" enctype="multipart/form-data">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label th:text="#{addPassword.selectText.1}"></label>
|
<label th:text="#{addPassword.selectText.1}"></label>
|
||||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}"></div>
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}"></div>
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
<span class="tool-header-text" th:text="#{watermark.header}"></span>
|
<span class="tool-header-text" th:text="#{watermark.header}"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form method="post" enctype="multipart/form-data" action="api/v1/security/add-watermark">
|
<form method="post" enctype="multipart/form-data" th:action="@{'api/v1/security/add-watermark'}">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label th:text="#{watermark.selectText.1}"></label>
|
<label th:text="#{watermark.selectText.1}"></label>
|
||||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}"></div>
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}"></div>
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
<span class="material-symbols-rounded tool-header-icon security">ink_eraser</span>
|
<span class="material-symbols-rounded tool-header-icon security">ink_eraser</span>
|
||||||
<span class="tool-header-text" th:text="#{autoRedact.header}"></span>
|
<span class="tool-header-text" th:text="#{autoRedact.header}"></span>
|
||||||
</div>
|
</div>
|
||||||
<form action="api/v1/security/auto-redact" method="post" enctype="multipart/form-data">
|
<form th:action="@{'api/v1/security/auto-redact'}" method="post" enctype="multipart/form-data">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<input type="file" class="form-control" id="fileInput" name="fileInput" required accept="application/pdf">
|
<input type="file" class="form-control" id="fileInput" name="fileInput" required accept="application/pdf">
|
||||||
</div>
|
</div>
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
<span class="material-symbols-rounded tool-header-icon security">workspace_premium</span>
|
<span class="material-symbols-rounded tool-header-icon security">workspace_premium</span>
|
||||||
<span class="tool-header-text" th:text="#{certSign.header}"></span>
|
<span class="tool-header-text" th:text="#{certSign.header}"></span>
|
||||||
</div>
|
</div>
|
||||||
<form action="api/v1/security/cert-sign" method="post" enctype="multipart/form-data">
|
<form th:action="@{'api/v1/security/cert-sign'}" method="post" enctype="multipart/form-data">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label th:text="#{certSign.selectPDF}"></label>
|
<label th:text="#{certSign.selectPDF}"></label>
|
||||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}"></div>
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}"></div>
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
<span class="tool-header-text" th:text="#{permissions.header}"></span>
|
<span class="tool-header-text" th:text="#{permissions.header}"></span>
|
||||||
</div>
|
</div>
|
||||||
<p th:text="#{permissions.warning}"></p>
|
<p th:text="#{permissions.warning}"></p>
|
||||||
<form action="api/v1/security/add-password" method="post" enctype="multipart/form-data">
|
<form th:action="@{'api/v1/security/add-password'}" method="post" enctype="multipart/form-data">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label th:text="#{permissions.selectText.1}"></label>
|
<label th:text="#{permissions.selectText.1}"></label>
|
||||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}"></div>
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}"></div>
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
<span class="material-symbols-rounded tool-header-icon security">remove_moderator</span>
|
<span class="material-symbols-rounded tool-header-icon security">remove_moderator</span>
|
||||||
<span class="tool-header-text" th:text="#{removeCertSign.header}"></span>
|
<span class="tool-header-text" th:text="#{removeCertSign.header}"></span>
|
||||||
</div>
|
</div>
|
||||||
<form action="api/v1/security/remove-cert-sign" method="post" enctype="multipart/form-data">
|
<form th:action="@{'api/v1/security/remove-cert-sign'}" method="post" enctype="multipart/form-data">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label th:text="#{removeCertSign.selectPDF}"></label>
|
<label th:text="#{removeCertSign.selectPDF}"></label>
|
||||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}"></div>
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}"></div>
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
<span class="material-symbols-rounded tool-header-icon security">lock_open_right</span>
|
<span class="material-symbols-rounded tool-header-icon security">lock_open_right</span>
|
||||||
<span class="tool-header-text" th:text="#{removePassword.header}"></span>
|
<span class="tool-header-text" th:text="#{removePassword.header}"></span>
|
||||||
</div>
|
</div>
|
||||||
<form action="api/v1/security/remove-password" method="post" enctype="multipart/form-data">
|
<form th:action="@{'api/v1/security/remove-password'}" method="post" enctype="multipart/form-data">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label th:text="#{removePassword.selectText.1}"></label>
|
<label th:text="#{removePassword.selectText.1}"></label>
|
||||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}"></div>
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}"></div>
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
<span class="material-symbols-rounded tool-header-icon security">water_drop</span>
|
<span class="material-symbols-rounded tool-header-icon security">water_drop</span>
|
||||||
<span class="tool-header-text" th:text="#{remove-watermark.header}"></span>
|
<span class="tool-header-text" th:text="#{remove-watermark.header}"></span>
|
||||||
</div>
|
</div>
|
||||||
<form method="post" enctype="multipart/form-data" action="api/v1/security/remove-watermark">
|
<form method="post" enctype="multipart/form-data" th:action="@{'api/v1/security/remove-watermark'}">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label th:text="#{remove-watermark.selectText.1}"></label>
|
<label th:text="#{remove-watermark.selectText.1}"></label>
|
||||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}"></div>
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}"></div>
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
<span class="material-symbols-rounded tool-header-icon security">sanitizer</span>
|
<span class="material-symbols-rounded tool-header-icon security">sanitizer</span>
|
||||||
<span class="tool-header-text" th:text="#{sanitizePDF.header}"></span>
|
<span class="tool-header-text" th:text="#{sanitizePDF.header}"></span>
|
||||||
</div>
|
</div>
|
||||||
<form action="api/v1/security/sanitize-pdf" method="post" enctype="multipart/form-data">
|
<form th:action="@{'api/v1/security/sanitize-pdf'}" method="post" enctype="multipart/form-data">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}"></div>
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}"></div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user