Merge pull request #24 from Kitzanos/feature/GEPAFINBE-23
GEPAFIN-BE-23(Benificiaries Login WIth Saml2) to start communication with LoginUmbria
This commit is contained in:
36
pom.xml
36
pom.xml
@@ -116,10 +116,6 @@
|
|||||||
<artifactId>jjwt-jackson</artifactId>
|
<artifactId>jjwt-jackson</artifactId>
|
||||||
<version>0.11.5</version>
|
<version>0.11.5</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>jakarta.validation</groupId>
|
<groupId>jakarta.validation</groupId>
|
||||||
<artifactId>jakarta.validation-api</artifactId>
|
<artifactId>jakarta.validation-api</artifactId>
|
||||||
@@ -140,6 +136,37 @@
|
|||||||
<version>0.23.0</version>
|
<version>0.23.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-saml2-service-provider -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.security</groupId>
|
||||||
|
<artifactId>spring-security-saml2-service-provider</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.opensaml/opensaml-core -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.opensaml</groupId>
|
||||||
|
<artifactId>opensaml-core</artifactId>
|
||||||
|
<version>4.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.opensaml/opensaml-saml-api -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.opensaml</groupId>
|
||||||
|
<artifactId>opensaml-saml-api</artifactId>
|
||||||
|
<version>4.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.opensaml/opensaml-saml-impl -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.opensaml</groupId>
|
||||||
|
<artifactId>opensaml-saml-impl</artifactId>
|
||||||
|
<version>4.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.cloud</groupId>
|
<groupId>org.springframework.cloud</groupId>
|
||||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||||
@@ -158,7 +185,6 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.liquibase</groupId>
|
<groupId>org.liquibase</groupId>
|
||||||
<artifactId>liquibase-maven-plugin</artifactId>
|
<artifactId>liquibase-maven-plugin</artifactId>
|
||||||
<version>4.20.0</version>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<propertyFile>src/main/resources/application.properties</propertyFile>
|
<propertyFile>src/main/resources/application.properties</propertyFile>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|||||||
@@ -1,6 +1,18 @@
|
|||||||
package net.gepafin.tendermanagement.config;
|
package net.gepafin.tendermanagement.config;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.security.KeyFactory;
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
import java.security.cert.CertificateFactory;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.security.spec.PKCS8EncodedKeySpec;
|
||||||
|
import org.bouncycastle.util.io.pem.PemReader;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
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.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
@@ -14,6 +26,11 @@ import org.springframework.security.config.annotation.web.configurers.AbstractHt
|
|||||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.security.saml2.core.Saml2X509Credential;
|
||||||
|
import org.springframework.security.saml2.provider.service.registration.InMemoryRelyingPartyRegistrationRepository;
|
||||||
|
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
|
||||||
|
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
|
||||||
|
import org.springframework.security.saml2.provider.service.registration.Saml2MessageBinding;
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
|
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
|
||||||
@@ -23,6 +40,8 @@ import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
|||||||
import org.springframework.web.filter.CorsFilter;
|
import org.springframework.web.filter.CorsFilter;
|
||||||
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
|
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
import io.swagger.v3.oas.models.Components;
|
import io.swagger.v3.oas.models.Components;
|
||||||
import io.swagger.v3.oas.models.OpenAPI;
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
import io.swagger.v3.oas.models.security.SecurityRequirement;
|
import io.swagger.v3.oas.models.security.SecurityRequirement;
|
||||||
@@ -30,24 +49,29 @@ import io.swagger.v3.oas.models.security.SecurityScheme;
|
|||||||
import io.swagger.v3.oas.models.servers.Server;
|
import io.swagger.v3.oas.models.servers.Server;
|
||||||
import net.gepafin.tendermanagement.config.jwt.JWTFilter;
|
import net.gepafin.tendermanagement.config.jwt.JWTFilter;
|
||||||
import net.gepafin.tendermanagement.config.jwt.TokenProvider;
|
import net.gepafin.tendermanagement.config.jwt.TokenProvider;
|
||||||
|
import net.gepafin.tendermanagement.entities.SamlResponseLogEntity;
|
||||||
|
import net.gepafin.tendermanagement.repositories.SamlResponseLogRepository;
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
@EnableMethodSecurity(prePostEnabled = true)
|
@EnableMethodSecurity(prePostEnabled = true)
|
||||||
public class SecurityConfig {
|
public class SecurityConfig {
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
|
||||||
private final TokenProvider tokenProvider;
|
private final TokenProvider tokenProvider;
|
||||||
|
|
||||||
|
@Value("${base-url}")
|
||||||
|
String baseUrl;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SamlResponseLogRepository samlResponseLogRepository;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public SecurityConfig(TokenProvider tokenProvider) {
|
public SecurityConfig(TokenProvider tokenProvider) {
|
||||||
this.tokenProvider = tokenProvider;
|
this.tokenProvider = tokenProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
|
public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
|
||||||
return config.getAuthenticationManager();
|
return config.getAuthenticationManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public PasswordEncoder passwordEncoder() {
|
public PasswordEncoder passwordEncoder() {
|
||||||
return new BCryptPasswordEncoder();
|
return new BCryptPasswordEncoder();
|
||||||
@@ -75,8 +99,8 @@ public class SecurityConfig {
|
|||||||
|
|
||||||
CorsConfiguration config = new CorsConfiguration();
|
CorsConfiguration config = new CorsConfiguration();
|
||||||
config.addAllowedOrigin("*");
|
config.addAllowedOrigin("*");
|
||||||
config.addAllowedMethod("*");
|
config.addAllowedMethod("*");
|
||||||
config.addAllowedHeader("*");
|
config.addAllowedHeader("*");
|
||||||
config.setMaxAge(3600l);
|
config.setMaxAge(3600l);
|
||||||
|
|
||||||
if (config.getAllowedOrigins() != null && !config.getAllowedOrigins().isEmpty()) {
|
if (config.getAllowedOrigins() != null && !config.getAllowedOrigins().isEmpty()) {
|
||||||
@@ -86,24 +110,91 @@ public class SecurityConfig {
|
|||||||
}
|
}
|
||||||
return new CorsFilter(source);
|
return new CorsFilter(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public SecurityFilterChain securityFilterChain(HttpSecurity http, MvcRequestMatcher.Builder mvc) throws Exception {
|
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||||
http
|
http.csrf(AbstractHttpConfigurer::disable).authorizeHttpRequests(auth -> auth
|
||||||
.csrf(AbstractHttpConfigurer::disable)
|
// Allow public access to the login endpoints
|
||||||
.authorizeHttpRequests(auth -> auth
|
.requestMatchers("/v1/user/login").permitAll() // JWT-based login
|
||||||
.requestMatchers(mvc.pattern(HttpMethod.POST, "/v1/user/login")).permitAll()
|
.requestMatchers("/v1/saml/**").permitAll() // JWT-based login
|
||||||
.requestMatchers("/swagger-ui/**").permitAll()
|
.requestMatchers("/saml2/**").permitAll() // SAML login initiation
|
||||||
.requestMatchers("/v1/api-docs/**").permitAll()
|
.requestMatchers("/swagger-ui/**").permitAll() // Swagger docs
|
||||||
.anyRequest().authenticated()
|
.requestMatchers("/v1/api-docs/**").permitAll() // API docs
|
||||||
)
|
.anyRequest().authenticated())
|
||||||
.sessionManagement(session -> session
|
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||||
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
|
||||||
)
|
|
||||||
.addFilterBefore(corsFilter(), UsernamePasswordAuthenticationFilter.class)
|
.addFilterBefore(corsFilter(), UsernamePasswordAuthenticationFilter.class)
|
||||||
.addFilterBefore(new JWTFilter(tokenProvider), 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((request, response, authentication) -> {
|
||||||
|
logger.error("SAML success login");
|
||||||
|
SamlResponseLogEntity samlResponseLogEntity = new SamlResponseLogEntity();
|
||||||
|
samlResponseLogEntity.setRequest(request.toString());
|
||||||
|
samlResponseLogEntity.setResponse(response.toString());
|
||||||
|
samlResponseLogEntity.setAuthenticationObject(authentication.toString());
|
||||||
|
samlResponseLogRepository.save(samlResponseLogEntity);
|
||||||
|
try {
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
// Create a new SAML log entity
|
||||||
|
SamlResponseLogEntity samlResponseLogEntity1 = new SamlResponseLogEntity();
|
||||||
|
|
||||||
|
// Convert request, response, and authentication to JSON format
|
||||||
|
String requestJson = objectMapper.writeValueAsString(request.getParameterMap()); // Assuming request params to JSON
|
||||||
|
String responseJson = objectMapper.writeValueAsString(response); // This may need to be adapted based on your response object
|
||||||
|
String authenticationJson = objectMapper.writeValueAsString(authentication); // Authentication object to JSON
|
||||||
|
|
||||||
|
// Set the JSON strings in the entity
|
||||||
|
samlResponseLogEntity1.setRequest(requestJson);
|
||||||
|
samlResponseLogEntity1.setResponse(responseJson);
|
||||||
|
samlResponseLogEntity1.setAuthenticationObject(authenticationJson);
|
||||||
|
samlResponseLogRepository.save(samlResponseLogEntity1);
|
||||||
|
|
||||||
|
logger.info("SAML Request: " + requestJson);
|
||||||
|
logger.info("SAML Response: " + responseJson);
|
||||||
|
logger.info("Authentication Details: " + authenticationJson);
|
||||||
|
}catch(Exception e) {
|
||||||
|
logger.info("Exception object" + e);
|
||||||
|
}
|
||||||
|
// samlResponseLogRepository
|
||||||
|
logger.info("SAML login successful for user: " + authentication.getName());
|
||||||
|
response.sendRedirect("http://gepafin-staging-fe.s3-website.eu-central-1.amazonaws.com/");
|
||||||
|
}).failureHandler((request, response, exception) -> {
|
||||||
|
logger.error("SAML login failed: " + exception.getMessage());
|
||||||
|
|
||||||
|
SamlResponseLogEntity samlResponseLogEntity = new SamlResponseLogEntity();
|
||||||
|
samlResponseLogEntity.setRequest(request.toString());
|
||||||
|
samlResponseLogEntity.setResponse(response.toString());
|
||||||
|
samlResponseLogEntity.setExceptionObject(exception.toString());
|
||||||
|
samlResponseLogRepository.save(samlResponseLogEntity);
|
||||||
|
try {
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
// Create a new SAML log entity
|
||||||
|
SamlResponseLogEntity samlResponseLogEntity1 = new SamlResponseLogEntity();
|
||||||
|
|
||||||
|
// Convert request, response, and authentication to JSON format
|
||||||
|
String requestJson = objectMapper.writeValueAsString(request.getParameterMap()); // Assuming request params to JSON
|
||||||
|
String responseJson = objectMapper.writeValueAsString(response); // This may need to be adapted based on your response object
|
||||||
|
String exceptionJson = objectMapper.writeValueAsString(exception); // Authentication object to JSON
|
||||||
|
|
||||||
|
// Set the JSON strings in the entity
|
||||||
|
samlResponseLogEntity1.setRequest(requestJson);
|
||||||
|
samlResponseLogEntity1.setResponse(responseJson);
|
||||||
|
samlResponseLogEntity1.setAuthenticationObject(exceptionJson);
|
||||||
|
samlResponseLogRepository.save(samlResponseLogEntity1);
|
||||||
|
|
||||||
|
logger.info("SAML Request: " + requestJson);
|
||||||
|
logger.info("SAML Response: " + responseJson);
|
||||||
|
logger.info("exception Details: " + exceptionJson);
|
||||||
|
}catch(Exception e) {
|
||||||
|
logger.info("Exception object" + e);
|
||||||
|
}
|
||||||
|
response.sendRedirect("http://gepafin-staging-fe.s3-website.eu-central-1.amazonaws.com/login");
|
||||||
|
}));
|
||||||
return http.build();
|
return http.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,4 +207,51 @@ public class SecurityConfig {
|
|||||||
new SecurityScheme().type(SecurityScheme.Type.HTTP)
|
new SecurityScheme().type(SecurityScheme.Type.HTTP)
|
||||||
.scheme("bearer").bearerFormat("JWT")));
|
.scheme("bearer").bearerFormat("JWT")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RelyingPartyRegistrationRepository relyingPartyRegistrationRepository() {
|
||||||
|
|
||||||
|
String entityId = baseUrl + "/v1/saml/gw/metadata";
|
||||||
|
String acsUrl = baseUrl + "/login/saml2/sso/loginumbria";
|
||||||
|
RelyingPartyRegistration registration = RelyingPartyRegistration.withRegistrationId("loginumbria")
|
||||||
|
.entityId(entityId)
|
||||||
|
.signingX509Credentials(credentials -> {
|
||||||
|
try {
|
||||||
|
credentials.add(Saml2X509Credential.signing(readPrivateKey(), readCertificate()));
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.assertionConsumerServiceLocation(acsUrl)
|
||||||
|
.assertingPartyDetails(details -> details.entityId("https://federatest.umbriadigitale.it/gw/metadata")
|
||||||
|
.singleSignOnServiceLocation("https://federatest.umbriadigitale.it/gw/SSOProxy/SAML2")
|
||||||
|
.singleSignOnServiceBinding(Saml2MessageBinding.POST).wantAuthnRequestsSigned(false)
|
||||||
|
)
|
||||||
|
.build();
|
||||||
|
return new InMemoryRelyingPartyRegistrationRepository(registration);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public PrivateKey readPrivateKey() throws Exception {
|
||||||
|
// Path to your private key PEM file
|
||||||
|
File privateKeyFile = new File("src/main/resources/dev/saml/private-key.pem");
|
||||||
|
try (PemReader pemReader = new PemReader(new FileReader(privateKeyFile))) {
|
||||||
|
// Read the PEM content
|
||||||
|
byte[] pemContent = pemReader.readPemObject().getContent();
|
||||||
|
// Decode the PEM content
|
||||||
|
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pemContent);
|
||||||
|
KeyFactory keyFactory = KeyFactory.getInstance("RSA"); // Use RSA algorithm
|
||||||
|
// Generate and return the PrivateKey
|
||||||
|
return keyFactory.generatePrivate(keySpec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public X509Certificate readCertificate() throws Exception {
|
||||||
|
// Path to your certificate PEM fileFile
|
||||||
|
File certFile = new File("src/main/resources/dev/saml/public-cert.pem");
|
||||||
|
try (InputStream inStream = new FileInputStream(certFile)) {
|
||||||
|
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
|
||||||
|
return (X509Certificate) certFactory.generateCertificate(inStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package net.gepafin.tendermanagement.entities;
|
||||||
|
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "SAML_RESPONSE_LOG")
|
||||||
|
@Data
|
||||||
|
public class SamlResponseLogEntity extends BaseEntity{
|
||||||
|
|
||||||
|
@Column(name = "REQUEST")
|
||||||
|
private String request;
|
||||||
|
|
||||||
|
@Column(name = "RESPONSE")
|
||||||
|
private String response;
|
||||||
|
|
||||||
|
@Column(name = "AUTHENTICATION_OBJECT")
|
||||||
|
private String authenticationObject;
|
||||||
|
|
||||||
|
@Column(name = "EXCEPTION_OBJECT")
|
||||||
|
private String exceptionObject;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package net.gepafin.tendermanagement.repositories;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import net.gepafin.tendermanagement.entities.SamlResponseLogEntity;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface SamlResponseLogRepository extends JpaRepository<SamlResponseLogEntity, Long> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package net.gepafin.tendermanagement.web.rest.api;
|
||||||
|
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Content;
|
||||||
|
import io.swagger.v3.oas.annotations.media.ExampleObject;
|
||||||
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants;
|
||||||
|
|
||||||
|
public interface SamlApi {
|
||||||
|
|
||||||
|
|
||||||
|
@Operation(summary = "Api to get SP metadata",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "200", description = "OK"),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||||
|
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })),
|
||||||
|
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||||
|
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })),
|
||||||
|
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||||
|
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) })
|
||||||
|
@GetMapping(value = "/gw/metadata",
|
||||||
|
produces = { "application/json" })
|
||||||
|
ResponseEntity<String> getMetadata(HttpServletRequest request);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package net.gepafin.tendermanagement.web.rest.api.impl;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.security.saml2.provider.service.metadata.OpenSamlMetadataResolver;
|
||||||
|
import org.springframework.security.saml2.provider.service.metadata.Saml2MetadataResolver;
|
||||||
|
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
|
||||||
|
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import net.gepafin.tendermanagement.config.SecurityConfig;
|
||||||
|
import net.gepafin.tendermanagement.web.rest.api.SamlApi;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("${openapi.gepafin.base-path:/v1/saml}")
|
||||||
|
public class SamlApiController implements SamlApi{
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RelyingPartyRegistrationRepository relyingPartyRegistrationRepository;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResponseEntity<String> getMetadata(HttpServletRequest request) {
|
||||||
|
logger.info("get SP metadata");
|
||||||
|
Saml2MetadataResolver metadataResolver = new OpenSamlMetadataResolver();
|
||||||
|
RelyingPartyRegistration registration = relyingPartyRegistrationRepository.findByRegistrationId("loginumbria");
|
||||||
|
return ResponseEntity.status(HttpStatus.OK).header("Content-Type", MediaType.APPLICATION_XML_VALUE)
|
||||||
|
.body(metadataResolver.resolve(registration));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -6,5 +6,6 @@ spring.datasource.driver-class-name=org.postgresql.Driver
|
|||||||
|
|
||||||
# JPA Configuration
|
# JPA Configuration
|
||||||
spring.h2.console.enabled=true
|
spring.h2.console.enabled=true
|
||||||
|
base-url=https://api-dev-gepafin.memento.credit
|
||||||
|
|
||||||
isVatCheckGloballyDisabled = false
|
isVatCheckGloballyDisabled = false
|
||||||
|
|||||||
@@ -6,3 +6,4 @@ spring.datasource.driver-class-name=org.postgresql.Driver
|
|||||||
|
|
||||||
# JPA Configuration
|
# JPA Configuration
|
||||||
spring.jpa.show-sql=true
|
spring.jpa.show-sql=true
|
||||||
|
base-url=http://localhost:8080
|
||||||
@@ -5,3 +5,4 @@ spring.datasource.password=sa
|
|||||||
|
|
||||||
# JPA Configuration
|
# JPA Configuration
|
||||||
spring.h2.console.enabled=true
|
spring.h2.console.enabled=true
|
||||||
|
base-url=http://localhost:8080
|
||||||
@@ -35,6 +35,7 @@ aws.s3.url.folder=gepafin
|
|||||||
# Ensure these values match your expectations
|
# Ensure these values match your expectations
|
||||||
security.authentication.jwt.secret=my-secret-token-to-change-in-prod-environment-your-super-secure-randomly-generated-key
|
security.authentication.jwt.secret=my-secret-token-to-change-in-prod-environment-your-super-secure-randomly-generated-key
|
||||||
security.authentication.jwt.token-validity-in-seconds=86400
|
security.authentication.jwt.token-validity-in-seconds=86400
|
||||||
|
base-url=https://api-dev-gepafin.memento.credit
|
||||||
|
|
||||||
|
|
||||||
spring.main.allow-circular-references=true
|
spring.main.allow-circular-references=true
|
||||||
|
|||||||
@@ -710,4 +710,30 @@
|
|||||||
<sqlFile dbms="postgresql"
|
<sqlFile dbms="postgresql"
|
||||||
path="classpath:db/dump/updated_form_field_data_16-09-2024.sql" />
|
path="classpath:db/dump/updated_form_field_data_16-09-2024.sql" />
|
||||||
</changeSet>
|
</changeSet>
|
||||||
|
|
||||||
|
<changeSet id="23-09-2024_1" author="Rajesh Khore">
|
||||||
|
<createTable tableName="saml_response_log">
|
||||||
|
<column name="id" type="INTEGER" autoIncrement="true">
|
||||||
|
</column>
|
||||||
|
|
||||||
|
<column name="request" type="TEXT">
|
||||||
|
</column>
|
||||||
|
|
||||||
|
<column name="response" type="TEXT">
|
||||||
|
</column>
|
||||||
|
|
||||||
|
<column name="authentication_object" type="TEXT">
|
||||||
|
</column>
|
||||||
|
|
||||||
|
<column name="exception_object" type="TEXT">
|
||||||
|
</column>
|
||||||
|
|
||||||
|
<column name="created_date" type="TIMESTAMP WITHOUT TIME ZONE">
|
||||||
|
</column>
|
||||||
|
|
||||||
|
<column name="updated_date" type="TIMESTAMP WITHOUT TIME ZONE">
|
||||||
|
</column>
|
||||||
|
</createTable>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
||||||
|
|||||||
Reference in New Issue
Block a user