package com.infra_automation.config;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.Customizer;
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.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
@EnableWebSecurity
@Configuration
public class SecurityConfig {
// @Value("${api.auth.registration.url}")
// private String registrationURL;
//
// @Value("${api.auth.login.url}")
// private String loginURL;
//
// @Value("${api.allowed.origin}")
// private String allowedOrigin;
private final String authApiBaseURL;
private final String registrationURL;
private final String loginURL;
private final String allowOriginUrl;
private final List<String> allowMethods;
@Autowired
public SecurityConfig(
@Value("${api.auth.registration.url}") String registrationURL,
@Value("${api.auth.base.url}") String authApiBaseUrl,
@Value("${api.auth.login.url}") String loginURL,
@Value("${auth.allow.origin}") String allowOriginUrl,
@Value("#{'${auth.allow.method}'.split(',')}") List<String> allowMethods
) {
this.registrationURL = registrationURL;
this.loginURL = loginURL;
this.authApiBaseURL = authApiBaseUrl;
this.allowOriginUrl = allowOriginUrl;
this.allowMethods = allowMethods;
}
/**
* Creates a CORS configuration bean
*/
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(List.of("https://ekam.npci.org.in","http://localhost:3003"));
configuration.setAllowedMethods(List.of("GET", "POST", "DELETE", "PUT"));
configuration.setAllowedHeaders(List.of("*"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
/**
* Configures security settings including authentication, authorization, CORS, CSRF, and JWT filtering
*/
// @Bean
// public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity,
// JwtAuthenticationFilter jwtAuthenticationFilter,
// JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint)
// throws Exception {
// httpSecurity
// .headers(headers -> headers
// .httpStrictTransportSecurity(hsts -> hsts.includeSubDomains(true).maxAgeInSeconds(31536000))
// .contentSecurityPolicy(csp -> csp.policyDirectives("default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'"))
// .frameOptions(frameOptions -> frameOptions.deny())); // Prevent Clickjacking
//
//
// httpSecurity
// .cors(cors -> cors.configurationSource(corsConfigurationSource()))
// .csrf(csrf -> csrf.disable())
// .authorizeHttpRequests(auth -> auth
// .requestMatchers(registrationURL, loginURL, "/pcom_bk/api/v1/redis/get/**").permitAll()
// .anyRequest().permitAll()) // Restrict other endpoints
// .exceptionHandling(exception -> exception.authenticationEntryPoint(jwtAuthenticationEntryPoint))
// .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
//
// httpSecurity.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
//
// return httpSecurity.build();
// }
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity,
JwtAuthenticationFilter jwtAuthenticationFilter,
JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint) throws Exception {
httpSecurity
.headers(headers -> headers
.addHeaderWriter((request, response) -> {
response.setHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload");
})
.xssProtection(Customizer.withDefaults())
.addHeaderWriter((request, response) -> {
response.setHeader("Content-Security-Policy",
"default-src 'self'; " +
"script-src 'self'; " +
"frame-ancestors 'self'; " +
"img-src 'self'; " +
"style-src 'self'; " +
"object-src 'none'; " +
"frame-src 'self'; " +
"form-action 'self'; " +
"media-src 'self';"
);
})
.addHeaderWriter((request, response) -> {
response.setHeader("Expect-CT", "max-age=3600, enforce");
})
.addHeaderWriter((request, response) -> {
response.setHeader("X-XSS-Protection", "1; mode=block");
})
.referrerPolicy(referrer -> referrer
.policy(ReferrerPolicyHeaderWriter.ReferrerPolicy.SAME_ORIGIN)
)
.addHeaderWriter((request, response) -> {
response.setHeader("X-Content-Type-Options", "nosniff");
})
)
.cors(Customizer.withDefaults())
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(auth -> auth
.requestMatchers(authApiBaseURL + registrationURL + "/**",
authApiBaseURL + loginURL + "/**",
"/InfraBk/api/v1/inventory/flushDb",
"/InfraBk/api/v1/inventory/upload-inventory")
.permitAll()
.anyRequest()
.authenticated()
)
.exceptionHandling(exception -> exception
.authenticationEntryPoint(jwtAuthenticationEntryPoint)
)
.sessionManagement(session -> session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return httpSecurity.build();
}
@Bean
public InMemoryUserDetailsManager userDetailsManager() {
return new InMemoryUserDetailsManager();
}
/**
* Bean to encode passwords
*/
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
/**
* Provides the authentication manager
*/
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration)
throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
}
fixed these issues 3. Remove duplicate security headers
X-Content-Type-Options
X-XSS-Protection: 0, set this header to 1 and mode = block
X-Frame-Options
Strict-Transport-Security
1. set Access Control Allow Credentials header to False
For further actions, you may consider blocking this person and/or reporting abuse
Top comments (0)