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.                         // Integrity verrà generato solo se:
  614.                         // Nel caso di 2 header da generare localmente, quello integrity viene prodotto solo se c'è un payload o uno degli header indicati da firmare.
  615.                         // 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.
  616.                         boolean addIntegrity = false;
  617.                         boolean signedHeaders = false;
  618.                         if(securityConfig.getHttpHeaders()!=null && !securityConfig.getHttpHeaders().isEmpty()) {
  619.                             Map<String, List<String>> mapForceTransportHeaders = msg.getForceTransportHeaders();
  620.                             for (String httpHeader : securityConfig.getHttpHeaders()) {
  621.                                 if(!httpHeader.equalsIgnoreCase(HttpConstants.DIGEST)) {
  622.                                     List<String> values = ModIImbustamentoRest.getHeaderValues(ruoloMessaggio, msg, mapForceTransportHeaders, httpHeader);
  623.                                     if(values!=null && !values.isEmpty()) {
  624.                                         signedHeaders = true;
  625.                                         break;
  626.                                     }
  627.                                 }
  628.                             }
  629.                         }
  630.                         if(msg.castAsRest().hasContent() || signedHeaders) {
  631.                             addIntegrity = true;
  632.                         }
  633.                         else if(integritaCustom) {
  634.                             addIntegrity = ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_HEADER_CUSTOM_MODE_VALUE_ALWAYS.equals(ModIPropertiesUtils.getPropertySecurityMessageHeaderCustomMode(aspc, nomePortType, azione, isRichiesta));
  635.                         }
  636.                        
  637.                        
  638.                         if(headerTokenRestIntegrity==null) {
  639.                            
  640.                             // 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.
  641.                             if(sorgenteLocale || addIntegrity) {
  642.                            
  643.                                 String prefixMsgDiag = null;
  644.                                 if(HttpConstants.AUTHORIZATION.equalsIgnoreCase(headerTokenRest)) {
  645.                                     prefixMsgDiag = DIAGNOSTIC_ADD_TOKEN_ID_AUTH;
  646.                                 }
  647.                                 else {
  648.                                     prefixMsgDiag = DIAGNOSTIC_ADD_TOKEN_INTEGRITY;
  649.                                 }
  650.                                 try {
  651.                                     msgDiag.logPersonalizzato(prefixMsgDiag+tipoDiagnostico+DIAGNOSTIC_IN_CORSO);
  652.                                
  653.                                     ModIJWTToken modiToken = imbustamentoRest.addToken(msg, isRichiesta, context, keystoreConfig, securityConfig, busta,
  654.                                             securityMessageProfile, false, headerTokenRest,
  655.                                             corniceSicurezza, patternCorniceSicurezza,
  656.                                             null, // devo fornirlo solo durante la generazione dell'Audit Token
  657.                                             ruoloMessaggio, includiRequestDigest,
  658.                                             now, busta.getID(), ModIHeaderType.SINGLE, integritaCustom,
  659.                                             dynamicMap, requestInfo,
  660.                                             purposeId, sicurezzaRidefinitaOperazione);
  661.                                     protocolMessage.setBustaRawContent(new ModIBustaRawContent(headerTokenRest, modiToken.getToken()));
  662.                                    
  663.                                     CostantiPdD.addKeywordInCache(msgDiag, modiToken.isInCache(), context, CostantiPdD.KEY_INFO_IN_CACHE_FUNZIONE_MODI_TOKEN_AUTHORIZATION);
  664.                                     msgDiag.logPersonalizzato(prefixMsgDiag+tipoDiagnostico+DIAGNOSTIC_COMPLETATA);
  665.                                 }
  666.                                 catch(ProtocolException pe) {
  667.                                     msgDiag.addKeyword(CostantiPdD.KEY_ERRORE_PROCESSAMENTO, pe.getMessage());
  668.                                     msgDiag.logPersonalizzato(prefixMsgDiag+tipoDiagnostico+DIAGNOSTIC_FALLITA);
  669.                                     throw pe;
  670.                                 }
  671.                             }
  672.                            
  673.                         }
  674.                         else {
  675.                            
  676.                             String jtiAuthorization = busta.getID();
  677.                             String jtiIntegrity = busta.getID();
  678.                             if(!securityConfig.isMultipleHeaderUseSameJti()) {
  679.                                 if(securityConfig.isMultipleHeaderUseJtiAuthorizationAsIdMessaggio()) {
  680.                                     jtiIntegrity = newUniqueIdentifier();
  681.                                 }else {
  682.                                     jtiAuthorization = newUniqueIdentifier();
  683.                                 }
  684.                             }
  685.                            
  686.                             // Authorization
  687.                             String securityMessageProfileAuthorization = null;
  688.                             if(ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0301.equals(securityMessageProfile)
  689.                                     ||
  690.                                     ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0401.equals(securityMessageProfile)) {
  691.                                 securityMessageProfileAuthorization = ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM01;
  692.                             }
  693.                             else {
  694.                                 securityMessageProfileAuthorization = ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM02;
  695.                             }
  696.                            
  697.                             boolean useKIDforIdAUTH = false; // normalmente il token authorization sarà PDND, se cmq è locale lo genero uguale per il kid
  698.                             if(ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0401.equals(securityMessageProfile)
  699.                                     ||
  700.                                     ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0402.equals(securityMessageProfile)) {
  701.                                 useKIDforIdAUTH = true;
  702.                             }

  703.                             ModIJWTToken modiTokenAuthorization = null;
  704.                             try {
  705.                                 msgDiag.logPersonalizzato(DIAGNOSTIC_ADD_TOKEN_ID_AUTH+tipoDiagnostico+DIAGNOSTIC_IN_CORSO);
  706.                            
  707.                                 modiTokenAuthorization = imbustamentoRest.addToken(msg, isRichiesta, context, keystoreConfig, securityConfig, busta,
  708.                                         securityMessageProfileAuthorization, useKIDforIdAUTH, headerTokenRest,
  709.                                         corniceSicurezza, patternCorniceSicurezza,
  710.                                         null, // devo fornirlo solo durante la generazione dell'Audit Token
  711.                                         ruoloMessaggio, includiRequestDigest,
  712.                                         now, jtiAuthorization, ModIHeaderType.BOTH_AUTH, integritaCustom,
  713.                                         dynamicMap, requestInfo,
  714.                                         purposeId, sicurezzaRidefinitaOperazione);
  715.                                
  716.                                 CostantiPdD.addKeywordInCache(msgDiag, modiTokenAuthorization.isInCache(), context, CostantiPdD.KEY_INFO_IN_CACHE_FUNZIONE_MODI_TOKEN_AUTHORIZATION);
  717.                                 msgDiag.logPersonalizzato(DIAGNOSTIC_ADD_TOKEN_ID_AUTH+tipoDiagnostico+DIAGNOSTIC_COMPLETATA);
  718.                             }
  719.                             catch(ProtocolException pe) {
  720.                                 msgDiag.addKeyword(CostantiPdD.KEY_ERRORE_PROCESSAMENTO, pe.getMessage());
  721.                                 msgDiag.logPersonalizzato(DIAGNOSTIC_ADD_TOKEN_ID_AUTH+tipoDiagnostico+DIAGNOSTIC_FALLITA);
  722.                                 throw pe;
  723.                             }
  724.                            
  725.                             // Integrity
  726.                             // !! Nel caso di 2 header, quello integrity viene prodotto solo se c'è un payload o uno degli header indicati da firmare.
  727.                             ModIJWTToken modiTokenIntegrity = null;
  728.                             if(addIntegrity) {
  729.                                 try {
  730.                                     msgDiag.logPersonalizzato(DIAGNOSTIC_ADD_TOKEN_INTEGRITY+tipoDiagnostico+DIAGNOSTIC_IN_CORSO);
  731.                                    
  732.                                     boolean keystoreKidModeIntegrity = ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0401.equals(securityMessageProfile)
  733.                                             ||
  734.                                             ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0402.equals(securityMessageProfile);                                  
  735.                                     ModISecurityConfig securityConfigIntegrity = new ModISecurityConfig(msg, context, protocolFactory, state, requestInfo,  
  736.                                             idSoggettoMittente, asps, sa,
  737.                                             rest, fruizione, isRichiesta,
  738.                                             patternCorniceSicurezza, schemaCorniceSicurezza,
  739.                                             busta, bustaRichiesta,
  740.                                             false,
  741.                                             keystoreDefinitoInFruizione,
  742.                                             keystoreDefinitoInTokenPolicy, tokenPolicyKid, tokenPolicyClientId,
  743.                                             keystoreKidModeIntegrity,
  744.                                             addSecurity, addAudit);
  745.                                     modiTokenIntegrity = imbustamentoRest.addToken(msg, isRichiesta, context, keystoreConfig, securityConfigIntegrity, busta,
  746.                                             securityMessageProfile, false, headerTokenRestIntegrity,
  747.                                             corniceSicurezza, patternCorniceSicurezza,
  748.                                             null, // devo fornirlo solo durante la generazione dell'Audit Token
  749.                                             ruoloMessaggio, includiRequestDigest,
  750.                                             now, jtiIntegrity, ModIHeaderType.BOTH_INTEGRITY, integritaCustom,
  751.                                             dynamicMap, requestInfo,
  752.                                             purposeId, sicurezzaRidefinitaOperazione);
  753.                                    
  754.                                     // l'integrity non sarà mai in cache, ma il diagnostico e' condiviso
  755.                                     CostantiPdD.addKeywordInCache(msgDiag, modiTokenIntegrity.isInCache(), context, CostantiPdD.KEY_INFO_IN_CACHE_FUNZIONE_MODI_TOKEN_INTEGRITY);
  756.                                     msgDiag.logPersonalizzato(DIAGNOSTIC_ADD_TOKEN_INTEGRITY+tipoDiagnostico+DIAGNOSTIC_COMPLETATA);
  757.                                 }
  758.                                 catch(ProtocolException pe) {
  759.                                     msgDiag.addKeyword(CostantiPdD.KEY_ERRORE_PROCESSAMENTO, pe.getMessage());
  760.                                     msgDiag.logPersonalizzato(DIAGNOSTIC_ADD_TOKEN_INTEGRITY+tipoDiagnostico+DIAGNOSTIC_FALLITA);
  761.                                     throw pe;
  762.                                 }
  763.                             }
  764.                            
  765.                             if(modiTokenIntegrity!=null) {
  766.                                 protocolMessage.setBustaRawContent(new ModIBustaRawContent(modiTokenAuthorization.getToken(), headerTokenRestIntegrity, modiTokenIntegrity.getToken()));
  767.                             }
  768.                             else {
  769.                                 protocolMessage.setBustaRawContent(new ModIBustaRawContent(headerTokenRest, modiTokenAuthorization.getToken()));
  770.                             }
  771.                                                        
  772.                         }
  773.                     }
  774.                     else {
  775.                         // soap
  776.                         boolean integritaX509 = ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0301.equals(securityMessageProfile) ||
  777.                                 ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0302.equals(securityMessageProfile);
  778.                         boolean integritaKid = ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0401.equals(securityMessageProfile) ||
  779.                                 ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0402.equals(securityMessageProfile);
  780.                         boolean integrita = integritaX509 || integritaKid;
  781.                        
  782.                         String prefixMsgDiag = null;
  783.                         MapKey<String> mapKey = null;
  784.                         if(integrita) {
  785.                             prefixMsgDiag = DIAGNOSTIC_ADD_TOKEN_INTEGRITY;
  786.                             mapKey = CostantiPdD.KEY_INFO_IN_CACHE_FUNZIONE_MODI_TOKEN_INTEGRITY;
  787.                         }
  788.                         else {
  789.                             prefixMsgDiag = DIAGNOSTIC_ADD_TOKEN_ID_AUTH;
  790.                             mapKey = CostantiPdD.KEY_INFO_IN_CACHE_FUNZIONE_MODI_TOKEN_AUTHORIZATION;
  791.                         }
  792.                         try {
  793.                             msgDiag.logPersonalizzato(prefixMsgDiag+tipoDiagnostico+DIAGNOSTIC_IN_CORSO);
  794.                            
  795.                             boolean corniceSicurezzaLegacySoap = corniceSicurezza && !addAudit;
  796.                            
  797.                             SOAPEnvelope env = imbustamentoSoap.addSecurity(msg, isRichiesta, context, keystoreConfig, securityConfig, busta,
  798.                                     securityMessageProfile, corniceSicurezzaLegacySoap, ruoloMessaggio, includiRequestDigest, signAttachments,
  799.                                     dynamicMap, requestInfo);
  800.                             protocolMessage.setBustaRawContent(new ModIBustaRawContent(env));
  801.                            
  802.                             // il token SOAP non è mai in cache
  803.                             CostantiPdD.addKeywordInCache(msgDiag, false, context, mapKey);
  804.                             msgDiag.logPersonalizzato(prefixMsgDiag+tipoDiagnostico+DIAGNOSTIC_COMPLETATA);
  805.                         }
  806.                         catch(ProtocolException pe) {
  807.                             msgDiag.addKeyword(CostantiPdD.KEY_ERRORE_PROCESSAMENTO, pe.getMessage());
  808.                             msgDiag.logPersonalizzato(prefixMsgDiag+tipoDiagnostico+DIAGNOSTIC_FALLITA);
  809.                             throw pe;
  810.                         }
  811.                     }
  812.                    
  813.                 }
  814.                
  815.                 // audit (ID_AUDIT)
  816.                 if(addAudit) {
  817.                    
  818.                     busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_AUDIT_PATTERN,
  819.                             ModIPropertiesUtils.convertProfiloAuditToSDKValue(patternCorniceSicurezza));
  820.                     busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_AUDIT_SCHEMA,
  821.                             ModIPropertiesUtils.convertSchemaAuditToSDKValue(schemaCorniceSicurezza, this.modiProperties));
  822.                    
  823.                     if(imbustamentoRest==null) {
  824.                         // audit su api soap
  825.                         imbustamentoRest = new ModIImbustamentoRest(this.log);
  826.                     }
  827.                    
  828.                     String securityMessageProfileAudit = null;
  829.                     if(ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0301.equals(securityMessageProfile)
  830.                             ||
  831.                             ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0401.equals(securityMessageProfile)) {
  832.                         securityMessageProfileAudit = ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM01;
  833.                     }
  834.                     else {
  835.                         securityMessageProfileAudit = ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM02;
  836.                     }
  837.                                        
  838.                     boolean useKIDforAudit = false;
  839.                     if(ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0401.equals(securityMessageProfile)
  840.                             ||
  841.                             ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0402.equals(securityMessageProfile)
  842.                             ||
  843.                             !sorgenteLocale) {
  844.                         useKIDforAudit = true;
  845.                     }
  846.                    
  847.                     String headerTokenAudit = this.modiProperties.getSecurityTokenHeaderModIAudit();
  848.                    
  849.                     String jtiAudit = newUniqueIdentifier();
  850.                    
  851.                     try {
  852.                         msgDiag.logPersonalizzato("addTokenAudit.richiesta.inCorso");
  853.                    
  854.                         ModIJWTToken modiTokenAudit = imbustamentoRest.addToken(msg, isRichiesta, context, keystoreConfig, securityConfigAudit, busta,
  855.                                 securityMessageProfileAudit, useKIDforAudit, headerTokenAudit,
  856.                                 corniceSicurezza, patternCorniceSicurezza, schemaCorniceSicurezza,
  857.                                 ruoloMessaggio, false,
  858.                                 now, jtiAudit, ModIHeaderType.SINGLE, false,
  859.                                 dynamicMap, requestInfo,
  860.                                 purposeId, sicurezzaRidefinitaOperazione);
  861.                         if(protocolMessage.getBustaRawContent() instanceof ModIBustaRawContent) {
  862.                             ModIBustaRawContent raw = (ModIBustaRawContent) protocolMessage.getBustaRawContent();
  863.                             raw.getElement().setTokenAudit(headerTokenAudit, modiTokenAudit.getToken());
  864.                         }
  865.                        
  866.                         CostantiPdD.addKeywordInCache(msgDiag, modiTokenAudit.isInCache(), context, CostantiPdD.KEY_INFO_IN_CACHE_FUNZIONE_MODI_TOKEN_AUDIT);
  867.                         msgDiag.logPersonalizzato("addTokenAudit.richiesta.completata");
  868.                     }
  869.                     catch(ProtocolException pe) {
  870.                         msgDiag.addKeyword(CostantiPdD.KEY_ERRORE_PROCESSAMENTO, pe.getMessage());
  871.                         msgDiag.logPersonalizzato("addTokenAudit.richiesta.fallita");
  872.                         throw pe;
  873.                     }
  874.                 }

  875.             }
  876.            
  877.             protocolMessage.setMessage(msg);
  878.             return protocolMessage;
  879.        
  880.         }
  881.         catch(ProtocolException pe) {
  882.             if(pe.isInteroperabilityError() &&
  883.                 context!=null) {
  884.                 context.addObject(Costanti.ERRORE_VALIDAZIONE_PROTOCOLLO, Costanti.ERRORE_TRUE);
  885.             }
  886.             throw pe;
  887.         }
  888.         catch(Exception e){
  889.             throw new ProtocolException(e.getMessage(),e);
  890.         }
  891.        
  892.     }
  893.    
  894.     private OpenSPCoop2Message computeSignalHubMessage(OpenSPCoop2Message msg, Context context,
  895.             IProtocolFactory<?> protocolFactory, IState state) throws ProtocolException, UtilsException, DriverConfigurazioneException, IOException {
  896.        
  897.         // ottengo le informazioni inserite dall'handler
  898.         IDServizio idServizio = (IDServizio) context.get(ModICostanti.MODIPA_KEY_INFO_SIGNAL_HUB_SERVICE);
  899.         String objectId = (String) context.get(ModICostanti.MODIPA_KEY_INFO_SIGNAL_HUB_OBJECT_ID);
  900.         String objectType = (String) context.get(ModICostanti.MODIPA_KEY_INFO_SIGNAL_HUB_OBJECT_TYPE);
  901.         ModISignalHubOperation signalType = (ModISignalHubOperation) context.get(ModICostanti.MODIPA_KEY_INFO_SIGNAL_HUB_SIGNAL_TYPE);
  902.         String serviceId = (String) context.get(ModICostanti.MODIPA_KEY_INFO_SIGNAL_HUB_ESERVICE_ID);
  903.        
  904.         // configuro il generatore di numeri seriali
  905.         ConfigurazionePdD config = protocolFactory.getConfigurazionePdD();
  906.         IDSerialGenerator serialGenerator = new IDSerialGenerator(config.getLog(), state, config.getTipoDatabase());
  907.        
  908.         IDSerialGeneratorParameter serialGeneratorParameter = new IDSerialGeneratorParameter(protocolFactory.getProtocol());
  909.         serialGeneratorParameter.setSerializableTimeWaitMs(config.getAttesaAttivaJDBC());
  910.         serialGeneratorParameter.setSerializableNextIntervalTimeMs(config.getCheckIntervalJDBC());
  911.         serialGeneratorParameter.setTipo(IDSerialGeneratorType.NUMERIC);
  912.         serialGeneratorParameter.setWrap(true);
  913.         serialGeneratorParameter.setSize(256);
  914.         serialGeneratorParameter.setMaxValue(Long.MAX_VALUE);
  915.         serialGeneratorParameter.setInformazioneAssociataAlProgressivo(serviceId);
  916.        
  917.         // se mi trovo in condizione di seedupdate il signalId sara gia stato creato e inserito come objectId da govway
  918.         Long signalId;
  919.         if (signalType.equals(ModISignalHubOperation.SEEDUPDATE)) {
  920.             signalId = Long.valueOf(objectId);
  921.            
  922.             objectId = "-";
  923.             objectType = "-";
  924.         } else {
  925.            
  926.             // per le operazione UPDATE, CREATE, DELETE ottengo i dati per produrre il digest dell'id
  927.             DigestServiceParams param = obtainDigestServiceParam(context, idServizio, serialGenerator, serialGeneratorParameter);
  928.            
  929.             // configuro il generatore di digest
  930.             DigestConfig digestConfig = new DigestConfig();
  931.             digestConfig.setDigestType(param.getDigestAlgorithm());
  932.             digestConfig.setSaltLength(param.getSeed().length);
  933.             digestConfig.setHashComposition(this.modiProperties.getSignalHubHashCompose());
  934.             digestConfig.setBase64Encode(true);
  935.            
  936.             IDigest digestGenerator = DigestFactory.getDigest(this.log, digestConfig);
  937.            
  938.             // produco il digest e il numero seriale del segnale
  939.             objectId = new String(digestGenerator.digest(objectId.getBytes(), param.getSeed()));
  940.             signalId = Long.valueOf(serialGenerator.buildID(serialGeneratorParameter));
  941.         }
  942.        
  943.         // serializzo le informazioni prodotte in json
  944.         JSONUtils jsonUtils = JSONUtils.getInstance();
  945.         ObjectNode root = jsonUtils.newObjectNode();
  946.         root.put(ModICostanti.MODIPA_SIGNAL_HUB_ID_SIGNAL_ID, signalId);
  947.         root.put(ModICostanti.MODIPA_SIGNAL_HUB_ID_OBJECT_TYPE, objectType);
  948.         root.put(ModICostanti.MODIPA_SIGNAL_HUB_ID_OBJECT_ID, objectId);
  949.         root.put(ModICostanti.MODIPA_SIGNAL_HUB_ID_ESERVICE_ID, serviceId);
  950.         root.put(ModICostanti.MODIPA_SIGNAL_HUB_ID_SIGNAL_TYPE, signalType.toString());
  951.        
  952.        
  953.         // altero il messaggio govway in modo tale di restituire al backend il nuovo messaggio
  954.         TransportRequestContext transportRequestContext = msg.getTransportRequestContext();
  955.         String protocolName = msg.getProtocolName();
  956.         String transactionId = msg.getTransactionId();
  957.        
  958.         msg = OpenSPCoop2MessageFactory.getDefaultMessageFactory().createMessage(
  959.                 msg.getMessageType(),
  960.                 msg.getMessageRole(),
  961.                 HttpConstants.CONTENT_TYPE_JSON,
  962.                 jsonUtils.toByteArray(root)).getMessage();
  963.        
  964.         msg.setTransportRequestContext(transportRequestContext);
  965.         msg.setProtocolName(protocolName);
  966.         msg.setTransactionId(transactionId);
  967.        
  968.         return msg;
  969.     }
  970.    
  971.     private static final String ERROR_MESSAGE_SEED_NOT_UPDATED = "seed update non riuscito";
  972.     private DigestServiceParams obtainDigestServiceParam(Context context, IDServizio idServizio, IDSerialGenerator serialGenerator, IDSerialGeneratorParameter serialGeneratorParameter) throws ProtocolException, UtilsException, DriverConfigurazioneException, IOException {    
  973.        
  974.         // ottengo il driver di configurazione
  975.         Object db = ConfigurazionePdDReader.getDriverConfigurazionePdD();
  976.         if (!(db instanceof DriverConfigurazioneDB))
  977.             throw new ProtocolException("driver db non trovato");
  978.        
  979.         // ottengo il driver per le informazioni diagnostiche
  980.         DigestServiceParamsDriver driver = new DigestServiceParamsDriver((DriverConfigurazioneDB) db);
  981.         DigestServiceParams param = driver.getValidEntry(idServizio);
  982.        
  983.         // non esiste informazioni crittografiche valide devo rigenerarle
  984.         if (param == null) {
  985.             RequestInfo reqInfo = (RequestInfo) context.getObject(org.openspcoop2.core.constants.Costanti.REQUEST_INFO);
  986.            
  987.             driver.acquireLock(reqInfo.getIdTransazione());
  988.             try (MockServletInputStream is = new MockServletInputStream()) {
  989.                
  990.                 // riprovo a vedere se esistono informaizoni crittografiche valide prodotte da un altro thread nel frattempo
  991.                 param = driver.getValidEntry(idServizio);
  992.                 if (param != null)
  993.                     return param;
  994.                
  995.                 // genero nuove informazioni crittografiche
  996.                 List<ProtocolProperty> eServiceProperties = SignalHubUtils.obtainSignalHubProtocolProperty(context);
  997.                
  998.                 String seedSignalId = serialGenerator.buildID(serialGeneratorParameter);
  999.                 param = SignalHubUtils.generateDigestServiceParams(idServizio, eServiceProperties, Long.valueOf(seedSignalId));

  1000.                 String eServiceId = ProtocolPropertiesUtils.getRequiredStringValuePropertyRegistry(eServiceProperties, ModICostanti.MODIPA_API_IMPL_INFO_ID_ESERVICE_ID);
  1001.                
  1002.                
  1003.                 // creo una richiesta e risposta servlet mock per inviare un segnale di SEEDUPDATE alla stessa porta delegata con le stesse credenziali
  1004.                 MockHttpServletRequest req = new MockHttpServletRequest(reqInfo.getProtocolContext().getHttpServletRequest());
  1005.                 MockHttpServletResponse res = new MockHttpServletResponse();
  1006.                
  1007.                 // i segnali di SEEDUPDATE devono essere inserite negli header di default
  1008.                 req.setInputStream(is);
  1009.                 req.setHeader("GovWay-Signal-Type", List.of(ModISignalHubOperation.SEEDUPDATE.toString()));
  1010.                 req.setHeader("GovWay-Signal-ObjectId", List.of(seedSignalId));
  1011.                 req.setHeader("GovWay-Signal-ObjectType", List.of("seed"));
  1012.                 req.setHeader("GovWay-Signal-ServiceId", List.of(eServiceId));
  1013.                 req.setHeader("Content-Length", List.of("0"));
  1014.                 req.setHeader("Content-Type", null);
  1015.                
  1016.                 // rimuove la transazione corrente dal contesto in quanto verra eseguita la transazione per il SEEDUPDATE
  1017.                 Transaction transaction = TransactionContext.removeTransaction(reqInfo.getIdTransazione());
  1018.                
  1019.                 try {
  1020.                     req.getRequestDispatcher(req.getPathInfo()).forward(req, res);
  1021.                 } catch (Exception e) {
  1022.                     throw newSeedUpdateException(e);
  1023.                 } finally {
  1024.                     try {
  1025.                         TransactionContext.setTransactionThreadLocal(reqInfo.getIdTransazione(), transaction);
  1026.                     } catch (TransactionNotExistsException e) {
  1027.                         // ignore should never happen
  1028.                     }
  1029.                 }
  1030.                
  1031.                 // controllo che il backend abbia ritornato una risposta positiva di creazione del seme
  1032.                 try {
  1033.                     if (res.getStatus() != HttpServletResponse.SC_OK) {
  1034.                         throw newSeedUpdateException("returnCode:"+res.getStatus());
  1035.                     }
  1036.                     byte[] out = ((MockServletOutputStream)res.getOutputStream()).getByteArrayOutputStream().toByteArray();
  1037.                    
  1038.                     JSONUtils jsonUtils = JSONUtils.getInstance();
  1039.                     JsonNode node = jsonUtils.getAsNode(out);
  1040.                     if (node.get(ModICostanti.MODIPA_SIGNAL_HUB_ID_SIGNAL_ID).isNull())
  1041.                         throw newSeedUpdateException("signalId is null");
  1042.                 } catch (IOException e) {
  1043.                     throw newSeedUpdateException(e, "seed response invalid");
  1044.                 }
  1045.                
  1046.                 // posso inserire le nuove informazioni crittografiche
  1047.                 driver.addNewEntry(param);
  1048.                
  1049.             } finally {
  1050.                 driver.releaseLock();
  1051.             }
  1052.            
  1053.             // rimuovo le informazioni crittografiche vecchie
  1054.             driver.removeOldEntries(idServizio, this.modiProperties.getSignalHubDigestHistroy());
  1055.         }
  1056.        
  1057.         return param;
  1058.     }
  1059.     private ProtocolException newSeedUpdateException(Exception e) {
  1060.         return newSeedUpdateException(e, null);
  1061.     }
  1062.     private ProtocolException newSeedUpdateException(String posizione) {
  1063.         return newSeedUpdateException(null, posizione);
  1064.     }
  1065.     private ProtocolException newSeedUpdateException(Exception e, String posizione) {
  1066.         String msgError = posizione!=null ? " ("+posizione+")" : "";
  1067.         msgError = ERROR_MESSAGE_SEED_NOT_UPDATED + msgError;
  1068.         if(this.log!=null && e!=null) {
  1069.             this.log.error("{}: {}",msgError,e.getMessage(),e);
  1070.         }
  1071.         return new ProtocolException(msgError);
  1072.     }
  1073.    
  1074. }