Spring Boot
Logging
Enable jdbc query logging
logging.level.org.springframework.jdbc.core.JdbcTemplate=DEBUG
Enable cache logging
logging.level.org.springframework.cache=TRACE
HTTPS
Enabling HTTPS with built-in Tomcat
1. Retrieve (e.g. letsencrypt) certificate.
2. Generate pk12 keystore:
openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -CAfile chain.pem -name default -caname root -out default.p12
3. Add SSL configuration to application.properties:
security.require-ssl=true
server.ssl.key-store=/path/to/default.p12
server.ssl.key-store-password=PASSWORD
server.ssl.keyStoreType=PKCS12
server.ssl.keyAlias=default
4. Restart application.
Enabling HTTPS with Apache HTTP as reverse proxy
Requred additional Apache HTTP modules are proxy, proxy_http and headers.
1. Configure Apache HTTP:
site.conf (complete)
<IfModule mod_ssl.c>
<VirtualHost *:443>
Include /etc/apache2/ssl/default
ServerName example.org
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
SSLCertificateFile /etc/apache2/ssl/certs/example.org/cert.pem
SSLCertificateKeyFile /etc/apache2/ssl/certs/exmaple.org/privkey.pem
SSLCACertificateFile /etc/apache2/ssl/certs/example.org/fullchain.pem
ErrorLog ${APACHE_LOG_DIR}/example.org.error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/example.org.access.log combined
ProxyRequests Off
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto https
RequestHeader set X-Forwarded-Port 443
ProxyPass / http://127.0.0.1:64444/
ProxyPassReverse / http://127.0.0.1:64444/
</VirtualHost>
</IfModule>
/etc/apache2/ssl/default (for reference)
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLHonorCipherOrder on
SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS"
BrowserMatch "MSIE [2-6]" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0
BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
2. Configure application:
application.properties:
server.forward-headers-strategy=native
3. Required HttpSecurity config:
...
http.requiresChannel()
.anyRequest()
.requiresSecure()
Noteworthy application properties
server.servlet.session.cookie.name
Misc
Example build script
build.gradle
plugins {
id "org.springframework.boot" version "3.3.0"
id "io.spring.dependency-management" version "1.1.5"
id "java"
}
group = "org.example"
repositories {
mavenCentral()
}
dependencies {
implementation "org.springframework.boot:spring-boot-starter-web"
implementation "org.springframework.boot:spring-boot-starter-jdbc"
implementation "org.springframework.boot:spring-boot-starter-security"
implementation "org.springframework.boot:spring-boot-starter-thymeleaf"
implementation "org.thymeleaf.extras:thymeleaf-extras-springsecurity6"
runtimeOnly "org.xerial:sqlite-jdbc:3.45.3.0"
developmentOnly "org.springframework.boot:spring-boot-devtools"
testImplementation "org.junit.jupiter:junit-jupiter-api:5.9.3"
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.9.3"
}
configurations.implementation {
exclude group: "org.apache.logging.log4j", module: "log4j-to-slf4j"
exclude group: "org.springframework.boot", module: "spring-boot-starter-json"
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
test {
useJUnitPlatform()
}
bootJar {
launchScript()
}
springBoot {
buildInfo {
properties {
additional = [
revision: buildRev(),
time: new Date().format("yyyy-MM-dd:HHmmssZ")
]
}
}
}
def buildRev() {
final out = new ByteArrayOutputStream()
exec {
commandLine "hg", "parents", "--template", "{rev}"
standardOutput = out
}
out.toString()
}
Collections in the application.properties
application.properties
foo.key={'aa', 'b''b', 'cc'}
Value injection:
@Value("#{${foo.key}}") String[] keys
Avoiding redirects to login page on incorrect credentials when basic authentication is used:
1. Check that error page is not protected from anonymous access.
2. Alternatively, it may be avoided from the client-side by marking request as AJAX one by setting appropriate header:
X-Requested-With: XMLHttpRequest