133 lines
6.2 KiB
Java
133 lines
6.2 KiB
Java
package net.gepafin.tendermanagement.config;
|
|
|
|
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.http.HttpMethod;
|
|
import org.springframework.security.authentication.AuthenticationManager;
|
|
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
|
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
|
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.configuration.WebSecurityCustomizer;
|
|
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.web.SecurityFilterChain;
|
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
|
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
|
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
|
import org.springframework.web.cors.CorsConfiguration;
|
|
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
|
import org.springframework.web.filter.CorsFilter;
|
|
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
|
|
|
|
|
|
import io.swagger.v3.oas.models.Components;
|
|
import io.swagger.v3.oas.models.OpenAPI;
|
|
import io.swagger.v3.oas.models.security.SecurityRequirement;
|
|
import io.swagger.v3.oas.models.security.SecurityScheme;
|
|
import io.swagger.v3.oas.models.servers.Server;
|
|
import net.gepafin.tendermanagement.config.jwt.JWTFilter;
|
|
import net.gepafin.tendermanagement.config.jwt.TokenProvider;
|
|
|
|
@Configuration
|
|
@EnableWebSecurity
|
|
@EnableMethodSecurity(prePostEnabled = true)
|
|
public class SecurityConfig {
|
|
private final TokenProvider tokenProvider;
|
|
private final SamlSuccessHandler samlSuccessHandler;
|
|
private final SamlFailureHandler samlFailureHandler;
|
|
|
|
@Value("${base-url}")
|
|
String baseUrl;
|
|
|
|
@Autowired
|
|
public SecurityConfig(TokenProvider tokenProvider, SamlSuccessHandler samlSuccessHandler, SamlFailureHandler samlFailureHandler) {
|
|
this.tokenProvider = tokenProvider;
|
|
this.samlSuccessHandler =samlSuccessHandler;
|
|
this.samlFailureHandler=samlFailureHandler;
|
|
}
|
|
|
|
|
|
@Bean
|
|
public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
|
|
return config.getAuthenticationManager();
|
|
}
|
|
@Bean
|
|
public PasswordEncoder passwordEncoder() {
|
|
return new BCryptPasswordEncoder();
|
|
}
|
|
|
|
@Bean
|
|
public MvcRequestMatcher.Builder mvc(HandlerMappingIntrospector introspector) {
|
|
return new MvcRequestMatcher.Builder(introspector);
|
|
}
|
|
|
|
@Bean
|
|
public WebSecurityCustomizer webSecurityCustomizer(MvcRequestMatcher.Builder mvc) {
|
|
return (web) -> web.ignoring().requestMatchers(mvc.pattern(HttpMethod.OPTIONS, "/**"))
|
|
.requestMatchers(new AntPathRequestMatcher("/i18n/**"))
|
|
.requestMatchers(new AntPathRequestMatcher("/content/**"))
|
|
.requestMatchers(new AntPathRequestMatcher("/swagger-ui/index.html"))
|
|
.requestMatchers(new AntPathRequestMatcher("/swagger-ui/**"));
|
|
}
|
|
|
|
|
|
@Bean
|
|
public CorsFilter corsFilter() {
|
|
|
|
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
|
|
|
CorsConfiguration config = new CorsConfiguration();
|
|
config.addAllowedOrigin("*");
|
|
config.addAllowedMethod("*");
|
|
config.addAllowedHeader("*");
|
|
config.setMaxAge(3600l);
|
|
|
|
if (config.getAllowedOrigins() != null && !config.getAllowedOrigins().isEmpty()) {
|
|
source.registerCorsConfiguration("/v1/**", config);
|
|
source.registerCorsConfiguration("/management/**", config);
|
|
source.registerCorsConfiguration("/v1/api-docs", config);
|
|
}
|
|
return new CorsFilter(source);
|
|
}
|
|
@Bean
|
|
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
|
http.csrf(AbstractHttpConfigurer::disable).authorizeHttpRequests(auth -> auth
|
|
// Allow public access to the login endpoints
|
|
.requestMatchers("/v1/user/login").permitAll() // JWT-based login
|
|
.requestMatchers("/v1/saml/**").permitAll() // JWT-based login
|
|
.requestMatchers("/saml2/**").permitAll() // SAML login initiation
|
|
.requestMatchers("/swagger-ui/**").permitAll() // Swagger docs
|
|
.requestMatchers("/v1/api-docs/**").permitAll() // API docs
|
|
.anyRequest().authenticated())
|
|
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
|
.addFilterBefore(corsFilter(), UsernamePasswordAuthenticationFilter.class)
|
|
.addFilterBefore(new JWTFilter(tokenProvider), UsernamePasswordAuthenticationFilter.class)
|
|
// Add SAML2 login configuration (for BENEFICIARI)
|
|
/*
|
|
* .saml2Login(saml -> saml.loginPage("/saml/login") // Entry point for SAML
|
|
* login .defaultSuccessUrl("/") // Redirect after successful SAML login );
|
|
*/
|
|
.saml2Login(saml -> saml.defaultSuccessUrl("/").successHandler(samlSuccessHandler)
|
|
.failureHandler(samlFailureHandler));
|
|
|
|
|
|
return http.build();
|
|
}
|
|
|
|
@Bean
|
|
public OpenAPI customOpenAPI() {
|
|
return new OpenAPI()
|
|
.addServersItem(new Server().url("/"))
|
|
.addSecurityItem(new SecurityRequirement().addList("bearer-key"))
|
|
.components(new Components().addSecuritySchemes("bearer-key",
|
|
new SecurityScheme().type(SecurityScheme.Type.HTTP)
|
|
.scheme("bearer").bearerFormat("JWT")));
|
|
}
|
|
|
|
|
|
} |