updated code
This commit is contained in:
@@ -29,6 +29,7 @@ import org.opensaml.xmlsec.signature.support.SignatureConstants;
|
||||
import org.opensaml.xmlsec.signature.support.Signer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
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;
|
||||
@@ -45,6 +46,9 @@ import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import net.gepafin.tendermanagement.entities.SamlResponseEntity;
|
||||
import net.gepafin.tendermanagement.enums.SamlResponseStatusEnum;
|
||||
import net.gepafin.tendermanagement.repositories.SamlResponseRepository;
|
||||
|
||||
@Configuration
|
||||
public class SamlConfig {
|
||||
@@ -59,6 +63,9 @@ public class SamlConfig {
|
||||
|
||||
@Value("${active.profile.folder}")
|
||||
String activeProfileFolder;
|
||||
|
||||
@Autowired
|
||||
private SamlResponseRepository samlResponseRepository;
|
||||
|
||||
@Bean
|
||||
public RelyingPartyRegistrationRepository relyingPartyRegistrationRepository() {
|
||||
@@ -135,18 +142,24 @@ public class SamlConfig {
|
||||
authenticationRequestResolver.setAuthnRequestCustomizer((context) -> {
|
||||
|
||||
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
|
||||
String hubId = (String) request.getAttribute("hubId");
|
||||
String hubUuid = (String) request.getAttribute("hubId");
|
||||
|
||||
logger.info("Hub id " + hubId);
|
||||
logger.info("Hub id " + hubUuid);
|
||||
String inResponseTo = "_" + UUID.randomUUID().toString();
|
||||
|
||||
// Continue with normal AuthnRequest configuration
|
||||
AuthnRequest authnRequest = context.getAuthnRequest();
|
||||
authnRequest.setID("_" + UUID.randomUUID().toString()+":"+hubId);
|
||||
authnRequest.setID(inResponseTo);
|
||||
authnRequest.setVersion(SAMLVersion.VERSION_20);
|
||||
authnRequest.setProtocolBinding(SAMLConstants.SAML2_POST_BINDING_URI);
|
||||
authnRequest.setRequestedAuthnContext(buildRequestedAuthnContext());
|
||||
|
||||
|
||||
|
||||
SamlResponseEntity samlResponse = new SamlResponseEntity();
|
||||
samlResponse.setHubUuid(hubUuid);
|
||||
samlResponse.setInResponseTo(inResponseTo);
|
||||
samlResponse.setStatus(SamlResponseStatusEnum.INITIATED.getValue());
|
||||
samlResponseRepository.save(samlResponse);
|
||||
// Log the SAML AuthnRequest after setting context
|
||||
String samlRequest = SamlRequestLogger.convertSAMLObjectToString(authnRequest);
|
||||
logger.info("SAML AuthnRequest after setting context: " + samlRequest);
|
||||
@@ -156,21 +169,21 @@ public class SamlConfig {
|
||||
}
|
||||
|
||||
|
||||
private RequestedAuthnContext buildRequestedAuthnContext() {
|
||||
AuthnContextClassRefBuilder authnContextClassRefBuilder = new AuthnContextClassRefBuilder();
|
||||
AuthnContextClassRef authnContextClassRef = authnContextClassRefBuilder.buildObject(
|
||||
SAMLConstants.SAML20_NS, AuthnContextClassRef.DEFAULT_ELEMENT_LOCAL_NAME, SAMLConstants.SAML20_PREFIX
|
||||
);
|
||||
// Set the SPID Level 2 authentication context
|
||||
authnContextClassRef.setURI("urn:oasis:names:tc:SAML:2.0:ac:classes:SecureRemotePassword");
|
||||
|
||||
RequestedAuthnContextBuilder requestedAuthnContextBuilder = new RequestedAuthnContextBuilder();
|
||||
RequestedAuthnContext requestedAuthnContext = requestedAuthnContextBuilder.buildObject();
|
||||
requestedAuthnContext.setComparison(AuthnContextComparisonTypeEnumeration.EXACT);
|
||||
requestedAuthnContext.getAuthnContextClassRefs().add(authnContextClassRef);
|
||||
|
||||
return requestedAuthnContext;
|
||||
}
|
||||
private RequestedAuthnContext buildRequestedAuthnContext() {
|
||||
AuthnContextClassRefBuilder authnContextClassRefBuilder = new AuthnContextClassRefBuilder();
|
||||
AuthnContextClassRef authnContextClassRef = authnContextClassRefBuilder.buildObject(
|
||||
SAMLConstants.SAML20_NS, AuthnContextClassRef.DEFAULT_ELEMENT_LOCAL_NAME, SAMLConstants.SAML20_PREFIX
|
||||
);
|
||||
// Set the SPID Level 2 authentication context
|
||||
authnContextClassRef.setURI("urn:oasis:names:tc:SAML:2.0:ac:classes:SecureRemotePassword");
|
||||
|
||||
RequestedAuthnContextBuilder requestedAuthnContextBuilder = new RequestedAuthnContextBuilder();
|
||||
RequestedAuthnContext requestedAuthnContext = requestedAuthnContextBuilder.buildObject();
|
||||
requestedAuthnContext.setComparison(AuthnContextComparisonTypeEnumeration.EXACT);
|
||||
requestedAuthnContext.getAuthnContextClassRefs().add(authnContextClassRef);
|
||||
|
||||
return requestedAuthnContext;
|
||||
}
|
||||
|
||||
public PrivateKey readPrivateKey() throws Exception {
|
||||
// Path to your private key PEM file
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
package net.gepafin.tendermanagement.config;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
|
||||
@@ -11,6 +15,12 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import net.gepafin.tendermanagement.constants.GepafinConstant;
|
||||
import net.gepafin.tendermanagement.entities.SamlResponseEntity;
|
||||
import net.gepafin.tendermanagement.enums.SamlResponseStatusEnum;
|
||||
import net.gepafin.tendermanagement.repositories.SamlResponseRepository;
|
||||
import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException;
|
||||
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
|
||||
|
||||
@Component
|
||||
public class SamlFailureHandler implements AuthenticationFailureHandler {
|
||||
@@ -20,16 +30,40 @@ public class SamlFailureHandler implements AuthenticationFailureHandler {
|
||||
@Value("${fe.base.url}")
|
||||
private String feBaseUrl;
|
||||
|
||||
@Autowired
|
||||
private SamlResponseRepository samlResponseRepository;
|
||||
|
||||
@Override
|
||||
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException exception) throws IOException {
|
||||
try {
|
||||
logger.error("SAML login failed: " + exception.getMessage());
|
||||
|
||||
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException exception) throws IOException {
|
||||
try {
|
||||
logger.error("SAML login failed: " + exception.getMessage());
|
||||
String inResponseTo = extractInResponseTo(feBaseUrl);
|
||||
if (Boolean.FALSE.equals(StringUtils.isEmpty(inResponseTo))) {
|
||||
SamlResponseEntity samlResponseLogEntity = samlResponseRepository
|
||||
.findByInResponseToAndStatus(inResponseTo, SamlResponseStatusEnum.INITIATED.getValue())
|
||||
.orElseThrow(() -> new CustomValidationException(Status.BAD_REQUEST,
|
||||
Translator.toLocale(GepafinConstant.INVALID_REQUEST)));
|
||||
samlResponseLogEntity.setStatus(SamlResponseStatusEnum.FAILED.getValue());
|
||||
samlResponseRepository.save(samlResponseLogEntity);
|
||||
}
|
||||
response.sendRedirect(feBaseUrl + "/login");
|
||||
} catch (Exception e) {
|
||||
logger.error("Error processing SAML failure handler", e);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Error processing SAML failure handler", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String extractInResponseTo(String message) {
|
||||
String regex = "InResponseTo attribute \\[([a-zA-Z0-9\\-]+)\\]";
|
||||
|
||||
Pattern pattern = Pattern.compile(regex);
|
||||
Matcher matcher = pattern.matcher(message);
|
||||
|
||||
if (matcher.find()) {
|
||||
return matcher.group(1);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,13 +2,13 @@ package net.gepafin.tendermanagement.config;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -26,10 +26,13 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import net.gepafin.tendermanagement.constants.GepafinConstant;
|
||||
import net.gepafin.tendermanagement.entities.HubEntity;
|
||||
import net.gepafin.tendermanagement.entities.SamlResponseEntity;
|
||||
import net.gepafin.tendermanagement.entities.UserEntity;
|
||||
import net.gepafin.tendermanagement.enums.SamlResponseStatusEnum;
|
||||
import net.gepafin.tendermanagement.repositories.SamlResponseRepository;
|
||||
import net.gepafin.tendermanagement.repositories.UserRepository;
|
||||
import net.gepafin.tendermanagement.service.HubService;
|
||||
import net.gepafin.tendermanagement.util.Utils;
|
||||
import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException;
|
||||
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
|
||||
@@ -47,6 +50,9 @@ public class SamlSuccessHandler implements AuthenticationSuccessHandler {
|
||||
|
||||
@Value("${fe.base.url}")
|
||||
private String feBaseUrl;
|
||||
|
||||
@Autowired
|
||||
private HubService hubService;
|
||||
|
||||
@Override
|
||||
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
|
||||
@@ -59,16 +65,6 @@ public class SamlSuccessHandler implements AuthenticationSuccessHandler {
|
||||
Map<String, List<Object>> userAttributes = principal.getAttributes();
|
||||
String token = Utils.generateSecureToken();
|
||||
logger.info("SAML User Attributes: " + userAttributes);
|
||||
|
||||
SamlResponseEntity samlResponseLogEntity = new SamlResponseEntity();
|
||||
samlResponseLogEntity.setAuthenticationObject(authentication.toString());
|
||||
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
String userAttributesJson = objectMapper.writeValueAsString(userAttributes);
|
||||
samlResponseLogEntity.setAuthenticationObject(userAttributesJson);
|
||||
samlResponseLogEntity.setToken(token);
|
||||
samlResponseLogRepository.save(samlResponseLogEntity);
|
||||
|
||||
|
||||
// Extracting raw SAML response
|
||||
String samlResponse = samlAuth.getSaml2Response();
|
||||
@@ -89,8 +85,28 @@ public class SamlSuccessHandler implements AuthenticationSuccessHandler {
|
||||
logger.info("SAML Response ID: " + responseId);
|
||||
logger.info("InResponseTo: " + inResponseTo);
|
||||
logger.info("IssueInstant: " + issueInstant);
|
||||
|
||||
SamlResponseEntity samlResponseLogEntity = samlResponseLogRepository
|
||||
.findByInResponseToAndStatus(inResponseTo, SamlResponseStatusEnum.INITIATED.getValue())
|
||||
.orElseThrow(() -> new CustomValidationException(Status.BAD_REQUEST,
|
||||
Translator.toLocale(GepafinConstant.INVALID_REQUEST)));
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
String userAttributesJson = objectMapper.writeValueAsString(userAttributes);
|
||||
|
||||
samlResponseLogEntity.setAuthenticationObject(userAttributesJson);
|
||||
samlResponseLogEntity.setToken(token);
|
||||
samlResponseLogEntity.setStatus(SamlResponseStatusEnum.SUCCESS.getValue());
|
||||
samlResponseLogEntity.setInResponseTo(inResponseTo);
|
||||
samlResponseLogEntity.setSamlId(responseId);
|
||||
samlResponseLogEntity.setIssueInstant(issueInstant);
|
||||
samlResponseLogRepository.save(samlResponseLogEntity);
|
||||
|
||||
HubEntity hub = hubService.getHubByUuid(samlResponseLogEntity.getHubUuid());
|
||||
|
||||
String redirectUrl = feBaseUrl;
|
||||
if (Boolean.FALSE.equals(StringUtils.isEmpty(hub.getDomainName()))) {
|
||||
redirectUrl = hub.getDomainName();
|
||||
}
|
||||
|
||||
logger.info("SAML login successful for user: " + principal.getName());
|
||||
String cf = userAttributes.get("CodiceFiscale").get(0).toString();
|
||||
|
||||
Reference in New Issue
Block a user