ModIImbustamento.java

  1. /*
  2.  * GovWay - A customizable API Gateway
  3.  * https://govway.org
  4.  *
  5.  * Copyright (c) 2005-2025 Link.it srl (https://link.it).
  6.  *
  7.  * This program is free software: you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License version 3, as published by
  9.  * the Free Software Foundation.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  *
  19.  */

  20. package org.openspcoop2.protocol.modipa.builder;

  21. import java.io.IOException;
  22. import java.util.List;
  23. import java.util.Map;

  24. import javax.servlet.http.HttpServletResponse;
  25. import javax.xml.soap.SOAPEnvelope;

  26. import org.apache.commons.lang.StringUtils;
  27. import org.openspcoop2.core.config.ServizioApplicativo;
  28. import org.openspcoop2.core.config.driver.DriverConfigurazioneException;
  29. import org.openspcoop2.core.config.driver.db.DriverConfigurazioneDB;
  30. import org.openspcoop2.core.constants.Costanti;
  31. import org.openspcoop2.core.constants.TipoPdD;
  32. import org.openspcoop2.core.id.IDAccordo;
  33. import org.openspcoop2.core.id.IDServizio;
  34. import org.openspcoop2.core.id.IDServizioApplicativo;
  35. import org.openspcoop2.core.id.IDSoggetto;
  36. import org.openspcoop2.core.registry.AccordoServizioParteComune;
  37. import org.openspcoop2.core.registry.AccordoServizioParteSpecifica;
  38. import org.openspcoop2.core.registry.ProtocolProperty;
  39. import org.openspcoop2.core.registry.Resource;
  40. import org.openspcoop2.core.registry.driver.IDAccordoFactory;
  41. import org.openspcoop2.core.registry.driver.IDServizioFactory;
  42. import org.openspcoop2.message.OpenSPCoop2Message;
  43. import org.openspcoop2.message.OpenSPCoop2MessageFactory;
  44. import org.openspcoop2.message.constants.MessageRole;
  45. import org.openspcoop2.pdd.config.ConfigurazionePdDReader;
  46. import org.openspcoop2.pdd.config.DigestServiceParams;
  47. import org.openspcoop2.pdd.config.DigestServiceParamsDriver;
  48. import org.openspcoop2.pdd.config.OpenSPCoop2Properties;
  49. import org.openspcoop2.pdd.core.CostantiPdD;
  50. import org.openspcoop2.pdd.core.dynamic.DynamicUtils;
  51. import org.openspcoop2.pdd.core.token.PolicyNegoziazioneToken;
  52. import org.openspcoop2.pdd.core.transazioni.Transaction;
  53. import org.openspcoop2.pdd.core.transazioni.TransactionContext;
  54. import org.openspcoop2.pdd.core.transazioni.TransactionNotExistsException;
  55. import org.openspcoop2.pdd.logger.MsgDiagnosticiProperties;
  56. import org.openspcoop2.pdd.logger.MsgDiagnostico;
  57. import org.openspcoop2.protocol.engine.utils.NamingUtils;
  58. import org.openspcoop2.protocol.modipa.ModIBustaRawContent;
  59. import org.openspcoop2.protocol.modipa.config.ModIProperties;
  60. import org.openspcoop2.protocol.modipa.constants.ModICostanti;
  61. import org.openspcoop2.protocol.modipa.constants.ModIHeaderType;
  62. import org.openspcoop2.protocol.modipa.constants.ModISignalHubOperation;
  63. import org.openspcoop2.protocol.modipa.utils.MockHttpServletRequest;
  64. import org.openspcoop2.protocol.modipa.utils.MockHttpServletResponse;
  65. import org.openspcoop2.protocol.modipa.utils.MockServletInputStream;
  66. import org.openspcoop2.protocol.modipa.utils.MockServletOutputStream;
  67. import org.openspcoop2.protocol.modipa.utils.ModIKeystoreConfig;
  68. import org.openspcoop2.protocol.modipa.utils.ModIPropertiesUtils;
  69. import org.openspcoop2.protocol.modipa.utils.ModISecurityConfig;
  70. import org.openspcoop2.protocol.modipa.utils.ModIUtilities;
  71. import org.openspcoop2.protocol.modipa.utils.SignalHubUtils;
  72. import org.openspcoop2.protocol.sdk.Busta;
  73. import org.openspcoop2.protocol.sdk.ConfigurazionePdD;
  74. import org.openspcoop2.protocol.sdk.Context;
  75. import org.openspcoop2.protocol.sdk.IProtocolFactory;
  76. import org.openspcoop2.protocol.sdk.ProtocolException;
  77. import org.openspcoop2.protocol.sdk.ProtocolMessage;
  78. import org.openspcoop2.protocol.sdk.constants.RuoloMessaggio;
  79. import org.openspcoop2.protocol.sdk.properties.ProtocolPropertiesUtils;
  80. import org.openspcoop2.protocol.sdk.registry.IConfigIntegrationReader;
  81. import org.openspcoop2.protocol.sdk.registry.IRegistryReader;
  82. import org.openspcoop2.protocol.sdk.state.IState;
  83. import org.openspcoop2.protocol.sdk.state.RequestInfo;
  84. import org.openspcoop2.protocol.utils.IDSerialGenerator;
  85. import org.openspcoop2.utils.MapKey;
  86. import org.openspcoop2.utils.UtilsException;
  87. import org.openspcoop2.utils.certificate.KeystoreParams;
  88. import org.openspcoop2.utils.date.DateManager;
  89. import org.openspcoop2.utils.digest.DigestConfig;
  90. import org.openspcoop2.utils.digest.DigestFactory;
  91. import org.openspcoop2.utils.digest.IDigest;
  92. import org.openspcoop2.utils.id.UniqueIdentifierManager;
  93. import org.openspcoop2.utils.id.serial.IDSerialGeneratorParameter;
  94. import org.openspcoop2.utils.id.serial.IDSerialGeneratorType;
  95. import org.openspcoop2.utils.json.JSONUtils;
  96. import org.openspcoop2.utils.transport.TransportRequestContext;
  97. import org.openspcoop2.utils.transport.http.HttpConstants;
  98. import org.slf4j.Logger;

  99. import com.fasterxml.jackson.databind.JsonNode;
  100. import com.fasterxml.jackson.databind.node.ObjectNode;

  101. /**
  102.  * ModIImbustamento
  103.  *
  104.  * @author Poli Andrea (apoli@link.it)
  105.  * @author $Author$
  106.  * @version $Rev$, $Date$
  107.  */
  108. public class ModIImbustamento {

  109.     private Logger log;
  110.     private ModIProperties modiProperties;
  111.     public ModIImbustamento(Logger log) throws ProtocolException {
  112.         this.log = log;
  113.         this.modiProperties = ModIProperties.getInstance();
  114.     }
  115.    
  116.     private static final String DIAGNOSTIC_ADD_TOKEN_ID_AUTH = "addTokenIdAuth";
  117.     private static final String DIAGNOSTIC_ADD_TOKEN_INTEGRITY = "addTokenIntegrity";
  118.     private static final String DIAGNOSTIC_IN_CORSO = "inCorso";
  119.     private static final String DIAGNOSTIC_COMPLETATA = "completata";
  120.     private static final String DIAGNOSTIC_FALLITA = "fallita";
  121.    
  122.     private static String getReplyToErogazione(IDSoggetto idSoggettoMittente, AccordoServizioParteComune aspc, String nomePortType, String azione,
  123.             IRegistryReader registryReader, IConfigIntegrationReader configIntegrationReader,
  124.             IProtocolFactory<?> protocolFactory, IState state,
  125.             RequestInfo requestInfo) throws ProtocolException {
  126.         try {
  127.             return ModIUtilities.getReplyToErogazione(idSoggettoMittente, aspc, nomePortType, azione,
  128.                     registryReader, configIntegrationReader, protocolFactory, state, requestInfo);
  129.         }catch(Exception e) {
  130.             throw new ProtocolException("Configurazione presente nel registro non corretta: "+e.getMessage(),e);
  131.         }
  132.     }
  133.    
  134.     private static String newUniqueIdentifier() throws ProtocolException {
  135.         try{
  136.             return UniqueIdentifierManager.newUniqueIdentifier().getAsString();
  137.         }catch(Exception e){
  138.             throw new ProtocolException(e.getMessage());
  139.         }
  140.     }
  141.    
  142.     public ProtocolMessage buildMessage(OpenSPCoop2Message msg, Context context, Busta busta, Busta bustaRichiesta,
  143.             RuoloMessaggio ruoloMessaggio,
  144.             IRegistryReader registryReader, IConfigIntegrationReader configIntegrationReader,
  145.             IProtocolFactory<?> protocolFactory, IState state) throws ProtocolException{
  146.        
  147.         try{
  148.             ProtocolMessage protocolMessage = new ProtocolMessage();
  149.            
  150.             MessageRole messageRole = MessageRole.REQUEST;
  151.             if(RuoloMessaggio.RISPOSTA.equals(ruoloMessaggio)){
  152.                 messageRole = MessageRole.RESPONSE;
  153.             }
  154.            
  155.            
  156.             // **** Read object from Registry *****
  157.            
  158.             IDSoggetto idSoggettoMittente = new IDSoggetto(busta.getTipoMittente(),busta.getMittente());
  159.             IDSoggetto idSoggettoDestinatario = new IDSoggetto(busta.getTipoDestinatario(),busta.getDestinatario());
  160.             IDSoggetto idSoggettoErogatore = null;
  161.             IDSoggetto idSoggettoProprietarioSA = null;
  162.             if(RuoloMessaggio.RICHIESTA.equals(ruoloMessaggio)){
  163.                 idSoggettoErogatore = idSoggettoDestinatario;
  164.                 idSoggettoProprietarioSA = idSoggettoMittente;
  165.             }
  166.             else{
  167.                 idSoggettoErogatore = idSoggettoMittente;
  168.                 idSoggettoProprietarioSA = idSoggettoDestinatario;
  169.             }
  170.             IDServizio idServizio = IDServizioFactory.getInstance().getIDServizioFromValues(busta.getTipoServizio(), busta.getServizio(),
  171.                     idSoggettoErogatore, busta.getVersioneServizio());
  172.             AccordoServizioParteSpecifica asps = registryReader.getAccordoServizioParteSpecifica(idServizio);
  173.            
  174.             IDAccordo idAccordo = IDAccordoFactory.getInstance().getIDAccordoFromUri(asps.getAccordoServizioParteComune());
  175.             AccordoServizioParteComune aspc = registryReader.getAccordoServizioParteComune(idAccordo);
  176.             boolean rest = org.openspcoop2.core.registry.constants.ServiceBinding.REST.equals(aspc.getServiceBinding());
  177.            
  178.             IDServizioApplicativo idSA = null;
  179.             ServizioApplicativo sa = null;
  180.             if(MessageRole.REQUEST.equals(messageRole) &&
  181.                     busta.getServizioApplicativoFruitore()!=null &&
  182.                     !CostantiPdD.SERVIZIO_APPLICATIVO_ANONIMO.equals(busta.getServizioApplicativoFruitore())) {
  183.                 idSA = new IDServizioApplicativo();
  184.                 idSA.setIdSoggettoProprietario(idSoggettoProprietarioSA);
  185.                 idSA.setNome(busta.getServizioApplicativoFruitore());
  186.                 sa = configIntegrationReader.getServizioApplicativo(idSA);
  187.             }
  188.             if(MessageRole.REQUEST.equals(messageRole) && sa==null) {
  189.                 // provo a vedere se autenticato tramite autenticazione token
  190.                 IDServizioApplicativo idServizioApplicativoToken = null;
  191.                 if(context!=null && context.containsKey(org.openspcoop2.core.constants.Costanti.ID_APPLICATIVO_TOKEN)) {
  192.                     idServizioApplicativoToken = (IDServizioApplicativo) context.getObject(org.openspcoop2.core.constants.Costanti.ID_APPLICATIVO_TOKEN);
  193.                 }
  194.                 if(idServizioApplicativoToken!=null) {
  195.                     idSA = idServizioApplicativoToken;
  196.                     sa = configIntegrationReader.getServizioApplicativo(idSA);
  197.                 }
  198.             }
  199.            
  200.             String azione = busta.getAzione();
  201.             String nomePortType = asps.getPortType();
  202.            
  203.             RequestInfo requestInfo = null;
  204.             if(context!=null && context.containsKey(org.openspcoop2.core.constants.Costanti.REQUEST_INFO)) {
  205.                 requestInfo = (RequestInfo) context.getObject(org.openspcoop2.core.constants.Costanti.REQUEST_INFO);
  206.             }
  207.            
  208.             ModIImbustamentoRest imbustamentoRest = null;
  209.             ModIImbustamentoSoap imbustamentoSoap = null;
  210.             if(rest) {
  211.                 imbustamentoRest = new ModIImbustamentoRest(this.log);
  212.             }
  213.             else {
  214.                 imbustamentoSoap = new ModIImbustamentoSoap(this.log);
  215.             }
  216.            
  217.            
  218.            
  219.             /* *** PROFILO INTERAZIONE *** */
  220.            
  221.             String interactionProfile = ModIPropertiesUtils.readPropertyInteractionProfile(aspc, nomePortType, azione);
  222.             busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_INTERAZIONE, interactionProfile);
  223.            
  224.             if(ModICostanti.MODIPA_PROFILO_INTERAZIONE_VALUE_BLOCCANTE.equals(interactionProfile)) {
  225.            
  226.                 if(rest) {
  227.                     imbustamentoRest.addSyncInteractionProfile(msg, ruoloMessaggio);
  228.                 }
  229.                
  230.             }
  231.             else if(ModICostanti.MODIPA_PROFILO_INTERAZIONE_VALUE_NON_BLOCCANTE.equals(interactionProfile)) {
  232.                
  233.                 String asyncInteractionType = ModIPropertiesUtils.readPropertyAsyncInteractionProfile(aspc, nomePortType, azione);
  234.                 busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_INTERAZIONE_ASINCRONA_TIPO, asyncInteractionType);
  235.                
  236.                 String asyncInteractionRole = ModIPropertiesUtils.readPropertyAsyncInteractionRole(aspc, nomePortType, azione);
  237.                 busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_INTERAZIONE_ASINCRONA_RUOLO, asyncInteractionRole);
  238.                
  239.                 String replyTo = null;
  240.                
  241.                 AccordoServizioParteComune apiContenenteRisorsa = null;
  242.                                
  243.                 if(ModICostanti.MODIPA_PROFILO_INTERAZIONE_ASINCRONA_RUOLO_VALUE_RICHIESTA.equals(asyncInteractionRole)) {
  244.                
  245.                     if(RuoloMessaggio.RICHIESTA.equals(ruoloMessaggio) && ModICostanti.MODIPA_PROFILO_INTERAZIONE_ASINCRONA_VALUE_PUSH.equals(asyncInteractionType)) {
  246.                         // devo cercare l'url di invocazione del servizio erogato correlato.
  247.                        
  248.                         replyTo = getReplyToErogazione(idSoggettoMittente, aspc, nomePortType, azione,
  249.                                 registryReader, configIntegrationReader,
  250.                                 protocolFactory, state,
  251.                                 requestInfo);
  252.                     }
  253.                    
  254.                     apiContenenteRisorsa = aspc;
  255.                    
  256.                 }
  257.                 else {
  258.                    
  259.                     if(ModICostanti.MODIPA_PROFILO_INTERAZIONE_ASINCRONA_VALUE_PUSH.equals(asyncInteractionType)) {
  260.                         String asyncInteractionRequestApi = ModIPropertiesUtils.readPropertyAsyncInteractionRequestApi(aspc, nomePortType, azione);
  261.                         IDAccordo idApiCorrelata = IDAccordoFactory.getInstance().getIDAccordoFromUri(asyncInteractionRequestApi);
  262.                         String labelApi = NamingUtils.getLabelAccordoServizioParteComune(idApiCorrelata);
  263.                         busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_INTERAZIONE_ASINCRONA_API_RICHIESTA_CORRELATA, labelApi);
  264.                         apiContenenteRisorsa = registryReader.getAccordoServizioParteComune(idApiCorrelata, false, false);
  265.                     }
  266.                     else {
  267.                         apiContenenteRisorsa = aspc;
  268.                     }
  269.                    
  270.                     if(rest) {
  271.                        
  272.                         String asyncInteractionRequestResource = ModIPropertiesUtils.readPropertyAsyncInteractionRequestAction(aspc, nomePortType, azione);
  273.                                                
  274.                         String labelResourceCorrelata = asyncInteractionRequestResource;
  275.                         for (Resource r : apiContenenteRisorsa.getResourceList()) {
  276.                             if(r.getNome().equals(asyncInteractionRequestResource)) {
  277.                                 labelResourceCorrelata = NamingUtils.getLabelResource(r);
  278.                                 break;
  279.                             }
  280.                         }
  281.                        
  282.                         busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_INTERAZIONE_ASINCRONA_RISORSA_RICHIESTA_CORRELATA, labelResourceCorrelata);
  283.                        
  284.                     }
  285.                     else {
  286.                        
  287.                         String asyncInteractionRequestService = ModIPropertiesUtils.readPropertyAsyncInteractionRequestService(aspc, nomePortType, azione);
  288.                         busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_INTERAZIONE_ASINCRONA_SERVIZIO_RICHIESTA_CORRELATA, asyncInteractionRequestService);
  289.                        
  290.                         String asyncInteractionRequestAction = ModIPropertiesUtils.readPropertyAsyncInteractionRequestAction(aspc, nomePortType, azione);
  291.                         busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_INTERAZIONE_ASINCRONA_AZIONE_RICHIESTA_CORRELATA, asyncInteractionRequestAction);
  292.                        
  293.                     }
  294.                    
  295.                 }
  296.                
  297.                 if(rest) {
  298.                     imbustamentoRest.addAsyncInteractionProfile(msg, busta, ruoloMessaggio,
  299.                             asyncInteractionType, asyncInteractionRole,
  300.                             replyTo,
  301.                             apiContenenteRisorsa, azione);
  302.                 }
  303.                 else {
  304.                     imbustamentoSoap.addAsyncInteractionProfile(msg, busta, ruoloMessaggio,
  305.                             asyncInteractionType, asyncInteractionRole,
  306.                             replyTo,
  307.                             apiContenenteRisorsa, azione);
  308.                 }
  309.                
  310.             }
  311.            
  312.             /* *** SIGNAL HUB PUSH SIGNALS *** */  
  313.             if (RuoloMessaggio.RICHIESTA.equals(ruoloMessaggio)
  314.                     && context.containsKey(ModICostanti.MODIPA_KEY_INFO_SIGNAL_HUB_SIGNAL_TYPE)) {
  315.                 msg = this.computeSignalHubMessage(msg, context, protocolFactory, state);
  316.             }
  317.            
  318.            
  319.             /* *** SICUREZZA CANALE *** */
  320.            
  321.             String securityChannelProfile = ModIPropertiesUtils.readPropertySecurityChannelProfile(aspc, asps);
  322.             busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_CANALE, securityChannelProfile);
  323.            
  324.            
  325.             /* *** SICUREZZA MESSAGGIO *** */
  326.            
  327.             boolean isRichiesta = MessageRole.REQUEST.equals(messageRole);
  328.            
  329.            
  330.             boolean filterPDND = true;
  331.             String securityMessageProfileNonFiltratoPDND = ModIPropertiesUtils.readPropertySecurityMessageProfile(aspc, nomePortType, azione, !filterPDND);
  332.            
  333.             boolean existsSecurityFlusso =  false;
  334.             if(securityMessageProfileNonFiltratoPDND!=null && !ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_UNDEFINED.equals(securityMessageProfileNonFiltratoPDND)) {
  335.                 existsSecurityFlusso = ModIPropertiesUtils.processSecurity(this.log, aspc, nomePortType, azione, isRichiesta,
  336.                         msg, rest, this.modiProperties);
  337.             }
  338.            
  339.             if(existsSecurityFlusso) {
  340.                
  341.                 busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO,
  342.                         ModIPropertiesUtils.convertProfiloSicurezzaToSDKValue(securityMessageProfileNonFiltratoPDND, rest));
  343.                
  344.                 String sorgenteToken = ModIPropertiesUtils.readPropertySecurityMessageSorgenteToken(aspc, nomePortType, azione, true);
  345.                 busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_SORGENTE_TOKEN,
  346.                         ModIPropertiesUtils.convertProfiloSicurezzaSorgenteTokenToSDKValue(sorgenteToken));
  347.                 boolean sorgenteLocale = true;
  348.                 if(ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_SORGENTE_TOKEN_IDAUTH_VALUE_PDND.equals(sorgenteToken) ||
  349.                         ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_SORGENTE_TOKEN_IDAUTH_VALUE_OAUTH.equals(sorgenteToken)) {
  350.                     sorgenteLocale = false;
  351.                 }
  352.                
  353.                 String securityMessageProfile = ModIPropertiesUtils.readPropertySecurityMessageProfile(aspc, nomePortType, azione, filterPDND);
  354.                
  355.                 boolean sicurezzaRidefinitaOperazione = ModIPropertiesUtils.readSicurezzaMessaggioRidefinitaOperazioneEngine(aspc, nomePortType, azione);
  356.                                
  357.                 MsgDiagnostico msgDiag = null;
  358.                 TipoPdD tipoPdD = RuoloMessaggio.RICHIESTA.equals(ruoloMessaggio) ? TipoPdD.DELEGATA : TipoPdD.APPLICATIVA;
  359.                 IDSoggetto idSoggetto = TipoPdD.DELEGATA.equals(tipoPdD) ? idSoggettoMittente : idSoggettoDestinatario;
  360.                 if(idSoggetto==null || idSoggetto.getTipo()==null || idSoggetto.getNome()==null) {
  361.                     idSoggetto = OpenSPCoop2Properties.getInstance().getIdentitaPortaDefault(protocolFactory.getProtocol(), requestInfo);
  362.                 }
  363.                 else {
  364.                     idSoggetto.setCodicePorta(registryReader.getDominio(idSoggetto));
  365.                 }
  366.                 msgDiag = MsgDiagnostico.newInstance(TipoPdD.DELEGATA,
  367.                         idSoggetto,
  368.                         "ModI", requestInfo!=null && requestInfo.getProtocolContext()!=null ? requestInfo.getProtocolContext().getInterfaceName() : null,
  369.                         requestInfo,
  370.                         state);
  371.                 if(TipoPdD.DELEGATA.equals(tipoPdD)){
  372.                     msgDiag.setPrefixMsgPersonalizzati(MsgDiagnosticiProperties.MSG_DIAG_RICEZIONE_CONTENUTI_APPLICATIVI);
  373.                 }
  374.                 else {
  375.                     msgDiag.setPrefixMsgPersonalizzati(MsgDiagnosticiProperties.MSG_DIAG_RICEZIONE_BUSTE);
  376.                 }
  377.                 msgDiag.setPddContext(context, protocolFactory);
  378.                 String tipoDiagnostico = RuoloMessaggio.RICHIESTA.equals(ruoloMessaggio) ? ".richiesta." : ".risposta.";
  379.                
  380.                 // check config
  381.                
  382.                 boolean addSecurity = false;
  383.                 boolean securityMessageProfilePrevedeTokenLocale = securityMessageProfile!=null && !ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_UNDEFINED.equals(securityMessageProfile);
  384.                 if(securityMessageProfilePrevedeTokenLocale) {
  385.                     addSecurity = existsSecurityFlusso;
  386.                 }
  387.                
  388.                 boolean corniceSicurezza = ModIPropertiesUtils.isPropertySecurityMessageConCorniceSicurezza(aspc, nomePortType, azione);
  389.                 String patternCorniceSicurezza = null;
  390.                 String schemaCorniceSicurezza = null;
  391.                 if(corniceSicurezza) {
  392.                     patternCorniceSicurezza = ModIPropertiesUtils.readPropertySecurityMessageCorniceSicurezzaPattern(aspc, nomePortType, azione);
  393.                     if(patternCorniceSicurezza==null) {
  394.                         // backward compatibility
  395.                         patternCorniceSicurezza = ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_PATTERN_VALUE_OLD;
  396.                     }
  397.                     if(!ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_PATTERN_VALUE_OLD.equals(patternCorniceSicurezza)) {
  398.                         schemaCorniceSicurezza = ModIPropertiesUtils.readPropertySecurityMessageCorniceSicurezzaSchema(aspc, nomePortType, azione);
  399.                     }
  400.                 }
  401.                
  402.                 boolean bufferMessageReadOnly = this.modiProperties.isReadByPathBufferEnabled();

  403.                 boolean fruizione = isRichiesta;
  404.                
  405.                 boolean addAudit = fruizione && corniceSicurezza &&
  406.                         patternCorniceSicurezza!=null && !ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_PATTERN_VALUE_OLD.equals(patternCorniceSicurezza);
  407.                                
  408.                 boolean keystoreKidMode = ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0401.equals(securityMessageProfile)
  409.                         ||
  410.                         ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0402.equals(securityMessageProfile)
  411.                         ||
  412.                         !sorgenteLocale;
  413.                
  414.                 Map<String, Object> dynamicMap = null;
  415.                
  416.                 ModISecurityConfig securityConfig = null;
  417.                 ModISecurityConfig securityConfigAudit = null;
  418.                 ModIKeystoreConfig keystoreConfig = null;
  419.                
  420.                 boolean keystoreDefinitoInFruizione = false;
  421.                
  422.                 boolean keystoreDefinitoInTokenPolicy = false;
  423.                 String tokenPolicyKid = null;
  424.                 String tokenPolicyClientId = null;
  425.                
  426.                
  427.                 String headerTokenRest = null;
  428.                 String headerTokenRestIntegrity = null; // nel caso di Authorization insieme a Agid-JWT-Signature
  429.                 boolean integritaCustom = false;
  430.                
  431.                 if(addSecurity || addAudit) {
  432.                
  433.                     // dynamicMap
  434.                     Map<String, Object> dynamicMapRequest = null;
  435.                     if(RuoloMessaggio.RISPOSTA.equals(ruoloMessaggio)) {
  436.                         dynamicMapRequest = ModIUtilities.removeDynamicMapRequest(context);
  437.                     }
  438.                     if(dynamicMapRequest!=null) {
  439.                         dynamicMap = DynamicUtils.buildDynamicMapResponse(msg, context, busta, this.log, bufferMessageReadOnly, dynamicMapRequest);
  440.                     }
  441.                     else {
  442.                         dynamicMap = DynamicUtils.buildDynamicMap(msg, context, busta, this.log, bufferMessageReadOnly);
  443.                         ModIUtilities.saveDynamicMapRequest(context, dynamicMap);
  444.                     }
  445.                    
  446.                     // header
  447.                     Boolean multipleHeaderAuthorizationConfig = null;
  448.                     if(rest) {
  449.                         headerTokenRest = ModIPropertiesUtils.readPropertySecurityMessageHeader(aspc, nomePortType, azione, isRichiesta, filterPDND);
  450.                         if(headerTokenRest.contains(" ")) {
  451.                             String [] tmp = headerTokenRest.split(" ");
  452.                             if(tmp!=null && tmp.length==2 && tmp[0]!=null && tmp[1]!=null) {
  453.                                 headerTokenRest=tmp[0];
  454.                                 headerTokenRestIntegrity=tmp[1];
  455.                                 multipleHeaderAuthorizationConfig = true;
  456.                             }
  457.                         }
  458.                         integritaCustom = ModIPropertiesUtils.isPropertySecurityMessageHeaderCustom(aspc, nomePortType, azione, isRichiesta);
  459.                         /**
  460.                          * Lo registro nella busta solamente se lo aggiungo davvero dentro il metodo ModIImbustamentoRest
  461.                          *
  462.                          * if(integritaCustom) {
  463.                             String hdrCustom = headerTokenRest;
  464.                             if(multipleHeaderAuthorizationConfig!=null && multipleHeaderAuthorizationConfig && headerTokenRestIntegrity!=null) {
  465.                                 hdrCustom = headerTokenRestIntegrity;
  466.                             }
  467.                             busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_CUSTOM_HEADER,hdrCustom);
  468.                         }*/
  469.                     }
  470.                    
  471.                     // modalita Keystore
  472.                     KeystoreParams tokenPolicyKeystore = null;
  473.                     if(isRichiesta) {
  474.                        
  475.                         keystoreDefinitoInFruizione = ModIKeystoreConfig.isKeystoreDefinitoInFruizione(idSoggettoMittente, asps);
  476.                         if(!keystoreDefinitoInFruizione) {
  477.                             keystoreDefinitoInTokenPolicy = ModIKeystoreConfig.isKeystoreDefinitoInTokenPolicy(idSoggettoMittente, asps);
  478.                         }
  479.                        
  480.                         StringBuilder sbRequired = new StringBuilder();
  481.                         if(keystoreDefinitoInTokenPolicy) {
  482.                             PolicyNegoziazioneToken pnt = ImbustamentoUtils.readPolicyNegoziazioneToken(this.log, state, idSoggettoMittente, idServizio, azione, requestInfo, sbRequired);
  483.                             if(pnt!=null) {
  484.                                 tokenPolicyKeystore = ImbustamentoUtils.readKeystoreParams(this.log, pnt, sbRequired);
  485.                                 if(sbRequired.length()<=0) {
  486.                                     tokenPolicyClientId = ImbustamentoUtils.readClientId(this.log, pnt, sbRequired);
  487.                                 }
  488.                                 if(sbRequired.length()<=0) {
  489.                                     tokenPolicyKid = ImbustamentoUtils.readKID(this.log, pnt, tokenPolicyClientId, tokenPolicyKeystore, sbRequired);
  490.                                 }
  491.                                 if(sbRequired.length()>0) {
  492.                                     tokenPolicyKeystore=null; // almeno dopo segnalo l'errore registrato in sbRequired
  493.                                 }
  494.                             }
  495.                         }
  496.                        
  497.                         boolean erroreTP=false;
  498.                         boolean erroreSA=false;
  499.                         if(keystoreDefinitoInTokenPolicy) {
  500.                             if(tokenPolicyKeystore==null) {
  501.                                 erroreTP= true;
  502.                             }
  503.                         }
  504.                         else if((!keystoreDefinitoInFruizione) && sa==null) {
  505.                             erroreSA=true;
  506.                         }
  507.                            
  508.                         if(erroreTP || erroreSA) {
  509.                             boolean auditMsg = addAudit && patternCorniceSicurezza!=null && StringUtils.isNotEmpty(patternCorniceSicurezza);
  510.                             StringBuilder sb = new StringBuilder("'");
  511.                             if(securityMessageProfile!=null && StringUtils.isNotEmpty(securityMessageProfile)) {
  512.                                 sb.append(securityMessageProfile);
  513.                                 if(auditMsg) {
  514.                                     sb.append("' + '").append(patternCorniceSicurezza);
  515.                                 }
  516.                             }
  517.                             else if(auditMsg) {
  518.                                 sb.append(patternCorniceSicurezza);
  519.                             }
  520.                             else {
  521.                                 sb.append("-");
  522.                             }
  523.                             sb.append("'");
  524.                            
  525.                             String descrizioneErrore = erroreTP ? sbRequired.toString() : "l'identificazione di un applicativo";
  526.                            
  527.                             ProtocolException pe = new ProtocolException("Il profilo di sicurezza richiesto "+sb.toString()+" richiede "+descrizioneErrore);
  528.                             pe.setInteroperabilityError(true);
  529.                             throw pe;
  530.                         }
  531.                     }
  532.                    
  533.                     // security config
  534.                    
  535.                     if(addAudit) {
  536.                         securityConfigAudit = new ModISecurityConfig(msg, context, protocolFactory, state, requestInfo,
  537.                                 idSoggettoMittente, asps, sa,
  538.                                 rest, fruizione, isRichiesta,
  539.                                 patternCorniceSicurezza, schemaCorniceSicurezza,
  540.                                 busta, bustaRichiesta,
  541.                                 multipleHeaderAuthorizationConfig,
  542.                                 keystoreDefinitoInFruizione,
  543.                                 keystoreDefinitoInTokenPolicy, tokenPolicyKid, tokenPolicyClientId,
  544.                                 keystoreKidMode,
  545.                                 addSecurity, addAudit);
  546.                     }
  547.                    
  548.                     boolean keystoreKidModeSecurityToken = keystoreKidMode;
  549.                     if(rest && headerTokenRestIntegrity==null &&
  550.                         // un solo header
  551.                         (
  552.                                 ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0301.equals(securityMessageProfile)
  553.                                 ||
  554.                                 ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0302.equals(securityMessageProfile)
  555.                         )
  556.                     ){
  557.                         keystoreKidModeSecurityToken = false;
  558.                     }
  559.                    
  560.                     securityConfig = new ModISecurityConfig(msg, context, protocolFactory, state, requestInfo,
  561.                             idSoggettoMittente, asps, sa,
  562.                             rest, fruizione, isRichiesta,
  563.                             patternCorniceSicurezza, schemaCorniceSicurezza,
  564.                             busta, bustaRichiesta,
  565.                             multipleHeaderAuthorizationConfig,
  566.                             keystoreDefinitoInFruizione,
  567.                             keystoreDefinitoInTokenPolicy, tokenPolicyKid, tokenPolicyClientId,
  568.                             keystoreKidModeSecurityToken,
  569.                             addSecurity, addAudit);
  570.                    
  571.                     // keystore
  572.                    
  573.                     if(isRichiesta) {
  574.                    
  575.                         if(keystoreDefinitoInFruizione) {
  576.                             keystoreConfig = new ModIKeystoreConfig(fruizione, idSoggettoMittente, asps, securityMessageProfile);
  577.                         }
  578.                         else if(keystoreDefinitoInTokenPolicy) {
  579.                             keystoreConfig = new ModIKeystoreConfig(tokenPolicyKeystore);
  580.                         }
  581.                         else {
  582.                             keystoreConfig = new ModIKeystoreConfig(sa, securityMessageProfile);
  583.                         }
  584.                        
  585.                     }
  586.                     else {
  587.                        
  588.                         keystoreConfig = new ModIKeystoreConfig(fruizione, idSoggettoMittente, asps, securityMessageProfile);
  589.                        
  590.                     }
  591.                 }
  592.                                
  593.                 String purposeId = null;
  594.                 if(addSecurity || addAudit) {
  595.                     purposeId =  ModIPropertiesUtils.readPurposeId(configIntegrationReader, asps, idSoggettoMittente, azione);
  596.                 }
  597.                
  598.                 long now = DateManager.getTimeMillis();
  599.                
  600.                
  601.                 // security (ID_AUTH e INTEGRITY)
  602.                 if(addSecurity) {
  603.                                                                        
  604.                     boolean includiRequestDigest = ModIPropertiesUtils.isPropertySecurityMessageIncludiRequestDigest(aspc, nomePortType, azione);
  605.                    
  606.                     boolean signAttachments = false;
  607.                     if(!rest) {
  608.                         signAttachments = ModIPropertiesUtils.isAttachmentsSignature(aspc, nomePortType, azione, isRichiesta, msg);
  609.                     }
  610.                        
  611.                     if(rest) {
  612.                        
  613.                         boolean integritaX509 = ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0301.equals(securityMessageProfile) ||
  614.                                 ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0302.equals(securityMessageProfile);
  615.                         boolean integritaKid = ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0401.equals(securityMessageProfile) ||
  616.                                 ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0402.equals(securityMessageProfile);
  617.                         boolean integrita = integritaX509 || integritaKid;
  618.                         if(integrita) {
  619.                             // nop
  620.                         }
  621.                        
  622.                         // Integrity verrà generato solo se:
  623.                         // Nel caso di 2 header da generare localmente, quello integrity viene prodotto solo se c'è un payload o uno degli header indicati da firmare.
  624.                         // Nel caso di 1 solo header da generare localmente, l'integrity, e l'authorization prodotto tramite token policy lo stesso verrà generato solo se c'è un payload o uno degli header indicati da firmare.
  625.                         boolean addIntegrity = false;
  626.                         boolean signedHeaders = false;
  627.                         String integrityMode = null;
  628.                         if(securityConfig.getHttpHeaders()!=null && !securityConfig.getHttpHeaders().isEmpty()) {
  629.                             Map<String, List<String>> mapForceTransportHeaders = msg.getForceTransportHeaders();
  630.                             for (String httpHeader : securityConfig.getHttpHeaders()) {
  631.                                 if(!httpHeader.equalsIgnoreCase(HttpConstants.DIGEST)) {
  632.                                     List<String> values = ModIImbustamentoRest.getHeaderValues(ruoloMessaggio, msg, mapForceTransportHeaders, httpHeader);
  633.                                     if(values!=null && !values.isEmpty()) {
  634.                                         signedHeaders = true;
  635.                                         break;
  636.                                     }
  637.                                 }
  638.                             }
  639.                         }
  640.                         if(msg.castAsRest().hasContent() || signedHeaders) {
  641.                             addIntegrity = true;
  642.                         }
  643.                         else {/**Rilascio con issue 1625 else if(integritaCustom) {*/
  644.                             integrityMode = ModIPropertiesUtils.getPropertySecurityMessageHeaderCustomMode(aspc, nomePortType, azione, isRichiesta);
  645.                             addIntegrity =
  646.                                     (ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_HEADER_CUSTOM_MODE_VALUE_ALWAYS.equals(integrityMode))
  647.                                     ||
  648.                                     ( isRichiesta && ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_HEADER_CUSTOM_MODE_VALUE_RISPOSTE_CON_PAYLOAD_HTTP_QUALSIASI_RICHIESTA.equals(integrityMode) )
  649.                                     ||
  650.                                     ( !isRichiesta && ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_HEADER_CUSTOM_MODE_VALUE_RICHIESTE_CON_PAYLOAD_HTTP_QUALSIASI_RISPOSTA.equals(integrityMode) )
  651.                                     ;
  652.                         }
  653.                        
  654.                        
  655.                         if(headerTokenRestIntegrity==null) {
  656.                            
  657.                             // Il caso di 1 solo header da generare può succedere:
  658.                             // In presenza di un authorization prodotto tramite token policy dove a questo punto il token è per forza l'integrity
  659.                             // In presenza di un authorization locale con pattern senza integrity
  660.                             // In presenza di un authorization locale con pattern integrity e utilizzo di un solo header unico che contiene entrambe le funzionalità auth e integrity
  661.                             // In presenza di un authorization locale durante la fase della risposta, con indicazione di usare 2 header solo nella richiesta (opzione includi authorization nella risposta non selezionata)
  662.                             boolean addToken = false;
  663.                             if(sorgenteLocale) {
  664.                                 // devo generarlo se rappresenta anche l'authorization o se viene richiesto integrity
  665.                                 if(isRichiesta) {
  666.                                     addToken = true; // sicuramente rappresente l'identità di authorization
  667.                                 }
  668.                                 else {
  669.                                     String headerTokenRestOption = ModIPropertiesUtils.readPropertySecurityMessageHeaderRawOptionValue(aspc, nomePortType, azione, isRichiesta);
  670.                                     boolean opzioneDueHeaderRichiestaGeneraSoloIntegrityRisposta = ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_HEADER_VALUE_AUTHORIZATION_MODIPA.equals(headerTokenRestOption);
  671.                                     // il token deve essere generato sempre se rappresenta l'authorization come unica informazione. Se suddiviso tra due header il caso in cui non debba essere generato è se siamo nella risposta con indicazione di non generare authorization
  672.                                     if(!opzioneDueHeaderRichiestaGeneraSoloIntegrityRisposta) {
  673.                                         addToken = true;
  674.                                     }
  675.                                     else {
  676.                                         addToken = addIntegrity;
  677.                                     }                  
  678.                                 }
  679.                             }
  680.                             else {
  681.                                 addToken = addIntegrity;
  682.                             }
  683.                             if(addToken) {
  684.                            
  685.                                 String prefixMsgDiag = null;
  686.                                 if(HttpConstants.AUTHORIZATION.equalsIgnoreCase(headerTokenRest)) {
  687.                                     prefixMsgDiag = DIAGNOSTIC_ADD_TOKEN_ID_AUTH;
  688.                                 }
  689.                                 else {
  690.                                     prefixMsgDiag = DIAGNOSTIC_ADD_TOKEN_INTEGRITY;
  691.                                 }
  692.                                 try {
  693.                                     msgDiag.logPersonalizzato(prefixMsgDiag+tipoDiagnostico+DIAGNOSTIC_IN_CORSO);
  694.                                
  695.                                     ModIJWTToken modiToken = imbustamentoRest.addToken(msg, isRichiesta, context, keystoreConfig, securityConfig, busta,
  696.                                             securityMessageProfile, false, headerTokenRest,
  697.                                             corniceSicurezza, patternCorniceSicurezza,
  698.                                             null, // devo fornirlo solo durante la generazione dell'Audit Token
  699.                                             ruoloMessaggio, includiRequestDigest,
  700.                                             now, busta.getID(), ModIHeaderType.SINGLE, integritaCustom, integrityMode,
  701.                                             dynamicMap, requestInfo,
  702.                                             purposeId, sicurezzaRidefinitaOperazione);
  703.                                     protocolMessage.setBustaRawContent(new ModIBustaRawContent(headerTokenRest, modiToken.getToken()));
  704.                                    
  705.                                     CostantiPdD.addKeywordInCache(msgDiag, modiToken.isInCache(), context, CostantiPdD.KEY_INFO_IN_CACHE_FUNZIONE_MODI_TOKEN_AUTHORIZATION);
  706.                                     msgDiag.logPersonalizzato(prefixMsgDiag+tipoDiagnostico+DIAGNOSTIC_COMPLETATA);
  707.                                 }
  708.                                 catch(ProtocolException pe) {
  709.                                     msgDiag.addKeyword(CostantiPdD.KEY_ERRORE_PROCESSAMENTO, pe.getMessage());
  710.                                     msgDiag.logPersonalizzato(prefixMsgDiag+tipoDiagnostico+DIAGNOSTIC_FALLITA);
  711.                                     throw pe;
  712.                                 }
  713.                             }
  714.                            
  715.                         }
  716.                         else {
  717.                            
  718.                             String jtiAuthorization = busta.getID();
  719.                             String jtiIntegrity = busta.getID();
  720.                             if(!securityConfig.isMultipleHeaderUseSameJti()) {
  721.                                 if(securityConfig.isMultipleHeaderUseJtiAuthorizationAsIdMessaggio()) {
  722.                                     jtiIntegrity = newUniqueIdentifier();
  723.                                 }else {
  724.                                     jtiAuthorization = newUniqueIdentifier();
  725.                                 }
  726.                             }
  727.                            
  728.                             // Authorization
  729.                             String securityMessageProfileAuthorization = null;
  730.                             if(ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0301.equals(securityMessageProfile)
  731.                                     ||
  732.                                     ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0401.equals(securityMessageProfile)) {
  733.                                 securityMessageProfileAuthorization = ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM01;
  734.                             }
  735.                             else {
  736.                                 securityMessageProfileAuthorization = ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM02;
  737.                             }
  738.                            
  739.                             boolean useKIDforIdAUTH = false; // normalmente il token authorization sarà PDND, se cmq è locale lo genero uguale per il kid
  740.                             if(ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0401.equals(securityMessageProfile)
  741.                                     ||
  742.                                     ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0402.equals(securityMessageProfile)) {
  743.                                 useKIDforIdAUTH = true;
  744.                             }

  745.                             ModIJWTToken modiTokenAuthorization = null;
  746.                             try {
  747.                                 msgDiag.logPersonalizzato(DIAGNOSTIC_ADD_TOKEN_ID_AUTH+tipoDiagnostico+DIAGNOSTIC_IN_CORSO);
  748.                            
  749.                                 modiTokenAuthorization = imbustamentoRest.addToken(msg, isRichiesta, context, keystoreConfig, securityConfig, busta,
  750.                                         securityMessageProfileAuthorization, useKIDforIdAUTH, headerTokenRest,
  751.                                         corniceSicurezza, patternCorniceSicurezza,
  752.                                         null, // devo fornirlo solo durante la generazione dell'Audit Token
  753.                                         ruoloMessaggio, includiRequestDigest,
  754.                                         now, jtiAuthorization, ModIHeaderType.BOTH_AUTH, integritaCustom, integrityMode,
  755.                                         dynamicMap, requestInfo,
  756.                                         purposeId, sicurezzaRidefinitaOperazione);
  757.                                
  758.                                 CostantiPdD.addKeywordInCache(msgDiag, modiTokenAuthorization.isInCache(), context, CostantiPdD.KEY_INFO_IN_CACHE_FUNZIONE_MODI_TOKEN_AUTHORIZATION);
  759.                                 msgDiag.logPersonalizzato(DIAGNOSTIC_ADD_TOKEN_ID_AUTH+tipoDiagnostico+DIAGNOSTIC_COMPLETATA);
  760.                             }
  761.                             catch(ProtocolException pe) {
  762.                                 msgDiag.addKeyword(CostantiPdD.KEY_ERRORE_PROCESSAMENTO, pe.getMessage());
  763.                                 msgDiag.logPersonalizzato(DIAGNOSTIC_ADD_TOKEN_ID_AUTH+tipoDiagnostico+DIAGNOSTIC_FALLITA);
  764.                                 throw pe;
  765.                             }
  766.                            
  767.                             // Integrity
  768.                             // !! Nel caso di 2 header, quello integrity viene prodotto solo se c'è un payload o uno degli header indicati da firmare.
  769.                             ModIJWTToken modiTokenIntegrity = null;
  770.                             if(addIntegrity) {
  771.                                 try {
  772.                                     msgDiag.logPersonalizzato(DIAGNOSTIC_ADD_TOKEN_INTEGRITY+tipoDiagnostico+DIAGNOSTIC_IN_CORSO);
  773.                                    
  774.                                     boolean keystoreKidModeIntegrity = ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0401.equals(securityMessageProfile)
  775.                                             ||
  776.                                             ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0402.equals(securityMessageProfile);                                  
  777.                                     ModISecurityConfig securityConfigIntegrity = new ModISecurityConfig(msg, context, protocolFactory, state, requestInfo,  
  778.                                             idSoggettoMittente, asps, sa,
  779.                                             rest, fruizione, isRichiesta,
  780.                                             patternCorniceSicurezza, schemaCorniceSicurezza,
  781.                                             busta, bustaRichiesta,
  782.                                             false,
  783.                                             keystoreDefinitoInFruizione,
  784.                                             keystoreDefinitoInTokenPolicy, tokenPolicyKid, tokenPolicyClientId,
  785.                                             keystoreKidModeIntegrity,
  786.                                             addSecurity, addAudit);
  787.                                     modiTokenIntegrity = imbustamentoRest.addToken(msg, isRichiesta, context, keystoreConfig, securityConfigIntegrity, busta,
  788.                                             securityMessageProfile, false, headerTokenRestIntegrity,
  789.                                             corniceSicurezza, patternCorniceSicurezza,
  790.                                             null, // devo fornirlo solo durante la generazione dell'Audit Token
  791.                                             ruoloMessaggio, includiRequestDigest,
  792.                                             now, jtiIntegrity, ModIHeaderType.BOTH_INTEGRITY, integritaCustom, integrityMode,
  793.                                             dynamicMap, requestInfo,
  794.                                             purposeId, sicurezzaRidefinitaOperazione);
  795.                                    
  796.                                     // l'integrity non sarà mai in cache, ma il diagnostico e' condiviso
  797.                                     CostantiPdD.addKeywordInCache(msgDiag, modiTokenIntegrity.isInCache(), context, CostantiPdD.KEY_INFO_IN_CACHE_FUNZIONE_MODI_TOKEN_INTEGRITY);
  798.                                     msgDiag.logPersonalizzato(DIAGNOSTIC_ADD_TOKEN_INTEGRITY+tipoDiagnostico+DIAGNOSTIC_COMPLETATA);
  799.                                 }
  800.                                 catch(ProtocolException pe) {
  801.                                     msgDiag.addKeyword(CostantiPdD.KEY_ERRORE_PROCESSAMENTO, pe.getMessage());
  802.                                     msgDiag.logPersonalizzato(DIAGNOSTIC_ADD_TOKEN_INTEGRITY+tipoDiagnostico+DIAGNOSTIC_FALLITA);
  803.                                     throw pe;
  804.                                 }
  805.                             }
  806.                            
  807.                             if(modiTokenIntegrity!=null) {
  808.                                 protocolMessage.setBustaRawContent(new ModIBustaRawContent(modiTokenAuthorization.getToken(), headerTokenRestIntegrity, modiTokenIntegrity.getToken()));
  809.                             }
  810.                             else {
  811.                                 protocolMessage.setBustaRawContent(new ModIBustaRawContent(headerTokenRest, modiTokenAuthorization.getToken()));
  812.                             }
  813.                                                        
  814.                         }
  815.                     }
  816.                     else {
  817.                         // soap
  818.                         boolean integritaX509 = ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0301.equals(securityMessageProfile) ||
  819.                                 ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0302.equals(securityMessageProfile);
  820.                         boolean integritaKid = ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0401.equals(securityMessageProfile) ||
  821.                                 ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0402.equals(securityMessageProfile);
  822.                         boolean integrita = integritaX509 || integritaKid;
  823.                        
  824.                         String prefixMsgDiag = null;
  825.                         MapKey<String> mapKey = null;
  826.                         if(integrita) {
  827.                             prefixMsgDiag = DIAGNOSTIC_ADD_TOKEN_INTEGRITY;
  828.                             mapKey = CostantiPdD.KEY_INFO_IN_CACHE_FUNZIONE_MODI_TOKEN_INTEGRITY;
  829.                         }
  830.                         else {
  831.                             prefixMsgDiag = DIAGNOSTIC_ADD_TOKEN_ID_AUTH;
  832.                             mapKey = CostantiPdD.KEY_INFO_IN_CACHE_FUNZIONE_MODI_TOKEN_AUTHORIZATION;
  833.                         }
  834.                         try {
  835.                             msgDiag.logPersonalizzato(prefixMsgDiag+tipoDiagnostico+DIAGNOSTIC_IN_CORSO);
  836.                            
  837.                             boolean corniceSicurezzaLegacySoap = corniceSicurezza && !addAudit;
  838.                            
  839.                             SOAPEnvelope env = imbustamentoSoap.addSecurity(msg, isRichiesta, context, keystoreConfig, securityConfig, busta,
  840.                                     securityMessageProfile, corniceSicurezzaLegacySoap, ruoloMessaggio, includiRequestDigest, signAttachments,
  841.                                     dynamicMap, requestInfo);
  842.                             protocolMessage.setBustaRawContent(new ModIBustaRawContent(env));
  843.                            
  844.                             // il token SOAP non è mai in cache
  845.                             CostantiPdD.addKeywordInCache(msgDiag, false, context, mapKey);
  846.                             msgDiag.logPersonalizzato(prefixMsgDiag+tipoDiagnostico+DIAGNOSTIC_COMPLETATA);
  847.                         }
  848.                         catch(ProtocolException pe) {
  849.                             msgDiag.addKeyword(CostantiPdD.KEY_ERRORE_PROCESSAMENTO, pe.getMessage());
  850.                             msgDiag.logPersonalizzato(prefixMsgDiag+tipoDiagnostico+DIAGNOSTIC_FALLITA);
  851.                             throw pe;
  852.                         }
  853.                     }
  854.                    
  855.                 }
  856.                
  857.                 // audit (ID_AUDIT)
  858.                 if(addAudit) {
  859.                    
  860.                     busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_AUDIT_PATTERN,
  861.                             ModIPropertiesUtils.convertProfiloAuditToSDKValue(patternCorniceSicurezza));
  862.                     busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_AUDIT_SCHEMA,
  863.                             ModIPropertiesUtils.convertSchemaAuditToSDKValue(schemaCorniceSicurezza, this.modiProperties));
  864.                    
  865.                     if(imbustamentoRest==null) {
  866.                         // audit su api soap
  867.                         imbustamentoRest = new ModIImbustamentoRest(this.log);
  868.                     }
  869.                    
  870.                     String securityMessageProfileAudit = null;
  871.                     if(ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0301.equals(securityMessageProfile)
  872.                             ||
  873.                             ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0401.equals(securityMessageProfile)) {
  874.                         securityMessageProfileAudit = ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM01;
  875.                     }
  876.                     else {
  877.                         securityMessageProfileAudit = ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM02;
  878.                     }
  879.                                        
  880.                     boolean useKIDforAudit = false;
  881.                     if(ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0401.equals(securityMessageProfile)
  882.                             ||
  883.                             ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0402.equals(securityMessageProfile)
  884.                             ||
  885.                             !sorgenteLocale) {
  886.                         useKIDforAudit = true;
  887.                     }
  888.                    
  889.                     String headerTokenAudit = this.modiProperties.getSecurityTokenHeaderModIAudit();
  890.                    
  891.                     String jtiAudit = newUniqueIdentifier();
  892.                    
  893.                     try {
  894.                         msgDiag.logPersonalizzato("addTokenAudit.richiesta.inCorso");
  895.                    
  896.                         ModIJWTToken modiTokenAudit = imbustamentoRest.addToken(msg, isRichiesta, context, keystoreConfig, securityConfigAudit, busta,
  897.                                 securityMessageProfileAudit, useKIDforAudit, headerTokenAudit,
  898.                                 corniceSicurezza, patternCorniceSicurezza, schemaCorniceSicurezza,
  899.                                 ruoloMessaggio, false,
  900.                                 now, jtiAudit, ModIHeaderType.SINGLE, false, null,
  901.                                 dynamicMap, requestInfo,
  902.                                 purposeId, sicurezzaRidefinitaOperazione);
  903.                         if(protocolMessage.getBustaRawContent() instanceof ModIBustaRawContent) {
  904.                             ModIBustaRawContent raw = (ModIBustaRawContent) protocolMessage.getBustaRawContent();
  905.                             raw.getElement().setTokenAudit(headerTokenAudit, modiTokenAudit.getToken());
  906.                         }
  907.                        
  908.                         CostantiPdD.addKeywordInCache(msgDiag, modiTokenAudit.isInCache(), context, CostantiPdD.KEY_INFO_IN_CACHE_FUNZIONE_MODI_TOKEN_AUDIT);
  909.                         msgDiag.logPersonalizzato("addTokenAudit.richiesta.completata");
  910.                     }
  911.                     catch(ProtocolException pe) {
  912.                         msgDiag.addKeyword(CostantiPdD.KEY_ERRORE_PROCESSAMENTO, pe.getMessage());
  913.                         msgDiag.logPersonalizzato("addTokenAudit.richiesta.fallita");
  914.                         throw pe;
  915.                     }
  916.                 }

  917.             }
  918.            
  919.             protocolMessage.setMessage(msg);
  920.             return protocolMessage;
  921.        
  922.         }
  923.         catch(ProtocolException pe) {
  924.             if(pe.isInteroperabilityError() &&
  925.                 context!=null) {
  926.                 context.addObject(Costanti.ERRORE_VALIDAZIONE_PROTOCOLLO, Costanti.ERRORE_TRUE);
  927.             }
  928.             throw pe;
  929.         }
  930.         catch(Exception e){
  931.             throw new ProtocolException(e.getMessage(),e);
  932.         }
  933.        
  934.     }
  935.    
  936.     private OpenSPCoop2Message computeSignalHubMessage(OpenSPCoop2Message msg, Context context,
  937.             IProtocolFactory<?> protocolFactory, IState state) throws ProtocolException, UtilsException, DriverConfigurazioneException {
  938.        
  939.         // ottengo le informazioni inserite dall'handler
  940.         IDServizio idServizio = (IDServizio) context.get(ModICostanti.MODIPA_KEY_INFO_SIGNAL_HUB_SERVICE);
  941.         String objectId = (String) context.get(ModICostanti.MODIPA_KEY_INFO_SIGNAL_HUB_OBJECT_ID);
  942.         String objectType = (String) context.get(ModICostanti.MODIPA_KEY_INFO_SIGNAL_HUB_OBJECT_TYPE);
  943.         ModISignalHubOperation signalType = (ModISignalHubOperation) context.get(ModICostanti.MODIPA_KEY_INFO_SIGNAL_HUB_SIGNAL_TYPE);
  944.         String serviceId = (String) context.get(ModICostanti.MODIPA_KEY_INFO_SIGNAL_HUB_ESERVICE_ID);
  945.        
  946.         // configuro il generatore di numeri seriali
  947.         ConfigurazionePdD config = protocolFactory.getConfigurazionePdD();
  948.         IDSerialGenerator serialGenerator = new IDSerialGenerator(config.getLog(), state, config.getTipoDatabase());
  949.        
  950.         IDSerialGeneratorParameter serialGeneratorParameter = new IDSerialGeneratorParameter(protocolFactory.getProtocol());
  951.         serialGeneratorParameter.setSerializableTimeWaitMs(config.getAttesaAttivaJDBC());
  952.         serialGeneratorParameter.setSerializableNextIntervalTimeMs(config.getCheckIntervalJDBC());
  953.         serialGeneratorParameter.setTipo(IDSerialGeneratorType.NUMERIC);
  954.         serialGeneratorParameter.setWrap(true);
  955.         serialGeneratorParameter.setSize(256);
  956.         serialGeneratorParameter.setMaxValue(Long.MAX_VALUE);
  957.         serialGeneratorParameter.setInformazioneAssociataAlProgressivo(serviceId);
  958.        
  959.         // se mi trovo in condizione di seedupdate il signalId sara gia stato creato e inserito come objectId da govway
  960.         Long signalId;
  961.         if (signalType.equals(ModISignalHubOperation.SEEDUPDATE)) {
  962.             signalId = Long.valueOf(objectId);
  963.            
  964.             objectId = "-";
  965.             objectType = "-";
  966.         } else {
  967.            
  968.             // per le operazione UPDATE, CREATE, DELETE ottengo i dati per produrre il digest dell'id
  969.             DigestServiceParams param = obtainDigestServiceParam(context, idServizio, serialGenerator, serialGeneratorParameter);
  970.            
  971.             // configuro il generatore di digest
  972.             DigestConfig digestConfig = new DigestConfig();
  973.             digestConfig.setDigestType(param.getDigestAlgorithm());
  974.             digestConfig.setSaltLength(param.getSeed().length);
  975.             digestConfig.setHashComposition(this.modiProperties.getSignalHubHashCompose());
  976.             digestConfig.setBase64Encode(true);
  977.            
  978.             IDigest digestGenerator = DigestFactory.getDigest(this.log, digestConfig);
  979.            
  980.             // produco il digest e il numero seriale del segnale
  981.             objectId = new String(digestGenerator.digest(objectId.getBytes(), param.getSeed()));
  982.             signalId = Long.valueOf(serialGenerator.buildID(serialGeneratorParameter));
  983.         }
  984.        
  985.         // serializzo le informazioni prodotte in json
  986.         JSONUtils jsonUtils = JSONUtils.getInstance();
  987.         ObjectNode root = jsonUtils.newObjectNode();
  988.         root.put(ModICostanti.MODIPA_SIGNAL_HUB_ID_SIGNAL_ID, signalId);
  989.         root.put(ModICostanti.MODIPA_SIGNAL_HUB_ID_OBJECT_TYPE, objectType);
  990.         root.put(ModICostanti.MODIPA_SIGNAL_HUB_ID_OBJECT_ID, objectId);
  991.         root.put(ModICostanti.MODIPA_SIGNAL_HUB_ID_ESERVICE_ID, serviceId);
  992.         root.put(ModICostanti.MODIPA_SIGNAL_HUB_ID_SIGNAL_TYPE, signalType.toString());
  993.        
  994.        
  995.         // altero il messaggio govway in modo tale di restituire al backend il nuovo messaggio
  996.         TransportRequestContext transportRequestContext = msg.getTransportRequestContext();
  997.         String protocolName = msg.getProtocolName();
  998.         String transactionId = msg.getTransactionId();
  999.        
  1000.         msg = OpenSPCoop2MessageFactory.getDefaultMessageFactory().createMessage(
  1001.                 msg.getMessageType(),
  1002.                 msg.getMessageRole(),
  1003.                 HttpConstants.CONTENT_TYPE_JSON,
  1004.                 jsonUtils.toByteArray(root)).getMessage();
  1005.        
  1006.         msg.setTransportRequestContext(transportRequestContext);
  1007.         msg.setProtocolName(protocolName);
  1008.         msg.setTransactionId(transactionId);
  1009.        
  1010.         return msg;
  1011.     }
  1012.    
  1013.     private static final String ERROR_MESSAGE_SEED_NOT_UPDATED = "seed update non riuscito";
  1014.     private DigestServiceParams obtainDigestServiceParam(Context context, IDServizio idServizio, IDSerialGenerator serialGenerator, IDSerialGeneratorParameter serialGeneratorParameter) throws ProtocolException, UtilsException, DriverConfigurazioneException {      
  1015.        
  1016.         // ottengo il driver di configurazione
  1017.         Object db = ConfigurazionePdDReader.getDriverConfigurazionePdD();
  1018.         if (!(db instanceof DriverConfigurazioneDB))
  1019.             throw new ProtocolException("driver db non trovato");
  1020.        
  1021.         // ottengo il driver per le informazioni diagnostiche
  1022.         DigestServiceParamsDriver driver = new DigestServiceParamsDriver((DriverConfigurazioneDB) db);
  1023.         DigestServiceParams param = driver.getLastEntry(idServizio);
  1024.        
  1025.         // non esiste informazioni crittografiche valide devo rigenerarle
  1026.         if (param == null || !driver.isValid(param)) {
  1027.            
  1028.             RequestInfo reqInfo = (RequestInfo) context.getObject(org.openspcoop2.core.constants.Costanti.REQUEST_INFO);
  1029.            
  1030.             driver.acquireLock(reqInfo.getIdTransazione());
  1031.             try {
  1032.                
  1033.                 // riprovo a vedere se esistono informaizoni crittografiche valide prodotte da un altro thread nel frattempo
  1034.                 param = driver.getLastEntry(idServizio);
  1035.                 if (param != null && driver.isValid(param))
  1036.                     return param;
  1037.                
  1038.                 // genero nuove informazioni crittografiche
  1039.                 List<ProtocolProperty> eServiceProperties = SignalHubUtils.obtainSignalHubProtocolProperty(context);
  1040.                
  1041.                 // se non esiste un entry precedente so creando il primo seme, non devo inviare alcuna richiesta
  1042.                 if (param == null) {
  1043.                     param = SignalHubUtils.generateDigestServiceParams(idServizio, eServiceProperties, null);
  1044.                     driver.addNewEntry(param);
  1045.                     return param;
  1046.                 }
  1047.                
  1048.                 String seedSignalId = serialGenerator.buildID(serialGeneratorParameter);
  1049.                 param = SignalHubUtils.generateDigestServiceParams(idServizio, eServiceProperties, Long.valueOf(seedSignalId));

  1050.                 // invio la richiesta di SEEDUPDATE
  1051.                 sendSeedUpdateRequest(context, eServiceProperties, seedSignalId);
  1052.                
  1053.                 // posso inserire le nuove informazioni crittografiche
  1054.                 driver.addNewEntry(param);
  1055.                
  1056.             } finally {
  1057.                 driver.releaseLock();
  1058.             }
  1059.            
  1060.             // rimuovo le informazioni crittografiche vecchie
  1061.             driver.removeOldEntries(idServizio, this.modiProperties.getSignalHubDigestHistroy());
  1062.         }
  1063.        
  1064.         return param;
  1065.     }
  1066.    
  1067.     private void sendSeedUpdateRequest(Context context, List<ProtocolProperty> eServiceProperties, String seedSignalId) throws ProtocolException {
  1068.         RequestInfo reqInfo = (RequestInfo) context.getObject(org.openspcoop2.core.constants.Costanti.REQUEST_INFO);
  1069.         String eServiceId = ProtocolPropertiesUtils.getRequiredStringValuePropertyRegistry(eServiceProperties, ModICostanti.MODIPA_API_IMPL_INFO_ESERVICE_ID);
  1070.        
  1071.         // creo una richiesta e risposta servlet mock per inviare un segnale di SEEDUPDATE alla stessa porta delegata con le stesse credenziali
  1072.         MockHttpServletRequest req = new MockHttpServletRequest(reqInfo.getProtocolContext().getHttpServletRequest());
  1073.         MockHttpServletResponse res = new MockHttpServletResponse();
  1074.        
  1075.         Transaction transaction = null;
  1076.         try (MockServletInputStream is = new MockServletInputStream()) {
  1077.             // i segnali di SEEDUPDATE devono essere inserite negli header di default
  1078.             req.setInputStream(is);
  1079.             req.setHeader("GovWay-Signal-Type", List.of(ModISignalHubOperation.SEEDUPDATE.toString()));
  1080.             req.setHeader("GovWay-Signal-ObjectId", List.of(seedSignalId));
  1081.             req.setHeader("GovWay-Signal-ObjectType", List.of("seed"));
  1082.             req.setHeader("GovWay-Signal-ServiceId", List.of(eServiceId));
  1083.             req.setHeader("Content-Length", List.of("0"));
  1084.             req.setHeader("Content-Type", null);
  1085.            
  1086.             // rimuove la transazione corrente dal contesto in quanto verra eseguita la transazione per il SEEDUPDATE
  1087.             transaction = TransactionContext.removeTransaction(reqInfo.getIdTransazione());
  1088.        
  1089.             req.getRequestDispatcher(req.getPathInfo()).forward(req, res);
  1090.         } catch (Exception e) {
  1091.             throw newSeedUpdateException(e);
  1092.         } finally {
  1093.             try {
  1094.                 if (transaction != null)
  1095.                     TransactionContext.setTransactionThreadLocal(reqInfo.getIdTransazione(), transaction);
  1096.             } catch (TransactionNotExistsException e) {
  1097.                 // ignore should never happen
  1098.             }
  1099.         }
  1100.        
  1101.         // controllo che il backend abbia ritornato una risposta positiva di creazione del seme
  1102.         try {
  1103.             if (res.getStatus() != HttpServletResponse.SC_OK)
  1104.                 throw newSeedUpdateException("returnCode:"+res.getStatus());
  1105.             byte[] out = ((MockServletOutputStream)res.getOutputStream()).getByteArrayOutputStream().toByteArray();
  1106.            
  1107.             JSONUtils jsonUtils = JSONUtils.getInstance();
  1108.             JsonNode node = jsonUtils.getAsNode(out);
  1109.             if (node.get(ModICostanti.MODIPA_SIGNAL_HUB_ID_SIGNAL_ID).isNull())
  1110.                 throw newSeedUpdateException("signalId is null");
  1111.         } catch (IOException | UtilsException e) {
  1112.             throw newSeedUpdateException(e, "seed response invalid");
  1113.         }
  1114.     }
  1115.    
  1116.     private ProtocolException newSeedUpdateException(Exception e) {
  1117.         return newSeedUpdateException(e, null);
  1118.     }
  1119.     private ProtocolException newSeedUpdateException(String posizione) {
  1120.         return newSeedUpdateException(null, posizione);
  1121.     }
  1122.     private ProtocolException newSeedUpdateException(Exception e, String posizione) {
  1123.         String msgError = posizione!=null ? " ("+posizione+")" : "";
  1124.         msgError = ERROR_MESSAGE_SEED_NOT_UPDATED + msgError;
  1125.         if(this.log!=null && e!=null) {
  1126.             this.log.error("{}: {}",msgError,e.getMessage(),e);
  1127.         }
  1128.         return new ProtocolException(msgError);
  1129.     }
  1130.    
  1131. }