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.pd;

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

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

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

  55. public class AutenticazioneSsl extends AbstractAutenticazioneBase {

  56.     private boolean logError = true;
  57.     @Override
  58.     public void setLogError(boolean logError) {
  59.         this.logError = logError;
  60.     }
  61.    
  62.     @Override
  63.     public EsitoAutenticazionePortaDelegata process(DatiInvocazionePortaDelegata datiInvocazione) throws AutenticazioneException{

  64.         EsitoAutenticazionePortaDelegata esito = new EsitoAutenticazionePortaDelegata();
  65.        
  66.         OpenSPCoop2Properties op2Properties = OpenSPCoop2Properties.getInstance();
  67.         WWWAuthenticateConfig wwwAuthenticateConfig = op2Properties.getRealmAutenticazioneHttpsWWWAuthenticateConfig();
  68.        
  69.         if(datiInvocazione==null) {
  70.             throw new AutenticazioneException("Param datiInvocazione is null");
  71.         }
  72.        
  73.         IDSoggetto soggettoFruitore = null;
  74.         if(datiInvocazione.getPd()!=null) {
  75.             soggettoFruitore = new IDSoggetto(datiInvocazione.getPd().getTipoSoggettoProprietario(), datiInvocazione.getPd().getNomeSoggettoProprietario());
  76.         }
  77.                
  78.         Credenziali credenziali = datiInvocazione.getInfoConnettoreIngresso().getCredenziali();
  79.        
  80.         String subject = credenziali.getSubject();
  81.         String issuer = credenziali.getIssuer();
  82.         CertificateInfo certificate = null;
  83.         if(credenziali.getCertificate()!=null) {
  84.             certificate = credenziali.getCertificate().getCertificate();
  85.         }
  86.        
  87.         RequestInfo requestInfo = datiInvocazione.getRequestInfo();
  88.        
  89.         // Controllo credenziali fornite
  90.         if( subject==null || "".equals(subject) ){
  91.             esito.setErroreIntegrazione(IntegrationFunctionError.AUTHENTICATION_CREDENTIALS_NOT_FOUND, ErroriIntegrazione.ERRORE_402_AUTENTICAZIONE_FALLITA.getErrore402_AutenticazioneFallitaSsl(CostantiProtocollo.CREDENZIALI_NON_FORNITE,subject));
  92.             esito.setClientAuthenticated(false);
  93.             esito.setClientIdentified(false);
  94.             if(wwwAuthenticateConfig!=null) {
  95.                 esito.setWwwAuthenticateErrorHeader(wwwAuthenticateConfig.buildWWWAuthenticateHeaderValue_notFound());
  96.             }
  97.             return esito;
  98.         }
  99.         if(credenziali.getCertificate()!=null) {
  100.             certificate = credenziali.getCertificate().getCertificate();
  101.            
  102.             List<Proprieta> proprieta = null;
  103.             if(datiInvocazione.getPd()!=null) {
  104.                 proprieta = datiInvocazione.getPd().getProprietaList();
  105.             }

  106.             boolean checkValid = false;
  107.             boolean trustStore = false;
  108.             KeyStore trustStoreCertificatiX509 = null;
  109.             CertStore trustStoreCertificatiX509crls = null;
  110.             IOCSPValidator ocspValidator = null;
  111.             try {
  112.                 checkValid = CostantiProprieta.isAutenticazioneHttpsValidityCheck(proprieta, op2Properties.isAutenticazioneHttpsPortaDelegataValidityCheck());
  113.                 trustStore = CostantiProprieta.isAutenticazioneHttpsTrustStore(proprieta, op2Properties.getAutenticazioneHttpsPortaDelegataTruststorePath());
  114.                 if(trustStore) {
  115.                     String path = CostantiProprieta.getAutenticazioneHttpsTrustStorePath(proprieta, op2Properties.getAutenticazioneHttpsPortaDelegataTruststorePath());
  116.                     if(path!=null) {
  117.                         try {
  118.                             String password = CostantiProprieta.getAutenticazioneHttpsTrustStorePassword(proprieta, op2Properties.getAutenticazioneHttpsPortaDelegataTruststorePassword());
  119.                             String type = CostantiProprieta.getAutenticazioneHttpsTrustStoreType(proprieta, op2Properties.getAutenticazioneHttpsPortaDelegataTruststoreType());
  120.                             trustStoreCertificatiX509 = GestoreKeystoreCaching.getMerlinTruststore(requestInfo, path,
  121.                                     type,
  122.                                     password).getTrustStore();
  123.                         }catch(Exception e){
  124.                             throw new CoreException("Errore durante la lettura del truststore indicato ("+path+"): "+e.getMessage());
  125.                         }
  126.                     }
  127.                    
  128.                     if(trustStoreCertificatiX509!=null) {
  129.                         String crl = CostantiProprieta.getAutenticazioneHttpsTrustStoreCRLs(proprieta, op2Properties.getAutenticazioneHttpsPortaDelegataTruststoreCRLs());
  130.                        
  131.                         boolean crlByOcsp = false;
  132.                         String ocspPolicy = CostantiProprieta.getAutenticazioneHttpsTrustStoreOCSPPolicy(proprieta, op2Properties.getAutenticazioneHttpsPortaDelegataTruststoreOCSPPolicy());
  133.                         if(ocspPolicy!=null) {
  134.                             LoggerBuffer lb = new LoggerBuffer();
  135.                             lb.setLogDebug(OpenSPCoop2Logger.getLoggerOpenSPCoopCore());
  136.                             lb.setLogError(OpenSPCoop2Logger.getLoggerOpenSPCoopCore());
  137.                             GestoreOCSPResource ocspResourceReader = new GestoreOCSPResource(requestInfo);
  138.                             try {
  139.                                 ocspValidator = new GestoreOCSPValidator(requestInfo, lb,
  140.                                         trustStoreCertificatiX509,
  141.                                         crl,
  142.                                         ocspPolicy,
  143.                                         ocspResourceReader);
  144.                             }catch(Exception e){
  145.                                 throw new CoreException("Errore durante l'inizializzazione del gestore della policy OCSP ("+ocspPolicy+"): "+e.getMessage());
  146.                             }
  147.                             if(ocspValidator!=null) {
  148.                                 GestoreOCSPValidator gOcspValidator = (GestoreOCSPValidator) ocspValidator;
  149.                                 if(gOcspValidator.getOcspConfig()!=null) {
  150.                                     crlByOcsp = gOcspValidator.getOcspConfig().isCrl();
  151.                                 }
  152.                             }
  153.                         }
  154.                        
  155.                         if(crl!=null && !crlByOcsp) {
  156.                             try {
  157.                                 trustStoreCertificatiX509crls = GestoreKeystoreCaching.getCRLCertstore(requestInfo, crl).getCertStore();
  158.                             }catch(Exception e){
  159.                                 throw new CoreException("Errore durante la lettura delle CRLs ("+crl+"): "+e.getMessage());
  160.                             }
  161.                         }
  162.                     }
  163.                 }
  164.             }catch(Exception e) {
  165.                 if(this.logError) {
  166.                     OpenSPCoop2Logger.getLoggerOpenSPCoopCore().error("AutenticazioneSsl non riuscita",e);
  167.                 }
  168.                 esito.setErroreIntegrazione(IntegrationFunctionError.INTERNAL_REQUEST_ERROR, ErroriIntegrazione.ERRORE_5XX_GENERICO_PROCESSAMENTO_MESSAGGIO.
  169.                         get5XX_ErroreProcessamento(CodiceErroreIntegrazione.CODICE_536_CONFIGURAZIONE_NON_DISPONIBILE));
  170.                 esito.setClientIdentified(false);
  171.                 esito.setEccezioneProcessamento(e);
  172.                 return esito;
  173.             }
  174.            
  175.             if(checkValid
  176.                     &&
  177.                     trustStoreCertificatiX509crls==null) { // altrimenti la validita' viene verificata insieme alle CRL
  178.                 try {
  179.                     certificate.checkValid();
  180.                 }catch(Exception e) {
  181.                     esito.setErroreIntegrazione(IntegrationFunctionError.AUTHENTICATION_INVALID_CREDENTIALS,
  182.                             ErroriIntegrazione.ERRORE_402_AUTENTICAZIONE_FALLITA.getErrore402_AutenticazioneFallitaSsl(CostantiProtocollo.CREDENZIALI_FORNITE_NON_CORRETTE+": "+e.getMessage(),subject));
  183.                     esito.setClientAuthenticated(false);
  184.                     esito.setClientIdentified(false);
  185.                     if(wwwAuthenticateConfig!=null) {
  186.                         esito.setWwwAuthenticateErrorHeader(wwwAuthenticateConfig.buildWWWAuthenticateHeaderValue_invalid());
  187.                     }
  188.                     return esito;
  189.                 }
  190.             }
  191.            
  192.             if(trustStoreCertificatiX509!=null) {
  193.                 try {
  194.                     if(!certificate.isVerified(trustStoreCertificatiX509, true)) {
  195.                         throw new CoreException("Certificato non verificabile rispetto alle CA conosciute");
  196.                     }
  197.                     if(trustStoreCertificatiX509crls!=null) {
  198.                         try {
  199.                             certificate.checkValid(trustStoreCertificatiX509crls, trustStoreCertificatiX509);
  200.                         }catch(Throwable t) {
  201.                             throw new CoreException("Certificato non valido: "+t.getMessage());
  202.                         }
  203.                     }
  204.                 }catch(Exception e) {
  205.                     esito.setErroreIntegrazione(IntegrationFunctionError.AUTHENTICATION_INVALID_CREDENTIALS,
  206.                             ErroriIntegrazione.ERRORE_402_AUTENTICAZIONE_FALLITA.getErrore402_AutenticazioneFallitaSsl(CostantiProtocollo.CREDENZIALI_FORNITE_NON_CORRETTE+": "+e.getMessage(),subject));
  207.                     esito.setClientAuthenticated(false);
  208.                     esito.setClientIdentified(false);
  209.                     if(wwwAuthenticateConfig!=null) {
  210.                         esito.setWwwAuthenticateErrorHeader(wwwAuthenticateConfig.buildWWWAuthenticateHeaderValue_invalid());
  211.                     }
  212.                     return esito;
  213.                 }
  214.             }
  215.            
  216.             if(ocspValidator!=null) {
  217.                 try {
  218.                     ocspValidator.valid(certificate.getCertificate());
  219.                 }catch(Throwable t) {
  220.                     esito.setErroreIntegrazione(IntegrationFunctionError.AUTHENTICATION_INVALID_CREDENTIALS,
  221.                             ErroriIntegrazione.ERRORE_402_AUTENTICAZIONE_FALLITA.getErrore402_AutenticazioneFallitaSsl(CostantiProtocollo.CREDENZIALI_FORNITE_NON_CORRETTE+": "+t.getMessage(),subject));
  222.                     esito.setClientAuthenticated(false);
  223.                     esito.setClientIdentified(false);
  224.                     if(!(t instanceof OCSPResponseException)) {
  225.                         esito.setNoCache(true);
  226.                     }
  227.                     if(wwwAuthenticateConfig!=null) {
  228.                         esito.setWwwAuthenticateErrorHeader(wwwAuthenticateConfig.buildWWWAuthenticateHeaderValue_invalid());
  229.                     }
  230.                     return esito;
  231.                 }
  232.             }

  233.         }
  234.        
  235.         // Essendoci l'identita' del chiamante, il client e' stato autenticato o da un frontend o dall'application server stesso
  236.         esito.setClientAuthenticated(true);
  237.         esito.setCredential(subject);
  238.        
  239.         // Provo a identificare il chiamante rispetto ad una entita' del registro
  240.         IDServizioApplicativo idServizioApplicativo = null;
  241.         try{
  242.             ConfigurazionePdDManager configurazionePdDManager = ConfigurazionePdDManager.getInstance(datiInvocazione.getState());
  243.            
  244.             // NOTA: il fatto di essersi registrati come strict o come non strict รจ insito nella registrazione dell'applicativo
  245.            
  246.             ConfigurazioneFiltroServiziApplicativi filtroHttps = ConfigurazioneFiltroServiziApplicativi.getFiltroApplicativiHttps();
  247.            
  248.             // 1. Prima si cerca per certificato strict
  249.             if(certificate!=null) {
  250.                 idServizioApplicativo = configurazionePdDManager.getIdServizioApplicativoByCredenzialiSsl(certificate, true,
  251.                         filtroHttps.getTipiSoggetti(), filtroHttps.isIncludiApplicativiNonModI(), filtroHttps.isIncludiApplicativiModIEsterni(), filtroHttps.isIncludiApplicativiModIInterni());
  252.             }
  253.             if(idServizioApplicativo==null &&
  254.                 // 2. Poi per certificato no strict
  255.                 certificate!=null) {
  256.                 idServizioApplicativo = configurazionePdDManager.getIdServizioApplicativoByCredenzialiSsl(certificate, false,
  257.                         filtroHttps.getTipiSoggetti(), filtroHttps.isIncludiApplicativiNonModI(), filtroHttps.isIncludiApplicativiModIEsterni(), filtroHttps.isIncludiApplicativiModIInterni());
  258.             }
  259.             if(idServizioApplicativo==null) {
  260.                 // 3. per subject/issuer
  261.                 idServizioApplicativo = configurazionePdDManager.getIdServizioApplicativoByCredenzialiSsl(subject, issuer,
  262.                         filtroHttps.getTipiSoggetti(), filtroHttps.isIncludiApplicativiNonModI(), filtroHttps.isIncludiApplicativiModIEsterni(), filtroHttps.isIncludiApplicativiModIInterni());    
  263.             }
  264.             if(idServizioApplicativo==null) {
  265.                 // 4. solo per subject
  266.                 idServizioApplicativo = configurazionePdDManager.getIdServizioApplicativoByCredenzialiSsl(subject, null,
  267.                         filtroHttps.getTipiSoggetti(), filtroHttps.isIncludiApplicativiNonModI(), filtroHttps.isIncludiApplicativiModIEsterni(), filtroHttps.isIncludiApplicativiModIInterni());    
  268.             }
  269.            
  270.             if(idServizioApplicativo!=null && soggettoFruitore==null) {
  271.                 soggettoFruitore = idServizioApplicativo.getIdSoggettoProprietario();
  272.             }
  273.         }catch(Exception e){
  274.             if(this.logError) {
  275.                 OpenSPCoop2Logger.getLoggerOpenSPCoopCore().error("AutenticazioneSsl non riuscita",e);
  276.             }
  277.             esito.setErroreIntegrazione(IntegrationFunctionError.INTERNAL_REQUEST_ERROR, ErroriIntegrazione.ERRORE_5XX_GENERICO_PROCESSAMENTO_MESSAGGIO.
  278.                     get5XX_ErroreProcessamento(CodiceErroreIntegrazione.CODICE_536_CONFIGURAZIONE_NON_DISPONIBILE));
  279.             esito.setClientIdentified(false);
  280.             esito.setEccezioneProcessamento(e);
  281.             return esito;
  282.         }
  283.        
  284.         if(idServizioApplicativo == null){
  285.             // L'identificazione in ssl non e' obbligatoria
  286.             /**esito.setErroreIntegrazione(ErroriIntegrazione.ERRORE_402_AUTENTICAZIONE_FALLITA.getErrore402_AutenticazioneFallitaSsl(CostantiProtocollo.CREDENZIALI_FORNITE_NON_CORRETTE,subject));*/
  287.             esito.setClientIdentified(false);
  288.         }
  289.         else {
  290.             if(OpenSPCoop2Properties.getInstance().isAutenticazioneHttpsPortaDelegataCheckSoggettiProprietari() && !idServizioApplicativo.getIdSoggettoProprietario().equals(soggettoFruitore)) {
  291.                 esito.setErroreIntegrazione(IntegrationFunctionError.AUTHENTICATION_INVALID_CREDENTIALS,
  292.                         ErroriIntegrazione.ERRORE_402_AUTENTICAZIONE_FALLITA.getErrore402_AutenticazioneFallitaSsl(
  293.                                 "soggetto proprietario ("+idServizioApplicativo.getIdSoggettoProprietario()+") dell'applicativo identificato ("+idServizioApplicativo.getNome()+") differente dal soggetto proprietario della porta invocata ("+soggettoFruitore+")",subject));
  294.                 esito.setClientIdentified(false);
  295.                 return esito;
  296.             }
  297.             else {
  298.                 esito.setClientIdentified(true);
  299.                 esito.setIdServizioApplicativo(idServizioApplicativo);
  300.             }
  301.         }
  302.        
  303.         return esito;
  304.        
  305.     }

  306. }