You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
123 lines
6.5 KiB
123 lines
6.5 KiB
package com.gcc_manpower.config;
|
|
|
|
import org.springframework.context.annotation.Bean;
|
|
import org.springframework.context.annotation.Configuration;
|
|
import org.springframework.security.authentication.AuthenticationManager;
|
|
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
|
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.XXssProtectionHeaderWriter;
|
|
|
|
@Configuration
|
|
@EnableWebSecurity
|
|
public class SecurityConfig {
|
|
|
|
@Bean
|
|
public PasswordEncoder passwordEncoder() {
|
|
return new PasswordEncoder() {
|
|
private final BCryptPasswordEncoder bcrypt = new BCryptPasswordEncoder();
|
|
|
|
@Override
|
|
public String encode(CharSequence rawPassword) {
|
|
return bcrypt.encode(rawPassword);
|
|
}
|
|
|
|
@Override
|
|
public boolean matches(CharSequence rawPassword, String dbPassword) {
|
|
if (dbPassword != null && dbPassword.startsWith("$2a$")) {
|
|
return bcrypt.matches(rawPassword, dbPassword);
|
|
}
|
|
return rawPassword.toString().equals(dbPassword);
|
|
}
|
|
};
|
|
}
|
|
|
|
@Bean
|
|
public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
|
|
return config.getAuthenticationManager();
|
|
}
|
|
|
|
@Bean
|
|
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
|
http
|
|
// Configure headers for clickjacking and XSS protection
|
|
.headers(headers -> headers
|
|
.frameOptions(frame -> frame.sameOrigin())
|
|
.xssProtection(
|
|
xss -> xss.headerValue(XXssProtectionHeaderWriter.HeaderValue.ENABLED_MODE_BLOCK)))
|
|
// Configure URL authorization
|
|
.authorizeHttpRequests(auth -> auth
|
|
// Allow static resources
|
|
.requestMatchers(
|
|
"/assets/**",
|
|
"/css/**",
|
|
"/js/**",
|
|
"/images/**",
|
|
"/favicon.ico",
|
|
"/error")
|
|
.permitAll()
|
|
// Allow login pages and login API endpoints
|
|
.requestMatchers(
|
|
"/login",
|
|
"/api/val-app-usr-login",
|
|
"/gcctonermanagement/login",
|
|
"/gcctonermanagement/api/login",
|
|
"/gccservicepaymenttracker/login",
|
|
"/gccservicepaymenttracker/api/login",
|
|
"/gccservicedocuments/login",
|
|
"/gccservicedocuments/api/login")
|
|
.permitAll()
|
|
// Allow logout endpoints
|
|
.requestMatchers(
|
|
"/usr-logout",
|
|
"/gcctonermanagement/logout",
|
|
"/gccservicepaymenttracker/logout",
|
|
"/gccservicedocuments/logout")
|
|
.permitAll()
|
|
// Require authentication for all other requests
|
|
.anyRequest().authenticated())
|
|
// Configure CSRF protection (ignore CSRF on the login endpoints only)
|
|
.csrf(csrf -> csrf
|
|
.ignoringRequestMatchers(
|
|
"/api/val-app-usr-login",
|
|
"/gcctonermanagement/api/login",
|
|
"/gccservicepaymenttracker/api/login",
|
|
"/gccservicedocuments/api/login"))
|
|
// Session management configuration with module-aware invalid session
|
|
// redirection
|
|
.sessionManagement(session -> session
|
|
.invalidSessionStrategy((request, response) -> {
|
|
// Create a fresh session so requestedSessionIdValid won't cause endless loop
|
|
request.getSession(true);
|
|
String requestURI = request.getRequestURI();
|
|
if (requestURI.contains("/gccservicepaymenttracker")) {
|
|
response.sendRedirect(request.getContextPath() + "/gccservicepaymenttracker/login");
|
|
} else if (requestURI.contains("/gcctonermanagement")) {
|
|
response.sendRedirect(request.getContextPath() + "/gcctonermanagement/login");
|
|
} else if (requestURI.contains("/gccservicedocuments")) {
|
|
response.sendRedirect(request.getContextPath() + "/gccservicedocuments/login");
|
|
} else {
|
|
response.sendRedirect(request.getContextPath() + "/login");
|
|
}
|
|
}))
|
|
// Exception handling for unauthenticated requests with module-aware redirection
|
|
.exceptionHandling(exceptions -> exceptions
|
|
.authenticationEntryPoint((request, response, authException) -> {
|
|
String requestURI = request.getRequestURI();
|
|
if (requestURI.contains("/gccservicepaymenttracker")) {
|
|
response.sendRedirect(request.getContextPath() + "/gccservicepaymenttracker/login");
|
|
} else if (requestURI.contains("/gcctonermanagement")) {
|
|
response.sendRedirect(request.getContextPath() + "/gcctonermanagement/login");
|
|
} else if (requestURI.contains("/gccservicedocuments")) {
|
|
response.sendRedirect(request.getContextPath() + "/gccservicedocuments/login");
|
|
} else {
|
|
response.sendRedirect(request.getContextPath() + "/login");
|
|
}
|
|
}));
|
|
|
|
return http.build();
|
|
}
|
|
}
|