Commit 997d5e5d by GulnazS

Update /forward

parent 0f52c5d6
{
"permissions": {
"allow": [
"Bash(./gradlew clean build:*)"
],
"deny": [],
"ask": []
}
}
This diff is collapsed. Click to expand it.
...@@ -67,4 +67,9 @@ dependencies { ...@@ -67,4 +67,9 @@ dependencies {
// https://mvnrepository.com/artifact/org.apache.commons/commons-text // https://mvnrepository.com/artifact/org.apache.commons/commons-text
implementation("org.apache.commons:commons-text:1.14.0") implementation("org.apache.commons:commons-text:1.14.0")
implementation("org.apache.santuario:xmlsec:2.1.8")
implementation fileTree(dir: 'libs', includes: ['kalkancrypt-xmldsig-0.5.jar',
'knca_provider_jce_kalkan-0.7.5.jar',
'knca_provider_util-0.8.5.jar'])
} }
\ No newline at end of file
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header/>
<soap:Body>
<SendMessage xmlns:ns2="http://bip.bee.kz/common/v10/Types" xmlns:ns3="http://bip.bee.kz/SyncChannel/v10/Types"
xmlns="http://bip.bee.kz/SyncChannel/v10/Types">
<request xmlns="">
<requestInfo>
<messageId>0471901f-9bb6-4409-bba0-196c90396052</messageId>
<serviceId>nca_iiscon</serviceId>
<messageDate>2025-11-17T11:50:52.665+05:00</messageDate>
<sender>
<senderId>EISDS</senderId>
<password>8zDV~U4OUo</password>
</sender>
</requestInfo>
<requestData>
<data xmlns:s01="http://pki.gov.kz/api/ws/iiscon/wsdl"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="s01:SearchOrderByReferenceNumberRequest">
<s01:referenceNumber>14423463151114</s01:referenceNumber>
</data>
</requestData>
</request>
</SendMessage>
</soap:Body>
</soap:Envelope>
\ No newline at end of file
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Header/><soap:Body><SendMessage xmlns:ns2="http://bip.bee.kz/common/v10/Types" xmlns:ns3="http://bip.bee.kz/SyncChannel/v10/Types" xmlns="http://bip.bee.kz/SyncChannel/v10/Types"><request xmlns=""><requestInfo><messageId>7454d15b-266d-428e-9a11-f28b6ca72be5</messageId><serviceId>nca_iiscon</serviceId><messageDate>2025-11-12T16:57:16.968+05:00</messageDate><sender><senderId>EISDS</senderId><password>8zDV~U4OUo</password></sender></requestInfo><requestData><data xmlns:s01="http://pki.gov.kz/api/ws/iiscon/wsdl" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="s01:SearchOrderByReferenceNumberRequest"><s01:referenceNumber>12687611151112</s01:referenceNumber></data></requestData></request></SendMessage></soap:Body></soap:Envelope>
\ No newline at end of file
...@@ -3,14 +3,25 @@ package kz.arta.nca_iiscon.controller; ...@@ -3,14 +3,25 @@ package kz.arta.nca_iiscon.controller;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import kz.arta.nca_iiscon.data.forward.ForwardApplication; import kz.arta.nca_iiscon.data.forward.ForwardApplication;
import kz.arta.nca_iiscon.data.search.SearchOrderByReferenceNumberRequest; import kz.arta.nca_iiscon.data.search.SearchOrderByReferenceNumberRequest;
import kz.arta.nca_iiscon.data.search.SearchOrderRequestWrapper;
import kz.arta.nca_iiscon.service.ForwardApplicationNcaService; import kz.arta.nca_iiscon.service.ForwardApplicationNcaService;
import kz.arta.nca_iiscon.service.NcaIISConService; import kz.arta.nca_iiscon.service.NcaIISConService;
import kz.arta.nca_iiscon.service.RestService;
import kz.arta.nca_iiscon.util.XmlToJsonUtil; import kz.arta.nca_iiscon.util.XmlToJsonUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.IIOImage;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Base64;
@Slf4j @Slf4j
@ResponseBody @ResponseBody
...@@ -25,17 +36,36 @@ public class NcaIISConController { ...@@ -25,17 +36,36 @@ public class NcaIISConController {
private final ObjectMapper objectMapper = new ObjectMapper(); private final ObjectMapper objectMapper = new ObjectMapper();
private final RestService restService;
@PostMapping(value = "/iiscon", produces = MediaType.APPLICATION_JSON_VALUE) @PostMapping(value = "/iiscon", produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody Object getSearchOrderByReferenceNumber(@RequestBody SearchOrderByReferenceNumberRequest request public @ResponseBody Object getSearchOrderByReferenceNumber(@RequestPart(value = "data") String dataJson,
@RequestPart(value = "file", required = false) MultipartFile file
) throws Exception { ) throws Exception {
SearchOrderRequestWrapper wrapper = objectMapper.readValue(dataJson, SearchOrderRequestWrapper.class);
SearchOrderByReferenceNumberRequest request = wrapper.getRequest();
String savedPhoto = wrapper.getSavedPhoto();
String applicantNumber = wrapper.getApplicantNumber();
log.info("Received request with referenceNumber: {}", request.getReferenceNumber()); log.info("Received request with referenceNumber: {}", request.getReferenceNumber());
// Отправляем запрос и получаем ответ // Отправляем запрос и получаем ответ
Object response = service.sendRequest(request); Object response = service.sendRequestByTemplate(request);
log.info("SHEP Response {}", response); log.info("SHEP Response {}", response);
return XmlToJsonUtil.extractDataAsJson(response, true); String base64photo;
if (savedPhoto != null && !savedPhoto.isEmpty()) {
// Опция 1: base64 строка из JSON
if (savedPhoto.contains(",")) {
base64photo = savedPhoto.substring(savedPhoto.indexOf(",") + 1);
} else {
base64photo = savedPhoto;
}
} else if (file != null && !file.isEmpty()) {
// Опция 2: загруженный файл - конвертируем в JPEG и кодируем в base64
base64photo = convertImageToJpegBase64(file);
} else {
throw new IllegalArgumentException("Нет данных для фото: укажите savedPhoto (base64) или загрузите file");
}
return XmlToJsonUtil.extractDataAsJson(response, true, base64photo, applicantNumber);
} }
@PostMapping(value = "/forward", produces = MediaType.APPLICATION_JSON_VALUE) @PostMapping(value = "/forward", produces = MediaType.APPLICATION_JSON_VALUE)
...@@ -44,14 +74,105 @@ public class NcaIISConController { ...@@ -44,14 +74,105 @@ public class NcaIISConController {
) throws Exception { ) throws Exception {
// Отправляем запрос и получаем ответ // Отправляем запрос и получаем ответ
// Object response = forwardService.sendRequest(request);
Object response = forwardService.sendRequestByTemplate(request); Object response = forwardService.sendRequestByTemplate(request);
// Извлекаем data и конвертируем в JSON // Извлекаем data и конвертируем в JSON
String jsonResponse = XmlToJsonUtil.extractDataAsJson(response, false); String jsonResponse = XmlToJsonUtil.extractDataAsJson(response, false, null, null);
log.info("Converted response to JSON"); log.info("Converted response to JSON");
return jsonResponse; return jsonResponse;
} }
// /**
// * Конвертирует загруженный файл (любого формата) в JPEG и возвращает base64 строку
// */
private String convertImageToJpegBase64(MultipartFile file) throws Exception {
byte[] fileBytes = file.getBytes();
String contentType = file.getContentType();
String originalFilename = file.getOriginalFilename();
log.info("Processing file: {}, contentType: {}", originalFilename, contentType);
// Если файл уже в формате JPEG, просто кодируем в base64 без конвертации
if (contentType != null && (contentType.equals("image/jpeg") || contentType.equals("image/jpg"))) {
log.info("File is already JPEG, encoding without conversion");
return Base64.getEncoder().encodeToString(fileBytes);
}
try {
BufferedImage image = ImageIO.read(new ByteArrayInputStream(fileBytes));
if (image == null) {
log.warn("ImageIO could not read the image format. Returning raw base64. File may not be in JPEG format.");
return Base64.getEncoder().encodeToString(fileBytes);
}
// Изменяем размер изображения до 360x480 (сохраняя пропорции)
BufferedImage resizedImage = resizeImage(image, 360, 480);
BufferedImage jpegImage;
if (resizedImage.getType() == BufferedImage.TYPE_4BYTE_ABGR ||
resizedImage.getType() == BufferedImage.TYPE_INT_ARGB) {
jpegImage = new BufferedImage(resizedImage.getWidth(), resizedImage.getHeight(), BufferedImage.TYPE_INT_RGB);
jpegImage.createGraphics().drawImage(resizedImage, 0, 0, java.awt.Color.WHITE, null);
} else {
jpegImage = resizedImage;
}
// Конвертируем в JPEG с сжатием
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageWriter jpegWriter = ImageIO.getImageWritersByFormatName("jpg").next();
ImageWriteParam jpegParams = jpegWriter.getDefaultWriteParam();
jpegParams.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
jpegParams.setCompressionQuality(0.75f);
jpegWriter.setOutput(ImageIO.createImageOutputStream(outputStream));
jpegWriter.write(null, new IIOImage(jpegImage, null, null), jpegParams);
jpegWriter.dispose();
// Кодируем в base64
byte[] jpegBytes = outputStream.toByteArray();
return Base64.getEncoder().encodeToString(jpegBytes);
} catch (Exception e) {
log.error("Error converting image to JPEG: {}. Returning raw base64.", e.getMessage());
return Base64.getEncoder().encodeToString(fileBytes);
}
}
/**
* Изменяет размер изображения, сохраняя пропорции, чтобы уместиться в заданные максимальные размеры
*/
private BufferedImage resizeImage(BufferedImage originalImage, int maxWidth, int maxHeight) {
int originalWidth = originalImage.getWidth();
int originalHeight = originalImage.getHeight();
// Вычисляем новые размеры, сохраняя пропорции
double widthRatio = (double) maxWidth / originalWidth;
double heightRatio = (double) maxHeight / originalHeight;
double ratio = Math.min(widthRatio, heightRatio);
int newWidth = (int) (originalWidth * ratio);
int newHeight = (int) (originalHeight * ratio);
// Если изображение уже меньше максимальных размеров, возвращаем оригинал
if (ratio >= 1.0) {
return originalImage;
}
// Создаем новое изображение с уменьшенными размерами
BufferedImage resizedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g = resizedImage.createGraphics();
// Настраиваем качество ресайза
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.drawImage(originalImage, 0, 0, newWidth, newHeight, null);
g.dispose();
return resizedImage;
}
} }
\ No newline at end of file
...@@ -12,4 +12,7 @@ public class Data { ...@@ -12,4 +12,7 @@ public class Data {
@XmlElement(name = "confirmOrder") @XmlElement(name = "confirmOrder")
private ConfirmOrder confirmOrder; private ConfirmOrder confirmOrder;
@XmlElement(name = "confirmOrder")
private ConfirmOrder denyOrder;
} }
package kz.arta.nca_iiscon.data.search;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class SearchOrderRequestWrapper {
private SearchOrderByReferenceNumberRequest request;
private String savedPhoto;
private String applicantNumber;
}
package kz.arta.nca_iiscon.service;
import lombok.extern.slf4j.Slf4j;
import javax.xml.namespace.QName;
import javax.xml.soap.*;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import java.io.ByteArrayOutputStream;
import java.util.Iterator;
import java.util.Set;
@Slf4j
public class CustomSOAPHandler implements SOAPHandler<SOAPMessageContext> {
@Override
public boolean handleMessage(SOAPMessageContext context) {
Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outboundProperty) {
try {
SOAPMessage soapMessage = context.getMessage();
SOAPEnvelope envelope = soapMessage.getSOAPPart().getEnvelope();
// Устанавливаем правильный порядок namespace в envelope
envelope.removeNamespaceDeclaration("SOAP-ENV");
envelope.removeNamespaceDeclaration("wsu");
envelope.removeNamespaceDeclaration("xsd");
// Добавляем в правильном порядке
envelope.addNamespaceDeclaration("xsd", "http://www.w3.org/2001/XMLSchema");
envelope.addNamespaceDeclaration("SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/");
envelope.addNamespaceDeclaration("wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
// Убеждаемся, что есть Header
SOAPHeader header = envelope.getHeader();
if (header == null) {
envelope.addHeader();
}
SOAPBody body = envelope.getBody();
// Находим элемент SendMessage
SOAPElement sendMessage = (SOAPElement) body.getChildElements(
new QName("http://bip.bee.kz/SyncChannel/v10/Types", "SendMessage")
).next();
if (sendMessage != null) {
// Удаляем лишние namespace из SendMessage
sendMessage.removeNamespaceDeclaration("ns4");
sendMessage.removeNamespaceDeclaration("ns5");
sendMessage.removeNamespaceDeclaration("s01");
sendMessage.removeNamespaceDeclaration("xsi");
// SendMessage должен остаться без префикса
sendMessage.setPrefix("");
// Находим request
SOAPElement request = (SOAPElement) sendMessage.getChildElements(
new QName("", "request")
).next();
if (request != null) {
request.setAttribute("xmlns", "");
// Обрабатываем data элемент
processDataElement(request);
}
}
soapMessage.saveChanges();
// Логируем финальное сообщение
if (log.isInfoEnabled()) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
soapMessage.writeTo(out);
log.info("Outbound SOAP Message:\n{}", out.toString("UTF-8"));
}
} catch (Exception e) {
log.error("Error in SOAP Handler", e);
}
}
return true;
}
private void processDataElement(SOAPElement parent) throws SOAPException {
// Рекурсивно проходим по всем элементам
Iterator iterator = parent.getChildElements();
while (iterator.hasNext()) {
Object obj = iterator.next();
if (obj instanceof SOAPElement) {
SOAPElement element = (SOAPElement) obj;
// Если это data элемент
if ("data".equals(element.getLocalName())) {
// Убираем префикс s01 у data
element.setPrefix("");
// Добавляем xmlns:xsi и xmlns:s01
element.addNamespaceDeclaration("xsi", "http://www.w3.org/2001/XMLSchema-instance");
element.addNamespaceDeclaration("s01", "http://pki.gov.kz/api/ws/iiscon/wsdl");
// Устанавливаем xsi:type
element.setAttributeNS(
"http://www.w3.org/2001/XMLSchema-instance",
"xsi:type",
"s01:SearchOrderByReferenceNumberRequest"
);
}
// Меняем префикс на s01 для всех дочерних элементов из namespace http://pki.gov.kz/api/ws/iiscon/wsdl
String namespaceURI = element.getNamespaceURI();
if ("http://pki.gov.kz/api/ws/iiscon/wsdl".equals(namespaceURI)) {
element.setPrefix("s01");
}
// Рекурсивно обрабатываем детей
processDataElement(element);
}
}
}
@Override
public boolean handleFault(SOAPMessageContext context) {
return true;
}
@Override
public void close(MessageContext context) {
}
@Override
public Set<QName> getHeaders() {
return null;
}
}
\ No newline at end of file
package kz.arta.nca_iiscon.service; package kz.arta.nca_iiscon.service;
import kz.arta.nca_iiscon.data.forward.ForwardApplication; import kz.arta.nca_iiscon.data.forward.ForwardApplication;
import kz.arta.nca_iiscon.data.search.SearchOrderByReferenceNumberRequest; import kz.arta.nca_iiscon.data.forward.UpdateApplication;
import kz.arta.nca_iiscon.data.forward.application.ApplicationData;
import kz.arta.nca_iiscon.data.forward.application.ConfirmOrder;
import kz.arta.nca_iiscon.data.forward.application.Data;
import kz.arta.nca_iiscon.shep.*; import kz.arta.nca_iiscon.shep.*;
import kz.arta.nca_iiscon.util.SignerUtil;
import kz.arta.nca_iiscon.util.XmlTemplateBuilder; import kz.arta.nca_iiscon.util.XmlTemplateBuilder;
import kz.arta.nca_iiscon.util.XmlToJsonUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.xml.bind.*; import javax.xml.bind.*;
import javax.xml.datatype.DatatypeConfigurationException; import java.io.File;
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.handler.Handler;
import java.io.StringWriter;
import java.util.*; import java.util.*;
import java.util.function.Consumer;
@Slf4j @Slf4j
@Service @Service
...@@ -28,44 +30,43 @@ public class ForwardApplicationNcaService { ...@@ -28,44 +30,43 @@ public class ForwardApplicationNcaService {
private String serviceIdSHEP; private String serviceIdSHEP;
@Value("${service_url}") @Value("${service_url}")
private String urlSHEP; private String urlSHEP;
@Value("${service_url}") @Value("${eds_path}")
private String keyFile; private String keyFile;
@Value("${eds_password}")
private String keyPassword;
@Autowired @Autowired
private RestService restService; private RestService restService;
public String sendRequestByTemplate(ForwardApplication forwardApplication) throws Exception {
String request;
public Object sendRequest(ForwardApplication request) throws Exception {
try { try {
log.info("Initiating SHEP request to URL: {}", urlSHEP); //подписать хмл
File signWSSFile = new File(keyFile);
// Prepare the SHEP request
SyncSendMessageRequest shepRequest = prepareShepRequest(request);
logRequest(shepRequest);
// Get and configure the port Data data = Optional.ofNullable(forwardApplication)
ISyncChannel port = getConfiguredPort(); .map(ForwardApplication::getUpdateApplication)
.map(UpdateApplication::getApplicationData)
.map(ApplicationData::getData)
.orElse(null);
// Send the request and process response
SyncSendMessageResponse response = port.sendMessage(shepRequest);
log.info("Received SHEP response: {}", response); // digiSign
return response; assert data != null;
} catch (SendMessageSendMessageFaultMsg e) { updateIfPresent(data, data::setDigiSign, data.getDigiSign(), signWSSFile, keyPassword);
String errorResponse = handleFaultMessage(e.getFaultInfo());
log.error("SHEP request failed: {}", errorResponse);
return errorResponse;
} catch (Exception e) {
log.error("Unexpected error during SHEP request", e);
throw e;
}
}
public String sendRequestByTemplate(ForwardApplication forwardApplication) throws Exception { // confirmOrder
String request; ConfirmOrder confirm = data.getConfirmOrder();
//generate id if (confirm != null && confirm.getDigiSign() != null) {
updateIfPresent(confirm, confirm::setDigiSign, confirm.getDigiSign(), signWSSFile, keyPassword);
}
try { // denyOrder
ConfirmOrder deny = data.getDenyOrder();
if (deny != null && deny.getDigiSign() != null) {
updateIfPresent(deny, deny::setDigiSign, deny.getDigiSign(), signWSSFile, keyPassword);
}
request = XmlTemplateBuilder.buildXMLForward(forwardApplication, serviceIdSHEP, senderIdSHEP, senderPassSHEP); request = XmlTemplateBuilder.buildXMLForward(forwardApplication, serviceIdSHEP, senderIdSHEP, senderPassSHEP);
...@@ -74,7 +75,6 @@ public class ForwardApplicationNcaService { ...@@ -74,7 +75,6 @@ public class ForwardApplicationNcaService {
log.info("Response: {}\n", response); log.info("Response: {}\n", response);
return response; return response;
// return request;
} catch (Exception e) { } catch (Exception e) {
log.error("Ошибка: {}", e.getMessage(), e); log.error("Ошибка: {}", e.getMessage(), e);
e.printStackTrace(); e.printStackTrace();
...@@ -82,81 +82,22 @@ public class ForwardApplicationNcaService { ...@@ -82,81 +82,22 @@ public class ForwardApplicationNcaService {
} }
} }
private SyncSendMessageRequest prepareShepRequest(ForwardApplication request) private static void updateIfPresent(Object obj, Consumer<String> setter,
throws DatatypeConfigurationException { String valueToSign, File p12, String password) throws Exception {
SyncSendMessageRequest shepRequest = new SyncSendMessageRequest(); if (obj != null && valueToSign != null) {
SyncMessageInfo info = new SyncMessageInfo();
// Set sender information
SenderInfo sender = new SenderInfo();
sender.setPassword(senderPassSHEP);
sender.setSenderId(senderIdSHEP);
// Configure message info
info.setSender(sender);
info.setMessageId(UUID.randomUUID().toString());
info.setServiceId(serviceIdSHEP);
info.setMessageDate(new Date());
shepRequest.setRequestInfo(info); String cleaned = XmlToJsonUtil.cleanXml(valueToSign);
shepRequest.setRequestData(new RequestData()); log.info("Cleaned {}\n", cleaned);
if (cleaned == null || cleaned.isEmpty()) return;
// Оборачиваем в JAXBElement с пустым namespace для элемента data String signedXml = signIfPresent(cleaned, p12, password);
QName qname = new QName("", "data"); setter.accept(signedXml);
JAXBElement<ForwardApplication> jaxbElement =
new JAXBElement<>(qname, ForwardApplication.class, request);
shepRequest.getRequestData().setData(jaxbElement);
return shepRequest;
}
private ISyncChannel getConfiguredPort() {
ISyncChannel port = getPort();
BindingProvider bp = (BindingProvider) port;
// Configure endpoint address
bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, urlSHEP);
// Add handlers
List<Handler> handlers = new ArrayList<>(2);
handlers.add(new ForwardSOAPHandler()); // Добавляем кастомный handler первым
handlers.add(new WriteHandler());
bp.getBinding().setHandlerChain(handlers);
return port;
}
private void logRequest(SyncSendMessageRequest request) {
if (log.isInfoEnabled()) {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(
SyncSendMessageRequest.class,
SearchOrderByReferenceNumberRequest.class,
ForwardApplication.class
);
StringWriter sw = new StringWriter();
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(request, sw);
log.info("SHEP REQUEST: {}", sw.toString());
} catch (JAXBException e) {
log.warn("Failed to log request", e);
}
} }
} }
private String handleFaultMessage(Object e) { private static String signIfPresent(String xml, File signWSSFile, String password) throws Exception {
StringWriter sw = new StringWriter(); if (xml == null || xml.isEmpty()) {
JAXB.marshal(e, sw); return null;
return sw.toString(); }
} return SignerUtil.signXML(xml, signWSSFile, password);
private ISyncChannel getPort() {
ISyncChannel port;
QName portQName = new QName("http://bip.bee.kz/SyncChannel/v10/Interfaces", "ISyncChannel");
javax.xml.ws.Service service = javax.xml.ws.Service.create(portQName);
port = service.getPort(ISyncChannel.class);
return port;
} }
} }
...@@ -2,20 +2,13 @@ package kz.arta.nca_iiscon.service; ...@@ -2,20 +2,13 @@ package kz.arta.nca_iiscon.service;
import kz.arta.nca_iiscon.data.search.SearchOrderByReferenceNumberRequest; import kz.arta.nca_iiscon.data.search.SearchOrderByReferenceNumberRequest;
import kz.arta.nca_iiscon.shep.*; import kz.arta.nca_iiscon.shep.*;
import kz.arta.nca_iiscon.util.XmlTemplateBuilder;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.xml.bind.*; import javax.xml.bind.*;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.handler.Handler;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
@Slf4j @Slf4j
@Service @Service
...@@ -29,107 +22,25 @@ public class NcaIISConService { ...@@ -29,107 +22,25 @@ public class NcaIISConService {
@Value("${service_url}") @Value("${service_url}")
private String urlSHEP; private String urlSHEP;
@Autowired
private RestService restService;
public Object sendRequest(SearchOrderByReferenceNumberRequest request) throws Exception { public Object sendRequestByTemplate(SearchOrderByReferenceNumberRequest referenceNumberRequest) throws Exception {
String request;
try { try {
log.info("Initiating SHEP request to URL: {}", urlSHEP);
// Prepare the SHEP request request = XmlTemplateBuilder.buildXMLReference(referenceNumberRequest, serviceIdSHEP, senderIdSHEP, senderPassSHEP);
SyncSendMessageRequest shepRequest = prepareShepRequest(request);
logRequest(shepRequest);
// Get and configure the port log.info("Request: {}\n", request);
ISyncChannel port = getConfiguredPort(); Object response = restService.getPostWithsSoapHeaders(urlSHEP, request);
log.info("Response: {}\n", response);
// Send the request and process response
SyncSendMessageResponse response = port.sendMessage(shepRequest);
// log.info("Received SHEP response: {}", response);
return response; return response;
} catch (SendMessageSendMessageFaultMsg e) {
String errorResponse = handleFaultMessage(e.getFaultInfo());
log.error("SHEP request failed: {}", errorResponse);
return errorResponse;
} catch (Exception e) { } catch (Exception e) {
log.error("Unexpected error during SHEP request", e); log.error("Ошибка: {}", e.getMessage(), e);
throw e; e.printStackTrace();
} return e.getMessage();
}
private SyncSendMessageRequest prepareShepRequest(SearchOrderByReferenceNumberRequest request)
throws DatatypeConfigurationException {
SyncSendMessageRequest shepRequest = new SyncSendMessageRequest();
SyncMessageInfo info = new SyncMessageInfo();
// Set sender information
SenderInfo sender = new SenderInfo();
sender.setPassword(senderPassSHEP);
sender.setSenderId(senderIdSHEP);
// Configure message info
info.setSender(sender);
info.setMessageId(UUID.randomUUID().toString());
info.setServiceId(serviceIdSHEP);
info.setMessageDate(new Date());
shepRequest.setRequestInfo(info);
shepRequest.setRequestData(new RequestData());
// Оборачиваем в JAXBElement с пустым namespace для элемента data
QName qname = new QName("", "data");
JAXBElement<SearchOrderByReferenceNumberRequest> jaxbElement =
new JAXBElement<>(qname, SearchOrderByReferenceNumberRequest.class, request);
shepRequest.getRequestData().setData(jaxbElement);
return shepRequest;
}
private ISyncChannel getConfiguredPort() {
ISyncChannel port = getPort();
BindingProvider bp = (BindingProvider) port;
// Configure endpoint address
bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, urlSHEP);
// Add handlers
List<Handler> handlers = new ArrayList<>(2);
handlers.add(new CustomSOAPHandler()); // Добавляем кастомный handler первым
handlers.add(new WriteHandler());
bp.getBinding().setHandlerChain(handlers);
return port;
}
private void logRequest(SyncSendMessageRequest request) {
if (log.isInfoEnabled()) {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(
SyncSendMessageRequest.class,
SearchOrderByReferenceNumberRequest.class
);
StringWriter sw = new StringWriter();
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(request, sw);
log.info("SHEP SearchOrderByReferenceNumberRequest: {}", sw.toString());
} catch (JAXBException e) {
log.warn("Failed to log request", e);
}
} }
} }
private String handleFaultMessage(Object e) {
StringWriter sw = new StringWriter();
JAXB.marshal(e, sw);
return sw.toString();
}
private ISyncChannel getPort() {
ISyncChannel port;
QName portQName = new QName("http://bip.bee.kz/SyncChannel/v10/Interfaces", "ISyncChannel");
javax.xml.ws.Service service = javax.xml.ws.Service.create(portQName);
port = service.getPort(ISyncChannel.class);
return port;
}
} }
\ No newline at end of file
package kz.arta.nca_iiscon.service; //package kz.arta.nca_iiscon.service;
//
import javax.xml.namespace.QName; //import javax.xml.namespace.QName;
import javax.xml.soap.SOAPMessage; //import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext; //import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler; //import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext; //import javax.xml.ws.handler.soap.SOAPMessageContext;
import java.io.File; //import java.io.File;
import java.io.FileOutputStream; //import java.io.FileOutputStream;
import java.util.Set; //import java.util.Set;
//
public class WriteHandler implements SOAPHandler<SOAPMessageContext> { //public class WriteHandler implements SOAPHandler<SOAPMessageContext> {
@Override // @Override
public Set<QName> getHeaders() { // public Set<QName> getHeaders() {
return null; // return null;
} // }
//
@Override // @Override
public boolean handleMessage(SOAPMessageContext context) { // public boolean handleMessage(SOAPMessageContext context) {
SOAPMessage msg = context.getMessage(); // SOAPMessage msg = context.getMessage();
String filename="response.xml"; // String filename="response.xml";
Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); // Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outboundProperty){ // if (outboundProperty){
filename="request.xml"; // filename="request.xml";
} // }
try { // try {
FileOutputStream fileOutputStream =new FileOutputStream(new File(filename)); // FileOutputStream fileOutputStream =new FileOutputStream(new File(filename));
msg.writeTo(fileOutputStream); // msg.writeTo(fileOutputStream);
} catch (Exception e) { // } catch (Exception e) {
//
e.printStackTrace(); // e.printStackTrace();
} // }
return true; // return true;
} // }
//
@Override // @Override
public boolean handleFault(SOAPMessageContext context) { // public boolean handleFault(SOAPMessageContext context) {
return false; // return false;
} // }
//
@Override // @Override
public void close(MessageContext context) { // public void close(MessageContext context) {
//
} // }
} //}
package kz.arta.nca_iiscon.util;
import kz.gov.pki.kalkan.asn1.knca.KNCAObjectIdentifiers;
import kz.gov.pki.kalkan.asn1.pkcs.PKCSObjectIdentifiers;
import kz.gov.pki.kalkan.jce.provider.KalkanProvider;
import kz.gov.pki.kalkan.xmldsig.KncaXS;
import org.apache.xml.security.encryption.XMLCipherParameters;
import org.apache.xml.security.exceptions.XMLSecurityException;
import org.apache.xml.security.keys.KeyInfo;
import org.apache.xml.security.signature.XMLSignature;
import org.apache.xml.security.signature.XMLSignatureException;
import org.apache.xml.security.transforms.Transforms;
import org.apache.xml.security.utils.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.soap.*;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
public class SignerUtil {
private static Provider provider;
public static Logger log = LoggerFactory.getLogger(SignerUtil.class);
static {
provider = new KalkanProvider();
boolean exists = false;
Provider[] providers = Security.getProviders();
for (Provider p : providers) {
if (p.getName().equals(provider.getName())) {
exists = true;
}
}
if (!exists) {
Security.addProvider(provider);
KncaXS.loadXMLSecurity();
}
}
private synchronized static Certificate getCertificate(File keyPath, String keyPassword) throws Exception {
try(InputStream inputStream = new FileInputStream(keyPath)) {
KeyStore store = KeyStore.getInstance("PKCS12", provider.getName());
store.load(inputStream, keyPassword.toCharArray());
Enumeration<String> als = store.aliases();
String alias = null;
while (als.hasMoreElements()) {
alias = als.nextElement();
}
final PrivateKey privateKey = (PrivateKey) store.getKey(alias, keyPassword.toCharArray());
final X509Certificate x509Certificate = (X509Certificate) store.getCertificate(alias);
SignerUtil signerUtil = new SignerUtil();
Certificate certificate = signerUtil.new Certificate();
certificate.setCert(x509Certificate);
certificate.setPrivKey(privateKey);
return certificate;
} catch (Exception e){
e.printStackTrace();
return null;
}
}
public static Document getDocument(String xml) throws ParserConfigurationException, SAXException, IOException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.setNamespaceAware(true);
DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
return documentBuilder.parse(new ByteArrayInputStream(xml.getBytes()));
}
public static String signXML(String xml, File keyPath, String keyPassword) throws Exception {
Certificate certificate = getCertificate(keyPath, keyPassword);
return signXML(xml, certificate.getCert(), certificate.getPrivKey());
}
public static String signXML(String xml, X509Certificate cert, PrivateKey privKey) throws Exception {
return createXmlSignature(privKey, cert, xml);
}
public static String createXmlSignature(PrivateKey key, X509Certificate cert, String xmlSource)
throws ParserConfigurationException, SAXException, IOException, XMLSecurityException, TransformerException {
Document document = getDocument(xmlSource);
String signMethod;
String digestMethod;
String sigAlgOid = cert.getSigAlgOID();
if (sigAlgOid.equals(PKCSObjectIdentifiers.sha256WithRSAEncryption.getId())) {
signMethod = Constants.MoreAlgorithmsSpecNS + "rsa-sha256";
digestMethod = XMLCipherParameters.SHA256;
} else if (sigAlgOid.equals(KNCAObjectIdentifiers.gost34311_95_with_gost34310_2004.getId())) {
signMethod = Constants.MoreAlgorithmsSpecNS + "gost34310-gost34311";
digestMethod = Constants.MoreAlgorithmsSpecNS + "gost34311";
} else if (sigAlgOid.equals(KNCAObjectIdentifiers.gost3411_2015_with_gost3410_2015_512.getId())) {
signMethod = "urn:ietf:params:xml:ns:pkigovkz:xmlsec:algorithms:gostr34102015-gostr34112015-512";
digestMethod = "urn:ietf:params:xml:ns:pkigovkz:xmlsec:algorithms:gostr34112015-512";
} else {
throw new IllegalArgumentException("Incorrect algorithm: " + sigAlgOid);
}
Transforms transforms = new Transforms(document);
transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
transforms.addTransform(Transforms.TRANSFORM_C14N_WITH_COMMENTS);
XMLSignature xmlSignature = new XMLSignature(document, "", signMethod);
document.getFirstChild().appendChild(xmlSignature.getElement());
xmlSignature.addDocument("", transforms, digestMethod);
xmlSignature.addKeyInfo(cert);
xmlSignature.sign(key);
return getXmlString(document);
}
private static String getXmlString(Document document) throws TransformerException, IOException {
try (StringWriter os = new StringWriter()) {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
trans.transform(new DOMSource(document), new StreamResult(os));
return os.toString();
}
}
public boolean verifyXml(String xmlString) throws ParserConfigurationException, SAXException, IOException,
XMLSignatureException, XMLSecurityException {
Document doc = getDocument(xmlString);
Element sigElement = null;
Element rootEl = (Element) doc.getFirstChild();
NodeList list = rootEl.getElementsByTagName("ds:Signature");
if (list.getLength() == 0) {
throw new IllegalStateException("ds:Signature not found");
}
Node sigNode = list.item(0);
sigElement = (Element) sigNode;
XMLSignature signature = new XMLSignature(sigElement, "");
KeyInfo ki = signature.getKeyInfo();
X509Certificate cert = ki.getX509Certificate();
if (cert == null) {
throw new IllegalStateException("Certificate not found");
}
return signature.checkSignatureValue(cert);
}
public class Certificate {
private X509Certificate cert;
private PrivateKey privKey;
public X509Certificate getCert() {
return cert;
}
public void setCert(X509Certificate cert) {
this.cert = cert;
}
public PrivateKey getPrivKey() {
return privKey;
}
public void setPrivKey(PrivateKey privKey) {
this.privKey = privKey;
}
}
}
...@@ -7,9 +7,13 @@ import kz.arta.nca_iiscon.data.forward.document.Document; ...@@ -7,9 +7,13 @@ import kz.arta.nca_iiscon.data.forward.document.Document;
import kz.arta.nca_iiscon.data.forward.payment.Payment; import kz.arta.nca_iiscon.data.forward.payment.Payment;
import kz.arta.nca_iiscon.data.forward.registration.ApplicationRegistrationData; import kz.arta.nca_iiscon.data.forward.registration.ApplicationRegistrationData;
import kz.arta.nca_iiscon.data.forward.status.ExecutionStatus; import kz.arta.nca_iiscon.data.forward.status.ExecutionStatus;
import kz.arta.nca_iiscon.data.search.SearchOrderByReferenceNumberRequest;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.text.StringSubstitutor; import org.apache.commons.text.StringSubstitutor;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
...@@ -24,7 +28,7 @@ public class XmlTemplateBuilder { ...@@ -24,7 +28,7 @@ public class XmlTemplateBuilder {
public static String buildXMLForward(ForwardApplication request, String serviceId, String login, String password) throws IOException { public static String buildXMLForward(ForwardApplication request, String serviceId, String login, String password) throws IOException {
Random random = new Random(); Random random = new Random();
String template = loadTemplate("/templates/nonresident.xml"); String template = loadTemplate("/templates/request.xml");
String documentTemplate = loadTemplate("/templates/document.xml"); String documentTemplate = loadTemplate("/templates/document.xml");
String messageID = UUID.randomUUID().toString(); String messageID = UUID.randomUUID().toString();
...@@ -34,12 +38,13 @@ public class XmlTemplateBuilder { ...@@ -34,12 +38,13 @@ public class XmlTemplateBuilder {
String applicationId = request.getApplicationId(); String applicationId = request.getApplicationId();
ApplicationRegistrationData applicationRegistrationData = request.getRegisterApplication().getApplicationRegistrationData(); ApplicationRegistrationData applicationRegistrationData = request.getRegisterApplication().getApplicationRegistrationData();
String registerOrgCode = applicationRegistrationData.getRegisterOrgCode();
Employee employee = applicationRegistrationData.getRegisterEmployee(); Employee employee = applicationRegistrationData.getRegisterEmployee();
String employeeLastName = employee.getLastName(); String employeeLastName = employee.getLastName();
String employeeFirstName = employee.getFirstName(); String employeeFirstName = employee.getFirstName();
String employeeMiddleName = employee.getMiddleName(); String employeeMiddleName = employee.getMiddleName();
String employeePosition = employee.getPosition(); String employeePosition = employee.getPosition();
String employeeIin =employee.getIin(); String employeeIin = employee.getIin();
UpdateApplication updateApplication = request.getUpdateApplication(); UpdateApplication updateApplication = request.getUpdateApplication();
ApplicationData applicationData = updateApplication.getApplicationData(); ApplicationData applicationData = updateApplication.getApplicationData();
...@@ -57,7 +62,7 @@ public class XmlTemplateBuilder { ...@@ -57,7 +62,7 @@ public class XmlTemplateBuilder {
StringBuilder documentArray = new StringBuilder(); StringBuilder documentArray = new StringBuilder();
List<Document> documents = applicationData.getDocuments().getDocument(); List<Document> documents = applicationData.getDocuments().getDocument();
for(Document doc : documents){ for (Document doc : documents) {
Map<String, String> values = new HashMap<>(); Map<String, String> values = new HashMap<>();
values.put("documentId", doc.getDocumentId()); values.put("documentId", doc.getDocumentId());
...@@ -72,16 +77,19 @@ public class XmlTemplateBuilder { ...@@ -72,16 +77,19 @@ public class XmlTemplateBuilder {
} }
String digiSign = applicationData.getData().getDigiSign(); String digiSign = applicationData.getData().getDigiSign();
ConfirmOrder confirmOrder = applicationData.getData().getConfirmOrder();
String personLastName = applicant.getLastName(); String personLastName = applicant.getLastName();
String personFirstName = applicant.getFirstName(); String personFirstName = applicant.getFirstName();
String personMiddleName = applicant.getMiddleName(); String personMiddleName = applicant.getMiddleName();
String contactType = contact.getContactType().toUpperCase();; String contactType = contact.getContactType().toUpperCase();
;
String contactData = contact.getContactData(); String contactData = contact.getContactData();
Boolean isForNotification = contact.getIsForNotification(); Boolean isForNotification = contact.getIsForNotification();
String identityDocumentDocType = identityDocument.getDocType(); String identityDocumentDocType = identityDocument.getDocType();
String identityDocumentDocDate = identityDocument.getDocDate();
String docNum = identityDocument.getDocNum();
String expirationDate = identityDocument.getExpirationDate();
String identityDocumentDocSource = identityDocument.getDocSource(); String identityDocumentDocSource = identityDocument.getDocSource();
String identityDocumentDocName = identityDocument.getDocName(); String identityDocumentDocName = identityDocument.getDocName();
String dateOfBirth = applicant.getDateOfBirth(); String dateOfBirth = applicant.getDateOfBirth();
...@@ -99,11 +107,9 @@ public class XmlTemplateBuilder { ...@@ -99,11 +107,9 @@ public class XmlTemplateBuilder {
: applicationData.getLanguage(); : applicationData.getLanguage();
String confirmOrderDigiSign = confirmOrder.getDigiSign();//this
String subServiceTypeCode = applicationData.getSubServiceTypeCode(); String subServiceTypeCode = applicationData.getSubServiceTypeCode();
Map<String, String> values = new HashMap<>(); Map<String, String> values = new HashMap<>();
values.put("messageId", messageID); values.put("messageId", messageID);
values.put("serviceId", serviceId); values.put("serviceId", serviceId);
...@@ -111,6 +117,7 @@ public class XmlTemplateBuilder { ...@@ -111,6 +117,7 @@ public class XmlTemplateBuilder {
values.put("senderId", login); values.put("senderId", login);
values.put("password", password); values.put("password", password);
values.put("applicationId", applicationId); values.put("applicationId", applicationId);
values.put("registerOrgCode", registerOrgCode);
values.put("employeeLastName", employeeLastName); values.put("employeeLastName", employeeLastName);
values.put("employeeFirstName", employeeFirstName); values.put("employeeFirstName", employeeFirstName);
...@@ -131,6 +138,9 @@ public class XmlTemplateBuilder { ...@@ -131,6 +138,9 @@ public class XmlTemplateBuilder {
// Identity Document // Identity Document
values.put("identityDocumentDocType", identityDocumentDocType); values.put("identityDocumentDocType", identityDocumentDocType);
values.put("identityDocumentDocDate", identityDocumentDocDate);
values.put("docNum", docNum);
values.put("expirationDate", expirationDate);
values.put("identityDocumentDocSource", identityDocumentDocSource); values.put("identityDocumentDocSource", identityDocumentDocSource);
values.put("identityDocumentDocName", identityDocumentDocName); values.put("identityDocumentDocName", identityDocumentDocName);
...@@ -144,7 +154,8 @@ public class XmlTemplateBuilder { ...@@ -144,7 +154,8 @@ public class XmlTemplateBuilder {
values.put("language", language); values.put("language", language);
values.put("document", documentArray.toString()); values.put("document", documentArray.toString());
values.put("dataDigiSign", escapeXml(digiSign)); values.put("dataDigiSign", escapeXml(digiSign));
values.put("confirmOrderDigiSign", escapeXml(confirmOrderDigiSign)); values.put("order", loadOrder(applicationData));
log.info("order after put: {}", values.get("order"));
values.put("subServiceTypeCode", subServiceTypeCode); //ПОКА ОСТАВЛЮ ЖДУ values.put("subServiceTypeCode", subServiceTypeCode); //ПОКА ОСТАВЛЮ ЖДУ
StringSubstitutor substitutor = new StringSubstitutor(values); StringSubstitutor substitutor = new StringSubstitutor(values);
...@@ -164,6 +175,31 @@ public class XmlTemplateBuilder { ...@@ -164,6 +175,31 @@ public class XmlTemplateBuilder {
} }
} }
private static String loadOrder(ApplicationData applicationData) throws IOException {
ConfirmOrder confirmOrder = applicationData.getData().getConfirmOrder();
ConfirmOrder denyOrder = applicationData.getData().getDenyOrder();
ConfirmOrder order = confirmOrder != null ? confirmOrder : denyOrder;
String templatePath = confirmOrder != null
? "/templates/confirmOrder.xml"
: "/templates/denyOrder.xml";
if (order == null) {
throw new IllegalStateException("Оба объекта — confirmOrder и denyOrder — равны null");
}
String orderTemp = loadTemplate(templatePath);
String orderDigiSign = escapeXml(order.getDigiSign());
Map<String, String> values = new HashMap<>();
values.put("orderDigiSign", orderDigiSign);
StringSubstitutor substitutor = new StringSubstitutor(values);
return substitutor.replace(orderTemp);
}
/** /**
* Экранирует XML символы в строке * Экранирует XML символы в строке
*/ */
...@@ -172,9 +208,30 @@ public class XmlTemplateBuilder { ...@@ -172,9 +208,30 @@ public class XmlTemplateBuilder {
return null; return null;
} }
return input.replace("&", "&amp;") return input.replace("&", "&amp;")
.replace("<", "&lt;") .replace("<", "&lt;")
.replace(">", "&gt;") .replace(">", "&gt;")
.replace("\"", "&quot;") .replace("\"", "&quot;")
.replace("'", "&apos;"); .replace("'", "&apos;");
}
public static String buildXMLReference(SearchOrderByReferenceNumberRequest referenceNumberRequest, String serviceId, String login, String password) throws IOException {
String request;
try {
GregorianCalendar calendar = new GregorianCalendar();
calendar.setTime(new Date());
XMLGregorianCalendar xmlCalendar = DatatypeFactory.newInstance().newXMLGregorianCalendar(calendar);
String template = loadTemplate("/templates/referenceRequest.xml");
String messageID = UUID.randomUUID().toString();
log.info("messageID: {}", messageID);
return String.format(template, messageID, serviceId, xmlCalendar.toString(),
login, password, referenceNumberRequest.getReferenceNumber());
} catch (Exception e) {
log.error("Ошибка: {}", e.getMessage(), e);
e.printStackTrace();
return e.getMessage();
}
} }
} }
...@@ -29,33 +29,15 @@ public class XmlToJsonUtil { ...@@ -29,33 +29,15 @@ public class XmlToJsonUtil {
/** /**
* Извлекает XML из поля data и конвертирует в JSON * Извлекает XML из поля data и конвертирует в JSON
*/ */
public static String extractDataAsJson(Object response, Boolean isReference) { public static String extractDataAsJson(Object response, Boolean isReference, String base64photo, String applicantNumber) {
try { try {
// Если response уже String (из sendRequestByTemplate), парсим XML напрямую
if (response instanceof String) {
String xmlResponse = (String) response; String xmlResponse = (String) response;
log.info("Processing String XML response"); log.info("Processing String XML response");
// Извлекаем data element из SOAP response // Извлекаем data element из SOAP response
return extractDataFromSoapXml(xmlResponse); String xmlString = extractDataContentFromSoapXml(xmlResponse);
}
// Конвертируем response в JSON (для sendRequest)
String responseJson = objectMapper.writeValueAsString(response);
JsonNode rootNode = objectMapper.readTree(responseJson);
// Получаем XML строку из responseData.data
JsonNode dataNode = rootNode.at("/responseData/data");
if (dataNode.isMissingNode() || dataNode.isNull()) {
log.warn("Data node not found in response");
return "{}";
}
String xmlString = dataNode.asText();
log.info("XML Response: {}", xmlString);
// Парсим XML и конвертируем в JSON
return xmlToJson(xmlString, isReference);
// Конвертируем в JSON с правильным значением isReference
return xmlToJson(xmlString, isReference, base64photo, applicantNumber);
} catch (Exception e) { } catch (Exception e) {
log.error("Error extracting data as JSON", e); log.error("Error extracting data as JSON", e);
return "{\"error\": \"Failed to parse response\"}"; return "{\"error\": \"Failed to parse response\"}";
...@@ -65,7 +47,7 @@ public class XmlToJsonUtil { ...@@ -65,7 +47,7 @@ public class XmlToJsonUtil {
/** /**
* Извлекает data element из SOAP XML response * Извлекает data element из SOAP XML response
*/ */
private static String extractDataFromSoapXml(String soapXml) throws Exception { private static String extractDataContentFromSoapXml(String soapXml) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true); factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder(); DocumentBuilder builder = factory.newDocumentBuilder();
...@@ -86,8 +68,8 @@ public class XmlToJsonUtil { ...@@ -86,8 +68,8 @@ public class XmlToJsonUtil {
log.info("Extracted XML from SOAP response: {}", xmlContent); log.info("Extracted XML from SOAP response: {}", xmlContent);
// Конвертируем в JSON // Возвращаем XML content без конвертации в JSON
return xmlToJson(xmlContent, false); return xmlContent;
} }
/** /**
...@@ -123,7 +105,7 @@ public class XmlToJsonUtil { ...@@ -123,7 +105,7 @@ public class XmlToJsonUtil {
/** /**
* Конвертирует XML строку в JSON * Конвертирует XML строку в JSON
*/ */
public static String xmlToJson(String xmlString, Boolean isReference) { public static String xmlToJson(String xmlString, Boolean isReference, String base64photo, String applicantNumber) {
try { try {
// Парсим XML // Парсим XML
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
...@@ -143,10 +125,12 @@ public class XmlToJsonUtil { ...@@ -143,10 +125,12 @@ public class XmlToJsonUtil {
if (isReference) { if (isReference) {
String applicationId = gen.generate(); String applicationId = gen.generate();
String digiSign = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><application><applicationId>" + applicationId + "</applicationId><serviceTypeCode>C09-03</serviceTypeCode><registerOrgCode>MFA</registerOrgCode><executorOrgCode>MTC-CTSAT</executorOrgCode><smsCode>14</smsCode></application>"; String digiSign = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><application><applicationId>" + applicationId + "</applicationId><serviceTypeCode>C09-03</serviceTypeCode><registerOrgCode>MID-GER-MUNCHEN</registerOrgCode><executorOrgCode>MTC-CTSAT</executorOrgCode><smsCode>14</smsCode></application>";
String confirmOrderSigned = extractOrderSimple(xmlString, applicationId); String confirmOrderSigned = extractOrderSimple(xmlString, applicationId, base64photo, applicantNumber, true);
String denyOrderSigned = extractOrderSimple(xmlString, applicationId, null, applicantNumber, false);
jsonNode.put("applicationId", applicationId); jsonNode.put("applicationId", applicationId);
jsonNode.put("confirmOrderSign", confirmOrderSigned); jsonNode.put("confirmOrderSign", confirmOrderSigned);
jsonNode.put("denyOrderSign", denyOrderSigned);
jsonNode.put("digiSign", digiSign); jsonNode.put("digiSign", digiSign);
} }
...@@ -159,7 +143,7 @@ public class XmlToJsonUtil { ...@@ -159,7 +143,7 @@ public class XmlToJsonUtil {
} }
} }
public static String extractOrderSimple(String xml, String applicationId) { public static String extractOrderSimple(String xml, String applicationId, String base64photo, String applicantNumber, Boolean isConfirm) {
if (xml == null) return null; if (xml == null) return null;
xml = xml.replaceAll("&#13;", "").trim(); xml = xml.replaceAll("&#13;", "").trim();
...@@ -175,17 +159,12 @@ public class XmlToJsonUtil { ...@@ -175,17 +159,12 @@ public class XmlToJsonUtil {
orderPart = orderPart.replaceAll("(<|</)\\w*:", "$1"); orderPart = orderPart.replaceAll("(<|</)\\w*:", "$1");
// if (!orderPart.contains("<applicationType>") && orderPart.contains("<digitalDoc>")) {
// orderPart = orderPart.replace("</digitalDoc>", "</digitalDoc><applicationType>scan</applicationType>");
// }
// Add xmlns attribute to the order tag
orderPart = orderPart.replaceFirst("<order", "<order xmlns=\"http://pki.gov.kz/api/ws/iiscon/wsdl\""); orderPart = orderPart.replaceFirst("<order", "<order xmlns=\"http://pki.gov.kz/api/ws/iiscon/wsdl\"");
if (orderPart.contains("<digitalDoc>")) { if (orderPart.contains("<digitalDoc>") && isConfirm) {
String replacement = "</digitalDoc>" + String replacement = "</digitalDoc>" +
"<applicationId>"+ applicationId + "</applicationId>" + "<applicationId>"+ applicationId + "</applicationId>" +
"<applicantNumber>${applicantNumber}</applicantNumber>" + "<applicantNumber>"+ applicantNumber + "</applicantNumber>" +
"<originalPhotoFl>${originalPhotoFl}</originalPhotoFl>" + "<savedPhoto>" + base64photo + "</savedPhoto>" +
"<savedPhoto>${savedPhoto}</savedPhoto>" +
"<digitalDoc>false</digitalDoc>"; "<digitalDoc>false</digitalDoc>";
if (!orderPart.contains("<applicationType>")) { if (!orderPart.contains("<applicationType>")) {
...@@ -193,10 +172,18 @@ public class XmlToJsonUtil { ...@@ -193,10 +172,18 @@ public class XmlToJsonUtil {
} }
orderPart = orderPart.replaceFirst("</digitalDoc>", java.util.regex.Matcher.quoteReplacement(replacement)); orderPart = orderPart.replaceFirst("</digitalDoc>", java.util.regex.Matcher.quoteReplacement(replacement));
} } else if (orderPart.contains("<digitalDoc>") && !isConfirm){
String replacement = "</digitalDoc>" +
"<applicationId>"+ applicationId + "</applicationId>" +
"<applicantNumber>"+ applicantNumber + "</applicantNumber>" +
"<digitalDoc>false</digitalDoc>";
if (!orderPart.contains("<applicationType>")) {
replacement += "<applicationType>scan</applicationType>";
}
orderPart = orderPart.replaceAll("[\\n\\r\\t]+", ""); orderPart = orderPart.replaceFirst("</digitalDoc>", java.util.regex.Matcher.quoteReplacement(replacement));
}
String orderXml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" + orderPart; String orderXml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" + orderPart;
...@@ -288,6 +275,17 @@ public class XmlToJsonUtil { ...@@ -288,6 +275,17 @@ public class XmlToJsonUtil {
} }
} }
public static String cleanXml(String xml){
if (xml == null) return null;
xml = xml.replaceAll("&#13;", "").trim();
xml = xml.replaceAll(" +", " ");
return xml
.replace("\\\"", "\"");
}
/** /**
* Извлекает order из XML, удаляет префиксы и лишние символы * Извлекает order из XML, удаляет префиксы и лишние символы
* Возвращает чистый XML с декларацией и namespace * Возвращает чистый XML с декларацией и namespace
...@@ -344,12 +342,6 @@ public class XmlToJsonUtil { ...@@ -344,12 +342,6 @@ public class XmlToJsonUtil {
String result = writer.toString(); String result = writer.toString();
// Удаляем символы &#13; и другие лишние символы
// result = result.replaceAll("&#13;", "")
// .replaceAll("&#xD;", "")
// .trim();
// Удаляем все после закрывающего тега </order>
int orderEndIndex = result.indexOf("</order>"); int orderEndIndex = result.indexOf("</order>");
if (orderEndIndex != -1) { if (orderEndIndex != -1) {
result = result.substring(0, orderEndIndex + "</order>".length()); result = result.substring(0, orderEndIndex + "</order>".length());
......
...@@ -6,6 +6,9 @@ forward_service_id=nca_iiscon ...@@ -6,6 +6,9 @@ forward_service_id=nca_iiscon
service_url=http://192.168.14.19:9580/ws/SyncChannelService.wsdl service_url=http://192.168.14.19:9580/ws/SyncChannelService.wsdl
eds_path=src/main/resources/GOST512_67512ec61ca308dfe8201465b792132b94691a2b.p12
eds_password=Aa123456
login=EISDS login=EISDS
password=8zDV~U4OUo password=8zDV~U4OUo
......
<confirmOrder xmlns="http://pki.gov.kz/api/ws/iiscon/wsdl"><digiSign>${orderDigiSign}</digiSign></confirmOrder>
\ No newline at end of file
<denyOrder xmlns="http://pki.gov.kz/api/ws/iiscon/wsdl"><digiSign>${orderDigiSign}</digiSign></denyOrder>
\ No newline at end of file
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header/>
<soap:Body>
<SendMessage xmlns:ns2="http://bip.bee.kz/common/v10/Types" xmlns:ns3="http://bip.bee.kz/SyncChannel/v10/Types"
xmlns="http://bip.bee.kz/SyncChannel/v10/Types">
<request xmlns="">
<requestInfo>
<messageId>%s</messageId>
<serviceId>%s</serviceId>
<messageDate>%s</messageDate>
<sender>
<senderId>%s</senderId>
<password>%s</password>
</sender>
</requestInfo>
<requestData>
<data xmlns:s01="http://pki.gov.kz/api/ws/iiscon/wsdl"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="s01:SearchOrderByReferenceNumberRequest">
<s01:referenceNumber>%s</s01:referenceNumber>
</data>
</requestData>
</request>
</SendMessage>
</soap:Body>
</soap:Envelope>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><soap:Header/><soap:Body><SendMessage xmlns="http://bip.bee.kz/SyncChannel/v10/Types"><request xmlns=""><requestInfo>
<messageId>${messageId}</messageId>
<serviceId>${serviceId}</serviceId>
<messageDate>${forwardDate}</messageDate>
<sender>
<senderId>${senderId}</senderId>
<password>${password}</password>
</sender>
</requestInfo><requestData><data xmlns:app="http://schemas.letograf.kz/iiscon/bus/v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="app:ForwardApplication">
<app:applicationId>${applicationId}</app:applicationId>
<registerApplication xmlns="http://schemas.letograf.kz/iiscon/bus/v1"><applicationId>${applicationId}</applicationId><applicationRegistrationData><registerId>${applicationId}</registerId><registerOrgCode>${registerOrgCode}</registerOrgCode><serviceTypeCode>C09-03</serviceTypeCode><registerDate>${forwardDate}</registerDate><registerEmployee><lastName>${employeeLastName}</lastName><firstName>${employeeFirstName}</firstName><middleName>${employeeMiddleName}</middleName><position>${employeePosition}</position><iin>${employeeIin}</iin></registerEmployee><smsCode>14</smsCode><registerMethod>MOBILE</registerMethod></applicationRegistrationData></registerApplication><updateApplication xmlns="http://schemas.letograf.kz/iiscon/bus/v1"><applicationId>${applicationId}</applicationId><callOrigin><orgCode>MFA</orgCode><employee><lastName>${employeeLastName}</lastName><firstName>${employeeFirstName}</firstName><middleName>${employeeMiddleName}</middleName><position>${employeePosition}</position><iin>${employeeIin}</iin></employee><systemCode>052</systemCode></callOrigin><applicationData><applicant><person><iin>${personIin}</iin><lastName>${personLastName}</lastName><firstName>${personFirstName}</firstName><middleName>${personMiddleName}</middleName><contacts><contact><contactType>${contactType}</contactType><contactData>${contactData}</contactData><contactPrefix/><isForNotification>${isForNotification}</isForNotification></contact></contacts><identityDocument><docType>${identityDocumentDocType}</docType><docSer/><docNum/><docDate>${identityDocumentDocDate}</docDate><docSource>${identityDocumentDocSource}</docSource><docName>${identityDocumentDocName}</docName></identityDocument><dateOfBirth>${dateOfBirth}</dateOfBirth><placeOfBirth>${placeOfBirth}</placeOfBirth><gender>${gender}</gender><isForeigner>${isForeigner}</isForeigner><citizenship>${citizenship}</citizenship></person></applicant><executorOrgCode>MTC-CTSAT</executorOrgCode><deliveryOrgCode>MFA</deliveryOrgCode><deadline>${deadline}</deadline><cost>0.0</cost><payments><payment><paymentId>${paymentId}</paymentId><cost>0.0</cost><paymentType>BVU</paymentType></payment></payments><copies>1</copies><language>${language}</language><finalDocumentLang>${language}</finalDocumentLang><documents>${document}</documents><data><digiSign>${dataDigiSign}</digiSign>${order}</data><applicationAttrs><attr><name>note</name><value/></attr><attr><name>resultDeliveryPlace</name><value>SC</value></attr></applicationAttrs><subServiceTypeCode>${subServiceTypeCode}</subServiceTypeCode></applicationData></updateApplication><app:statusHistory>
<changeApplicationStatus xmlns="http://schemas.letograf.kz/iiscon/bus/v1"><applicationId>${applicationId}</applicationId><callOrigin><orgCode>MFA</orgCode><employee><lastName>${employeeLastName}</lastName><firstName>${employeeFirstName}</firstName><middleName>${employeeMiddleName}</middleName><position>${employeePosition}</position><iin>${employeeIin}</iin></employee><systemCode>052</systemCode></callOrigin><applicationStatus><executionStatus><appState>LAUNCHED</appState><statusInfo>Отправлено на исполнение</statusInfo><statusInfoKz>Орындауға жіберілген</statusInfoKz></executionStatus></applicationStatus><statusDate>${forwardDate}</statusDate></changeApplicationStatus><changeApplicationStatus xmlns="http://schemas.letograf.kz/iiscon/bus/v1"><applicationId>${applicationId}</applicationId><callOrigin><orgCode>MFA</orgCode><employee><lastName>${employeeLastName}</lastName><firstName>${employeeFirstName}</firstName><middleName>${employeeMiddleName}</middleName><position>${employeePosition}</position><iin>${employeeIin}</iin></employee><systemCode>052</systemCode></callOrigin><applicationStatus><executionStatus><appState>ACCEPTED</appState><statusInfo>Принято от заявителя</statusInfo><statusInfoKz>Өтініш жазушыдан қабылданған</statusInfoKz></executionStatus></applicationStatus><statusDate>${forwardDate}</statusDate></changeApplicationStatus></app:statusHistory>
</data></requestData></request></SendMessage></soap:Body></soap:Envelope>
<!--my-->
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<order >
<certificateRequests>
<csr>-----BEGIN CERTIFICATE
REQUEST-----MIICLDCCAZQCAQAwgYcxJjAkBgNVBAMMHdCk0JjQm9Ce0JfQntCkINCi0JDQotCs0K/QndCQMRcwFQYDVQQEDA7QpNCY0JvQntCX0J7QpDEYMBYGA1UEBRMPSUlOODMwNDA0MDAwMjM4MQswCQYDVQQGEwJLWjEdMBsGA1UEKgwU0JLQmNCi0JDQm9Cs0JXQktCd0JAwgawwIwYJKoMOAwoBAQICMBYGCiqDDgMKAQECAgEGCCqDDgMKAQMDA4GEAASBgGnTlks1sg/RHS52qedybPdFkDcFDhrj188+RO4jtqHmonulWd7RbwWe8jinafR7FTe8fByJqedZ93/46MhCl4JmZQoR35JUlukh5qL2TXN4VlQ2OS2rdE2PjtyCEoixbsv8vgpJQHfkNPwrcWEpQKLWrhQ53fWyp0kWPjs9YtlloFYwVAYJKoZIhvcNAQkOMUcwRTBDBgYqgw4DAwUEOTA3Bggqgw4DAwUBAQwrQzpcVXNlcnNcbGFcRGVza3RvcFzQmNCY0KHQptCe0J1cdGVzdFx0ZXN0NjAOBgoqgw4DCgEBAgMCBQADgYEAdBtTkoU+QApAi9qtjkZ11ub27NXuLHhnId9kHNyCCQlJabGJGj+kzoEU7z+lGRqvcKX2XOabyxLIHPKAvlEHL39+1ylewO6bzhIQrU/CSd2rqDJZOgO0kxsKWFzkY7qsj5Z4r9CsvIAJUQKj4GEHSpGYjis13W7maC7ajiO599s=-----END
CERTIFICATE REQUEST-----
</csr>
<requestTemplateName>individ_sign_ng</requestTemplateName>
<subjectDN>
<rdns>
<rdnName>C</rdnName>
<value>KZ</value>
</rdns>
<rdns>
<rdnName>SERIALNUMBER</rdnName>
<value>IIN830404000238</value>
</rdns>
<rdns>
<rdnName>SURNAME</rdnName>
<value>ФИЛОЗОФ</value>
</rdns>
<rdns>
<rdnName>CN</rdnName>
<value>ФИЛОЗОФ ТАТЬЯНА</value>
</rdns>
<rdns>
<rdnName>G</rdnName>
<value>ВИТАЛЬЕВНА</value>
</rdns>
</subjectDN>
<publicKey>
04818069d3964b35b20fd11d2e76a9e7726cf7459037050e1ae3d7cf3e44ee23b6a1e6a27ba559ded16f059ef238a769f47b1537bc7c1c89a9e759f77ff8e8c842978266650a11df925496e921e6a2f64d7378565436392dab744d8f8edc821288b16ecbfcbe0a494077e434fc2b71612940a2d6ae1439ddf5b2a749163e3b3d62d965
</publicKey>
</certificateRequests>
<referenceNumber>14993427151112</referenceNumber>
<orderType>ORDER_TYPE_ONLINE</orderType>
<storageCode>PKCS12</storageCode>
<digitalDoc>false</digitalDoc>
<applicationType>scan</applicationType>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="1">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<ds:SignatureMethod
Algorithm="urn:ietf:params:xml:ns:pkigovkz:xmlsec:algorithms:gostr34102015-gostr34112015-512"/>
<ds:Reference URI="">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="urn:ietf:params:xml:ns:pkigovkz:xmlsec:algorithms:gostr34112015-512"/>
<ds:DigestValue>
t6IpRUQr+C6qkEwwHBA2+pK4WmeiM6RMgXA7TsUyO3wv2SK6I+TNeUHGnXaLNa40OHmji+vfxFVoxWHvuRRAOg==
</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
7GtBBzqauxr4sFPHQkXOdTG8hcP6ZsJuzNEbalM4Z8iTmg7pZyZdZih0j+anyblDNpeN5Cr0S/F4M2JbWF7MFt6A7sItDfpL4rScNVt5bHxHUsGTPWK4Q0W79k3y45GvrWbWOSVQkrzOeLdfweYKw142SgucC+lU0XrfGMFOFEQ=
</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>
MIIEdjCCA96gAwIBAgIUZ1EuxhyjCN/oIBRlt5ITK5RpGiswDgYKKoMOAwoBAQIDAgUAMF0xTjBMBgNVBAMMRdKw0JvQotCi0KvSmiDQmtCj05jQm9CQ0J3QlNCr0KDQo9Co0Ksg0J7QoNCi0JDQm9Cr0pogKEdPU1QpIFRFU1QgMjAyMjELMAkGA1UEBhMCS1owHhcNMjUxMDI5MDM1MjI3WhcNMjYxMDI5MDM1MjI3WjCBrTEeMBwGA1UEAwwV0KLQldCh0KLQntCSINCi0JXQodCiMRUwEwYDVQQEDAzQotCV0KHQotCe0JIxGDAWBgNVBAUTD0lJTjEyMzQ1Njc4OTAxMTELMAkGA1UEBhMCS1oxGDAWBgNVBAoMD9CQ0J4gItCi0JXQodCiIjEYMBYGA1UECwwPQklOMTIzNDU2Nzg5MDIxMRkwFwYDVQQqDBDQotCV0KHQotCe0JLQmNCnMIGsMCMGCSqDDgMKAQECAjAWBgoqgw4DCgEBAgIBBggqgw4DCgEDAwOBhAAEgYAUC1c5kmlAGUiXCWQzEi7psOWNCMOTLV2ZuSOGuiDjx6A4nAYh/QECUKkzfzhqJk3/CFCyTwZ3GSv8h0Bq8zeEFwZBRLRISnOXp+VCoFXulgFBo1J3cFE31hlRMid382+2DqrjE4qDOpePgcd59r3fcW6brvxIRjpscxPcPcPKj6OCAdEwggHNMCgGA1UdJQQhMB8GCCsGAQUFBwMEBggqgw4DAwQBAgYJKoMOAwMEAQIFMDgGA1UdIAQxMC8wLQYGKoMOAwMCMCMwIQYIKwYBBQUHAgEWFWh0dHA6Ly9wa2kuZ292Lmt6L2NwczB3BggrBgEFBQcBAQRrMGkwKAYIKwYBBQUHMAGGHGh0dHA6Ly90ZXN0LnBraS5nb3Yua3ovb2NzcC8wPQYIKwYBBQUHMAKGMWh0dHA6Ly90ZXN0LnBraS5nb3Yua3ovY2VydC9uY2FfZ29zdDIwMjJfdGVzdC5jZXIwQQYDVR0fBDowODA2oDSgMoYwaHR0cDovL3Rlc3QucGtpLmdvdi5rei9jcmwvbmNhX2dvc3QyMDIyX3Rlc3QuY3JsMEMGA1UdLgQ8MDowOKA2oDSGMmh0dHA6Ly90ZXN0LnBraS5nb3Yua3ovY3JsL25jYV9nb3N0MjAyMl9kX3Rlc3QuY3JsMA4GA1UdDwEB/wQEAwIDyDAdBgNVHQ4EFgQUZ1EuxhyjCN/oIBRlt5ITK5RpGiswHwYDVR0jBBgwFoAU+tJLG6OgyWH+HKhQPmqiu0UNuKMwFgYGKoMOAwMFBAwwCgYIKoMOAwMFAQEwDgYKKoMOAwoBAQIDAgUAA4GBAJocEMkkNEEazl0GuwgD7sDJmJ6YdlMkIAffrV0SJ17uTpkuaFy9QX165Dxhusc5WSKkcMIj7HO2PlMVijWBxRP0yeL/E0ygs9Es+QGV/4WeiT9kWNXCT1HkROmpAILnuoxjs3fPWqGsrnzvj/Kwl2heabyGJ968kAk6DvY8psjU
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
</order>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment