AutenticazioneSsl.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.pdd.core.autenticazione.pa;

  21. import java.security.cert.CertStore;
  22. import java.util.ArrayList;
  23. import java.util.List;

  24. import org.openspcoop2.core.commons.CoreException;
  25. import org.openspcoop2.core.config.Proprieta;
  26. import org.openspcoop2.core.id.IDServizioApplicativo;
  27. import org.openspcoop2.core.id.IDSoggetto;
  28. import org.openspcoop2.core.registry.driver.DriverRegistroServiziNotFound;
  29. import org.openspcoop2.pdd.config.ConfigurazionePdDManager;
  30. import org.openspcoop2.pdd.config.CostantiProprieta;
  31. import org.openspcoop2.pdd.config.OpenSPCoop2Properties;
  32. import org.openspcoop2.pdd.core.autenticazione.AutenticazioneException;
  33. import org.openspcoop2.pdd.core.autenticazione.WWWAuthenticateConfig;
  34. import org.openspcoop2.pdd.core.credenziali.Credenziali;
  35. import org.openspcoop2.pdd.core.keystore.GestoreKeystoreCaching;
  36. import org.openspcoop2.pdd.logger.OpenSPCoop2Logger;
  37. import org.openspcoop2.protocol.engine.ConfigurazioneFiltroServiziApplicativi;
  38. import org.openspcoop2.protocol.engine.constants.Costanti;
  39. import org.openspcoop2.protocol.registry.RegistroServiziManager;
  40. import org.openspcoop2.protocol.sdk.constants.ErroriCooperazione;
  41. import org.openspcoop2.protocol.sdk.constants.IntegrationFunctionError;
  42. import org.openspcoop2.protocol.sdk.state.RequestInfo;
  43. import org.openspcoop2.security.keystore.cache.GestoreOCSPResource;
  44. import org.openspcoop2.security.keystore.cache.GestoreOCSPValidator;
  45. import org.openspcoop2.utils.LoggerBuffer;
  46. import org.openspcoop2.utils.UtilsMultiException;
  47. import org.openspcoop2.utils.certificate.CertificateInfo;
  48. import org.openspcoop2.utils.certificate.KeyStore;
  49. import org.openspcoop2.utils.transport.http.IOCSPValidator;
  50. import org.openspcoop2.utils.transport.http.OCSPResponseException;

  51. /**
  52.  * Classe che implementa una autenticazione BASIC.
  53.  *
  54.  * @author Andrea Poli (apoli@link.it)
  55.  * @author $Author$
  56.  * @version $Rev$, $Date$
  57.  */

  58. public class AutenticazioneSsl extends AbstractAutenticazioneBase {

  59.     private boolean logError = true;
  60.     @Override
  61.     public void setLogError(boolean logError) {
  62.         this.logError = logError;
  63.     }
  64.    
  65.     @Override
  66.     public EsitoAutenticazionePortaApplicativa process(DatiInvocazionePortaApplicativa datiInvocazione) throws AutenticazioneException{

  67.         EsitoAutenticazionePortaApplicativa esito = new EsitoAutenticazionePortaApplicativa();
  68.        
  69.         if(datiInvocazione==null) {
  70.             throw new AutenticazioneException("Param datiInvocazione is null");
  71.         }
  72.        
  73.         OpenSPCoop2Properties op2Properties = OpenSPCoop2Properties.getInstance();
  74.         WWWAuthenticateConfig wwwAuthenticateConfig = op2Properties.getRealmAutenticazioneHttpsWWWAuthenticateConfig();
  75.        
  76.         Credenziali credenziali = datiInvocazione.getInfoConnettoreIngresso().getCredenziali();
  77.        
  78.         RequestInfo requestInfo = datiInvocazione.getRequestInfo();
  79.        
  80.         String subject = credenziali.getSubject();
  81.         String issuer = credenziali.getIssuer();
  82.         CertificateInfo certificate = null;

  83.         // Controllo credenziali fornite
  84.         if( subject==null || "".equals(subject) ){
  85.             esito.setErroreCooperazione(IntegrationFunctionError.AUTHENTICATION_CREDENTIALS_NOT_FOUND, ErroriCooperazione.AUTENTICAZIONE_FALLITA_CREDENZIALI_NON_FORNITE.getErroreCooperazione());
  86.             esito.setClientAuthenticated(false);
  87.             esito.setClientIdentified(false);
  88.             if(wwwAuthenticateConfig!=null) {
  89.                 esito.setWwwAuthenticateErrorHeader(wwwAuthenticateConfig.buildWWWAuthenticateHeaderValue_notFound());
  90.             }
  91.             return esito;
  92.         }
  93.         if(credenziali.getCertificate()!=null) {
  94.             certificate = credenziali.getCertificate().getCertificate();
  95.            
  96.             List<Proprieta> proprieta = null;
  97.             if(datiInvocazione.getPa()!=null) {
  98.                 proprieta = datiInvocazione.getPa().getProprietaList();
  99.             }
  100.             else if(datiInvocazione.getPd()!=null) {
  101.                 proprieta = datiInvocazione.getPd().getProprietaList();
  102.             }
  103.            
  104.             boolean checkValid = false;
  105.             boolean trustStore = false;
  106.             KeyStore trustStoreCertificatiX509 = null;
  107.             CertStore trustStoreCertificatiX509crls = null;
  108.             IOCSPValidator ocspValidator = null;
  109.             try {
  110.                 checkValid = CostantiProprieta.isAutenticazioneHttpsValidityCheck(proprieta, op2Properties.isAutenticazioneHttpsPortaApplicativaValidityCheck());
  111.                 trustStore = CostantiProprieta.isAutenticazioneHttpsTrustStore(proprieta, op2Properties.getAutenticazioneHttpsPortaApplicativaTruststorePath());
  112.                 if(trustStore) {
  113.                     String path = CostantiProprieta.getAutenticazioneHttpsTrustStorePath(proprieta, op2Properties.getAutenticazioneHttpsPortaApplicativaTruststorePath());
  114.                     if(path!=null) {
  115.                         try {
  116.                             String password = CostantiProprieta.getAutenticazioneHttpsTrustStorePassword(proprieta, op2Properties.getAutenticazioneHttpsPortaApplicativaTruststorePassword());
  117.                             String type = CostantiProprieta.getAutenticazioneHttpsTrustStoreType(proprieta, op2Properties.getAutenticazioneHttpsPortaApplicativaTruststoreType());
  118.                             trustStoreCertificatiX509 = GestoreKeystoreCaching.getMerlinTruststore(requestInfo, path,
  119.                                     type,
  120.                                     password).getTrustStore();
  121.                         }catch(Exception e){
  122.                             throw new CoreException("Errore durante la lettura del truststore indicato ("+path+"): "+e.getMessage());
  123.                         }
  124.                     }
  125.                    
  126.                     if(trustStoreCertificatiX509!=null) {
  127.                        
  128.                         String crl = CostantiProprieta.getAutenticazioneHttpsTrustStoreCRLs(proprieta, op2Properties.getAutenticazioneHttpsPortaApplicativaTruststoreCRLs());
  129.                                                
  130.                         boolean crlByOcsp = false;
  131.                         String ocspPolicy = CostantiProprieta.getAutenticazioneHttpsTrustStoreOCSPPolicy(proprieta, op2Properties.getAutenticazioneHttpsPortaApplicativaTruststoreOCSPPolicy());
  132.                         if(ocspPolicy!=null) {
  133.                             LoggerBuffer lb = new LoggerBuffer();
  134.                             lb.setLogDebug(OpenSPCoop2Logger.getLoggerOpenSPCoopCore());
  135.                             lb.setLogError(OpenSPCoop2Logger.getLoggerOpenSPCoopCore());
  136.                             GestoreOCSPResource ocspResourceReader = new GestoreOCSPResource(requestInfo);
  137.                             try {
  138.                                 ocspValidator = new GestoreOCSPValidator(requestInfo, lb,
  139.                                         trustStoreCertificatiX509,
  140.                                         crl,
  141.                                         ocspPolicy,
  142.                                         ocspResourceReader);
  143.                             }catch(Exception e){
  144.                                 throw new CoreException("Errore durante l'inizializzazione del gestore della policy OCSP ("+ocspPolicy+"): "+e.getMessage());
  145.                             }
  146.                             if(ocspValidator!=null) {
  147.                                 GestoreOCSPValidator gOcspValidator = (GestoreOCSPValidator) ocspValidator;
  148.                                 if(gOcspValidator.getOcspConfig()!=null) {
  149.                                     crlByOcsp = gOcspValidator.getOcspConfig().isCrl();
  150.                                 }
  151.                             }
  152.                         }
  153.                        
  154.                         if(crl!=null && !crlByOcsp) {
  155.                             try {
  156.                                 trustStoreCertificatiX509crls = GestoreKeystoreCaching.getCRLCertstore(requestInfo, crl).getCertStore();
  157.                             }catch(Exception e){
  158.                                 throw new CoreException("Errore durante la lettura delle CRLs ("+crl+"): "+e.getMessage());
  159.                             }
  160.                         }
  161.                     }
  162.                 }
  163.             }catch(Exception e) {
  164.                 if(this.logError) {
  165.                     OpenSPCoop2Logger.getLoggerOpenSPCoopCore().error("AutenticazioneSsl non riuscita",e);
  166.                 }
  167.                 esito.setErroreCooperazione(IntegrationFunctionError.INTERNAL_REQUEST_ERROR, ErroriCooperazione.ERRORE_GENERICO_PROCESSAMENTO_MESSAGGIO.getErroreCooperazione());
  168.                 esito.setClientIdentified(false);
  169.                 esito.setEccezioneProcessamento(e);
  170.                 return esito;
  171.             }
  172.            
  173.             if(checkValid
  174.                     &&
  175.                     trustStoreCertificatiX509crls==null) { // altrimenti la validita' viene verificata insieme alle CRL
  176.                 try {
  177.                     certificate.checkValid();
  178.                 }catch(Exception e) {
  179.                     esito.setErroreCooperazione(IntegrationFunctionError.AUTHENTICATION_INVALID_CREDENTIALS,
  180.                             ErroriCooperazione.AUTENTICAZIONE_FALLITA_CREDENZIALI_FORNITE_NON_CORRETTE.getErroreCredenzialiForniteNonCorrette(e.getMessage()));
  181.                     esito.setClientAuthenticated(false);
  182.                     esito.setClientIdentified(false);
  183.                     if(wwwAuthenticateConfig!=null) {
  184.                         esito.setWwwAuthenticateErrorHeader(wwwAuthenticateConfig.buildWWWAuthenticateHeaderValue_invalid());
  185.                     }
  186.                     return esito;
  187.                 }
  188.             }
  189.            
  190.             if(trustStoreCertificatiX509!=null) {
  191.                 try {
  192.                     if(certificate.isVerified(trustStoreCertificatiX509, true)==false) {
  193.                         throw new CoreException("Certificato non verificabile rispetto alle CA conosciute");
  194.                     }
  195.                     if(trustStoreCertificatiX509crls!=null) {
  196.                         try {
  197.                             certificate.checkValid(trustStoreCertificatiX509crls, trustStoreCertificatiX509);
  198.                         }catch(Throwable t) {
  199.                             throw new CoreException("Certificato non valido: "+t.getMessage());
  200.                         }
  201.                     }
  202.                 }catch(Exception e) {
  203.                     esito.setErroreCooperazione(IntegrationFunctionError.AUTHENTICATION_INVALID_CREDENTIALS,
  204.                             ErroriCooperazione.AUTENTICAZIONE_FALLITA_CREDENZIALI_FORNITE_NON_CORRETTE.getErroreCredenzialiForniteNonCorrette(e.getMessage()));
  205.                     esito.setClientAuthenticated(false);
  206.                     esito.setClientIdentified(false);
  207.                     if(wwwAuthenticateConfig!=null) {
  208.                         esito.setWwwAuthenticateErrorHeader(wwwAuthenticateConfig.buildWWWAuthenticateHeaderValue_invalid());
  209.                     }
  210.                     return esito;
  211.                 }
  212.             }
  213.            
  214.             if(ocspValidator!=null) {
  215.                 try {
  216.                     ocspValidator.valid(certificate.getCertificate());
  217.                 }catch(Throwable t) {
  218.                     esito.setErroreCooperazione(IntegrationFunctionError.AUTHENTICATION_INVALID_CREDENTIALS,
  219.                             ErroriCooperazione.AUTENTICAZIONE_FALLITA_CREDENZIALI_FORNITE_NON_CORRETTE.getErroreCredenzialiForniteNonCorrette(t.getMessage()));
  220.                     esito.setClientAuthenticated(false);
  221.                     esito.setClientIdentified(false);
  222.                     if(!(t instanceof OCSPResponseException)) {
  223.                         esito.setNoCache(true);
  224.                     }
  225.                     if(wwwAuthenticateConfig!=null) {
  226.                         esito.setWwwAuthenticateErrorHeader(wwwAuthenticateConfig.buildWWWAuthenticateHeaderValue_invalid());
  227.                     }
  228.                     return esito;
  229.                 }
  230.             }
  231.            
  232.         }
  233.        
  234.         // Essendoci l'identita' del chiamante, il client e' stato autenticato o da un frontend o dall'application server stesso
  235.         esito.setClientAuthenticated(true);
  236.         esito.setCredential(subject);
  237.        
  238.         IDSoggetto idSoggetto = null;
  239.         try{
  240.             RegistroServiziManager registroServiziManager = RegistroServiziManager.getInstance(datiInvocazione.getState());
  241.             List<Throwable> notFoundExceptions = new ArrayList<>();
  242.            
  243.             // NOTA: il fatto di essersi registrati come strict o come non strict è insito nella registrazione dell'applicativo
  244.            
  245.             // 1. Prima si cerca per certificato strict
  246.             if(certificate!=null) {
  247.                 try{
  248.                     idSoggetto = registroServiziManager.getIdSoggettoByCredenzialiSsl(certificate, true, null); // all registry
  249.                 }catch(DriverRegistroServiziNotFound notFound){
  250.                     notFoundExceptions.add(notFound);
  251.                 }
  252.             }
  253.             if(idSoggetto==null &&
  254.                 // 2. Poi per certificato no strict
  255.                 certificate!=null) {
  256.                 try{
  257.                     idSoggetto = registroServiziManager.getIdSoggettoByCredenzialiSsl(certificate, false, null); // all registry
  258.                 }catch(DriverRegistroServiziNotFound notFound){
  259.                     notFoundExceptions.add(notFound);
  260.                 }  
  261.             }
  262.             if(idSoggetto==null) {
  263.                 // 3. per subject/issuer
  264.                 try {
  265.                     idSoggetto = registroServiziManager.getIdSoggettoByCredenzialiSsl(subject, issuer, null); // all registry
  266.                 }catch(DriverRegistroServiziNotFound notFound){
  267.                     notFoundExceptions.add(notFound);
  268.                 }
  269.             }
  270.             if(idSoggetto==null) {
  271.                 // 4. solo per subject
  272.                 try {
  273.                     idSoggetto = registroServiziManager.getIdSoggettoByCredenzialiSsl(subject, null, null); // all registry
  274.                 }catch(DriverRegistroServiziNotFound notFound){
  275.                     notFoundExceptions.add(notFound);
  276.                 }
  277.             }
  278.            
  279.             if(idSoggetto==null && !notFoundExceptions.isEmpty()) {
  280.                 throw new UtilsMultiException(notFoundExceptions.toArray(new Throwable[1]));
  281.             }
  282.         }
  283.         catch(UtilsMultiException notFound){
  284.             if(this.logError) {
  285.                 OpenSPCoop2Logger.getLoggerOpenSPCoopCore().debug("AutenticazioneSsl non ha trovato risultati",notFound);
  286.             }
  287.         }
  288.         catch(Exception e){
  289.             if(this.logError) {
  290.                 OpenSPCoop2Logger.getLoggerOpenSPCoopCore().error("AutenticazioneSsl non riuscita",e);
  291.             }
  292.             esito.setErroreCooperazione(IntegrationFunctionError.INTERNAL_REQUEST_ERROR, ErroriCooperazione.ERRORE_GENERICO_PROCESSAMENTO_MESSAGGIO.getErroreCooperazione());
  293.             esito.setClientIdentified(false);
  294.             esito.setEccezioneProcessamento(e);
  295.             return esito;
  296.         }
  297.        
  298.         IDServizioApplicativo idServizioApplicativo = null;
  299.         try {
  300.             if(idSoggetto==null && this.getProtocolFactory().createProtocolConfiguration().isSupportoAutenticazioneApplicativiErogazioni()
  301.                     &&
  302.                     !Costanti.MODIPA_PROTOCOL_NAME.equals(this.getProtocolFactory().getProtocol())  // su ModI i certificati vengono associati per le firme
  303.                     ) {
  304.                
  305.                 ConfigurazionePdDManager configurazionePdDManager = ConfigurazionePdDManager.getInstance(datiInvocazione.getState());
  306.                
  307.                 // NOTA: il fatto di essersi registrati come strict o come non strict è insito nella registrazione dell'applicativo
  308.                
  309.                 ConfigurazioneFiltroServiziApplicativi filtroHttps = ConfigurazioneFiltroServiziApplicativi.getFiltroApplicativiHttps();
  310.                
  311.                 // 1. Prima si cerca per certificato strict
  312.                 if(certificate!=null) {
  313.                     idServizioApplicativo = configurazionePdDManager.getIdServizioApplicativoByCredenzialiSsl(certificate, true,
  314.                             filtroHttps.getTipiSoggetti(), filtroHttps.isIncludiApplicativiNonModI(), filtroHttps.isIncludiApplicativiModIEsterni(), filtroHttps.isIncludiApplicativiModIInterni());
  315.                 }
  316.                 if(idServizioApplicativo==null &&
  317.                     // 2. Poi per certificato no strict
  318.                     certificate!=null) {
  319.                     idServizioApplicativo = configurazionePdDManager.getIdServizioApplicativoByCredenzialiSsl(certificate, false,
  320.                             filtroHttps.getTipiSoggetti(), filtroHttps.isIncludiApplicativiNonModI(), filtroHttps.isIncludiApplicativiModIEsterni(), filtroHttps.isIncludiApplicativiModIInterni());
  321.                 }
  322.                 if(idServizioApplicativo==null) {
  323.                     // 3. per subject/issuer
  324.                     idServizioApplicativo = configurazionePdDManager.getIdServizioApplicativoByCredenzialiSsl(subject, issuer,
  325.                             filtroHttps.getTipiSoggetti(), filtroHttps.isIncludiApplicativiNonModI(), filtroHttps.isIncludiApplicativiModIEsterni(), filtroHttps.isIncludiApplicativiModIInterni());    
  326.                 }
  327.                 if(idServizioApplicativo==null) {
  328.                     // 4. solo per subject
  329.                     idServizioApplicativo = configurazionePdDManager.getIdServizioApplicativoByCredenzialiSsl(subject, null,
  330.                             filtroHttps.getTipiSoggetti(), filtroHttps.isIncludiApplicativiNonModI(), filtroHttps.isIncludiApplicativiModIEsterni(), filtroHttps.isIncludiApplicativiModIInterni());    
  331.                 }

  332.                 if(idServizioApplicativo!=null) {
  333.                     if(idSoggetto==null) {
  334.                         idSoggetto = idServizioApplicativo.getIdSoggettoProprietario();
  335.                     }
  336.                     // Non ha senso poter identificare entrambi con le stesse credenziali
  337. //                  else if(idServizioApplicativo.getIdSoggettoProprietario().equals(idSoggetto)==false) {
  338. //                      throw new Exception("Identificato sia un soggetto che un applicativo. Il soggetto ["+idSoggetto+
  339. //                              "] identificato è differente dal proprietario dell'applicativo identificato ["+idServizioApplicativo.getIdSoggettoProprietario()+"]");
  340. //                  }
  341.                 }
  342.             }
  343.         }
  344.         catch(Exception e){
  345.             if(this.logError) {
  346.                     OpenSPCoop2Logger.getLoggerOpenSPCoopCore().error("AutenticazioneSsl (Applicativi) non riuscita",e);
  347.             }
  348.             esito.setErroreCooperazione(IntegrationFunctionError.INTERNAL_REQUEST_ERROR, ErroriCooperazione.ERRORE_GENERICO_PROCESSAMENTO_MESSAGGIO.getErroreCooperazione());
  349.             esito.setClientAuthenticated(false);
  350.             esito.setClientIdentified(false);
  351.             esito.setEccezioneProcessamento(e);
  352.             return esito;
  353.         }
  354.        
  355.         if(idSoggetto == null){
  356.             // L'identificazione in ssl non e' obbligatoria
  357.             /** esito.setErroreCooperazione(ErroriCooperazione.AUTENTICAZIONE_FALLITA_CREDENZIALI_FORNITE_NON_CORRETTE.getErroreCooperazione());*/
  358.             esito.setClientIdentified(false);
  359.             return esito;
  360.         }
  361.         else {
  362.             esito.setClientIdentified(true);
  363.             esito.setIdSoggetto(idSoggetto);
  364.             esito.setIdServizioApplicativo(idServizioApplicativo);
  365.         }
  366.        
  367.         return esito;
  368.        
  369.     }

  370. }