SecurityConfig.java
package com.taxonomy.security.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter;
/**
* Spring Security configuration for form-login mode (default, without Keycloak).
* <p>
* Active when the {@code keycloak} profile is NOT active.
* Protects GUI (form login + session) and REST API (HTTP Basic for programmatic clients).
* CSRF protection is enabled for browser sessions but disabled for {@code /api/**} paths
* so that stateless REST clients authenticated via HTTP Basic can POST without a CSRF token.
*/
@Configuration
@EnableMethodSecurity
@Profile("!keycloak")
public class SecurityConfig {
private final AuthorizationRulesConfigurer authRules;
public SecurityConfig(AuthorizationRulesConfigurer authRules) {
this.authRules = authRules;
}
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> authRules.configure(auth))
.csrf(csrf -> csrf
.ignoringRequestMatchers("/api/**")
)
.headers(headers -> headers
.contentTypeOptions(Customizer.withDefaults())
.frameOptions(frame -> frame.sameOrigin())
.httpStrictTransportSecurity(hsts -> hsts
.includeSubDomains(true)
.maxAgeInSeconds(31536000))
.referrerPolicy(referrer -> referrer
.policy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN))
)
.formLogin(Customizer.withDefaults())
.httpBasic(Customizer.withDefaults())
.logout(Customizer.withDefaults());
return http.build();
}
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}