ModIValidazioneSintatticaRest.java
/*
* GovWay - A customizable API Gateway
* https://govway.org
*
* Copyright (c) 2005-2024 Link.it srl (https://link.it).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openspcoop2.protocol.modipa.validator;
import java.io.ByteArrayOutputStream;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.openspcoop2.core.config.PortaApplicativa;
import org.openspcoop2.core.constants.CostantiDB;
import org.openspcoop2.core.id.IDPortaApplicativa;
import org.openspcoop2.core.id.IDSoggetto;
import org.openspcoop2.core.registry.AccordoServizioParteComune;
import org.openspcoop2.core.registry.Resource;
import org.openspcoop2.message.OpenSPCoop2Message;
import org.openspcoop2.message.constants.MessageRole;
import org.openspcoop2.message.constants.MessageType;
import org.openspcoop2.message.constants.ServiceBinding;
import org.openspcoop2.pdd.core.dynamic.DynamicMapBuilderUtils;
import org.openspcoop2.pdd.core.dynamic.DynamicUtils;
import org.openspcoop2.pdd.core.keystore.RemoteStoreProvider;
import org.openspcoop2.pdd.core.token.Costanti;
import org.openspcoop2.pdd.core.token.parser.Claims;
import org.openspcoop2.pdd.core.token.parser.TokenUtils;
import org.openspcoop2.pdd.logger.MsgDiagnostico;
import org.openspcoop2.protocol.modipa.config.ModIAuditClaimConfig;
import org.openspcoop2.protocol.modipa.config.ModIAuditConfig;
import org.openspcoop2.protocol.modipa.config.ModIProperties;
import org.openspcoop2.protocol.modipa.constants.ModICostanti;
import org.openspcoop2.protocol.modipa.constants.ModIHeaderType;
import org.openspcoop2.protocol.modipa.utils.ModISecurityConfig;
import org.openspcoop2.protocol.modipa.utils.ModITruststoreConfig;
import org.openspcoop2.protocol.modipa.utils.ModIUtilities;
import org.openspcoop2.protocol.sdk.Busta;
import org.openspcoop2.protocol.sdk.Context;
import org.openspcoop2.protocol.sdk.Eccezione;
import org.openspcoop2.protocol.sdk.IProtocolFactory;
import org.openspcoop2.protocol.sdk.ProtocolException;
import org.openspcoop2.protocol.sdk.RestMessageSecurityToken;
import org.openspcoop2.protocol.sdk.SecurityToken;
import org.openspcoop2.protocol.sdk.constants.CodiceErroreCooperazione;
import org.openspcoop2.protocol.sdk.state.IState;
import org.openspcoop2.protocol.sdk.state.RequestInfo;
import org.openspcoop2.protocol.sdk.validator.ValidazioneUtils;
import org.openspcoop2.security.message.MessageSecurityContext;
import org.openspcoop2.security.message.MessageSecurityContextParameters;
import org.openspcoop2.security.message.constants.SecurityConstants;
import org.openspcoop2.security.message.engine.MessageSecurityContext_impl;
import org.openspcoop2.security.message.jose.MessageSecurityReceiver_jose;
import org.openspcoop2.utils.certificate.CertificateInfo;
import org.openspcoop2.utils.certificate.remote.RemoteKeyType;
import org.openspcoop2.utils.date.DateUtils;
import org.openspcoop2.utils.digest.DigestEncoding;
import org.openspcoop2.utils.json.JSONUtils;
import org.openspcoop2.utils.transport.TransportUtils;
import org.openspcoop2.utils.transport.http.HttpConstants;
import org.openspcoop2.utils.transport.http.HttpUtilities;
import org.slf4j.Logger;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.TextNode;
/**
* ModIValidazioneSintatticaRest
*
* @author Poli Andrea (apoli@link.it)
* @author $Author$
* @version $Rev$, $Date$
*/
public class ModIValidazioneSintatticaRest extends AbstractModIValidazioneSintatticaCommons{
public ModIValidazioneSintatticaRest(Logger log, IState state, Context context, IProtocolFactory<?> factory, RequestInfo requestInfo,
ModIProperties modiProperties, ValidazioneUtils validazioneUtils) {
super(log, state, context, factory, requestInfo, modiProperties, validazioneUtils);
}
private void logError(String msg) {
this.log.error(msg);
}
private void logError(String msg, Exception e) {
this.log.error(msg,e);
}
public void validateSyncInteractionProfile(OpenSPCoop2Message msg, boolean request,
List<Eccezione> erroriValidazione) throws ProtocolException {
if(!request) {
String returnCode = null;
int returnCodeInt = -1;
if(!request && msg.getTransportResponseContext()!=null) {
returnCode = msg.getTransportResponseContext().getCodiceTrasporto();
if(returnCode!=null) {
try {
returnCodeInt = Integer.valueOf(returnCode);
}catch(Exception e) {
// ignore
}
}
}
Integer [] returnCodeAttesi = this.modiProperties.getRestBloccanteHttpStatus();
// Fix: il controllo deve essere fatto solo per i codici che non rientrano in 4xx e 5xx
boolean is4xx5xx = (returnCodeInt>=400) && (returnCodeInt<=599);
if(!is4xx5xx && returnCodeAttesi!=null) {
boolean found = false;
for (Integer integer : returnCodeAttesi) {
if(integer.intValue() == ModICostanti.MODIPA_PROFILO_INTERAZIONE_HTTP_CODE_2XX_INT_VALUE) {
if((returnCodeInt >= 200) && (returnCodeInt<=299) ) {
found = true;
}
}
else if(integer.intValue() == returnCodeInt) {
found = true;
}
if(found) {
break;
}
}
if(!found) {
StringBuilder sb = new StringBuilder();
for (Integer integer : returnCodeAttesi) {
if(integer.intValue() == ModICostanti.MODIPA_PROFILO_INTERAZIONE_HTTP_CODE_2XX_INT_VALUE) {
sb = new StringBuilder();
sb.append("2xx");
break;
}
if(sb.length()>0) {
sb.append(",");
}
sb.append(integer.intValue());
}
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.PROFILO_TRASMISSIONE,
"HTTP Status '"+returnCodeInt+"' differente da quello atteso per il profilo bloccante (atteso: "+sb.toString()+")"));
}
}
}
}
private String getErrorHeaderHttpPrefix(String hdr) {
return "Header HTTP '"+hdr+"'";
}
private String getErrorHeaderHttpNonPresente(String hdr) {
return getErrorHeaderHttpPrefix(hdr)+" non presente";
}
private String getErrorHeaderHttpPresentePiuVolte(String hdr) {
return getErrorHeaderHttpPrefix(hdr)+" presente più volte";
}
static String getErroreTokenSenzaClaim(String c) {
return "Token senza claim '"+c+"'";
}
static String getErroreTokenClaimNonValido(String c, Exception e) {
return "Token con claim '"+c+"' non valido: "+e.getMessage();
}
public void validateAsyncInteractionProfile(OpenSPCoop2Message msg, boolean request, String asyncInteractionType, String asyncInteractionRole,
AccordoServizioParteComune apiContenenteRisorsa, String azione,
Busta busta, List<Eccezione> erroriValidazione,
String replyTo) throws ProtocolException {
String correlationIdHeader = this.modiProperties.getRestCorrelationIdHeader();
String correlationId = null;
if(msg!=null) {
if(request && msg.getTransportRequestContext()!=null) {
correlationId = msg.getTransportRequestContext().getHeaderFirstValue(correlationIdHeader);
}
else if(!request && msg.getTransportResponseContext()!=null) {
correlationId = msg.getTransportResponseContext().getHeaderFirstValue(correlationIdHeader);
}
}
String replyToHeader = this.modiProperties.getRestReplyToHeader();
String replyToAddress = null;
if(msg!=null) {
if(request && msg.getTransportRequestContext()!=null) {
replyToAddress = msg.getTransportRequestContext().getHeaderFirstValue(replyToHeader);
}
else if(!request && msg.getTransportResponseContext()!=null) {
replyToAddress = msg.getTransportResponseContext().getHeaderFirstValue(replyToHeader);
}
}
String locationHeader = this.modiProperties.getRestLocationHeader();
String location = null;
if(msg!=null) {
if(request && msg.getTransportRequestContext()!=null) {
location = msg.getTransportRequestContext().getHeaderFirstValue(locationHeader);
}
else if(!request && msg.getTransportResponseContext()!=null) {
location = msg.getTransportResponseContext().getHeaderFirstValue(locationHeader);
}
}
if(replyToAddress!=null) {
busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_INTERAZIONE_ASINCRONA_REPLY_TO, replyToAddress);
}
if(correlationId!=null) {
busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_INTERAZIONE_ASINCRONA_ID_CORRELAZIONE, correlationId);
if(correlationId.length()<=255) {
busta.setCollaborazione(correlationId);
}
}
String returnCode = null;
int returnCodeInt = -1;
if(!request && msg.getTransportResponseContext()!=null) {
returnCode = msg.getTransportResponseContext().getCodiceTrasporto();
if(returnCode!=null) {
try {
returnCodeInt = Integer.valueOf(returnCode);
}catch(Exception e) {
// ignore
}
}
}
// Fix: il controllo deve essere fatto solo per i codici che non rientrano in 4xx e 5xx
boolean is4xx5xx = false;
if(!request) {
is4xx5xx = (returnCodeInt>=400) && (returnCodeInt<=599);
}
Integer [] returnCodeAttesi = null;
if(!is4xx5xx && asyncInteractionType!=null) {
if(ModICostanti.MODIPA_PROFILO_INTERAZIONE_ASINCRONA_VALUE_PUSH.equals(asyncInteractionType)) {
if(ModICostanti.MODIPA_PROFILO_INTERAZIONE_ASINCRONA_RUOLO_VALUE_RICHIESTA.equals(asyncInteractionRole)) {
if(request) {
if(replyToAddress==null || "".equals(replyToAddress)) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SERVIZIO_CORRELATO_NON_PRESENTE,
getErrorHeaderHttpNonPresente(replyToHeader)));
return;
}
if(this.modiProperties.isRestSecurityTokenPushReplyToUpdateInErogazione()) {
if(msg.getTransportRequestContext()!=null) {
msg.getTransportRequestContext().removeHeader(replyToHeader); // rimuovo se già esiste
}
msg.forceTransportHeader(replyToHeader, replyTo);
}
}
else {
if(correlationId==null || "".equals(correlationId)) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.COLLABORAZIONE_NON_PRESENTE,
getErrorHeaderHttpNonPresente(correlationIdHeader)));
return;
}
returnCodeAttesi = this.modiProperties.getRestNonBloccantePushRequestHttpStatus();
}
}
else {
if(request) {
if(correlationId==null || "".equals(correlationId)) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.COLLABORAZIONE_NON_PRESENTE,
getErrorHeaderHttpNonPresente(correlationIdHeader)));
return;
}
}
else {
returnCodeAttesi = this.modiProperties.getRestNonBloccantePushResponseHttpStatus();
}
}
}
else {
// pull
if(request) {
// Flusso di richiesta
if(ModICostanti.MODIPA_PROFILO_INTERAZIONE_ASINCRONA_RUOLO_VALUE_RICHIESTA_STATO.equals(asyncInteractionRole) ||
ModICostanti.MODIPA_PROFILO_INTERAZIONE_ASINCRONA_RUOLO_VALUE_RISPOSTA.equals(asyncInteractionRole)) {
String urlInvocata = msg.getTransportRequestContext().getFunctionParameters();
if(urlInvocata!=null && !"".equals(urlInvocata)) {
String resourcePathAzione = null;
for (Resource r : apiContenenteRisorsa.getResourceList()) {
if(r.getNome().equals(azione)) {
resourcePathAzione = r.getPath();
break;
}
}
if(!urlInvocata.startsWith("/")) {
urlInvocata = "/" + urlInvocata;
}
String correlationIdExtracted = ModIUtilities.extractCorrelationIdFromLocation(resourcePathAzione, urlInvocata, false, this.log);
if(correlationIdExtracted!=null && correlationIdExtracted.length()<=255) {
busta.setCollaborazione(correlationIdExtracted);
}
}
}
}
else {
// Flusso di risposta
if(ModICostanti.MODIPA_PROFILO_INTERAZIONE_ASINCRONA_RUOLO_VALUE_RICHIESTA.equals(asyncInteractionRole)) {
if(location==null || "".equals(location)) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SERVIZIO_CORRELATO_NON_PRESENTE,
getErrorHeaderHttpNonPresente(locationHeader)));
return;
}
busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_INTERAZIONE_ASINCRONA_LOCATION, location);
String correlationIdExtracted = ModIUtilities.extractCorrelationId(location, apiContenenteRisorsa, azione, asyncInteractionRole, this.log);
if(correlationIdExtracted!=null && correlationIdExtracted.length()<=255) {
busta.setCollaborazione(correlationIdExtracted);
}
returnCodeAttesi = this.modiProperties.getRestNonBloccantePullRequestHttpStatus();
}
else if(ModICostanti.MODIPA_PROFILO_INTERAZIONE_ASINCRONA_RUOLO_VALUE_RICHIESTA_STATO.equals(asyncInteractionRole)) {
Integer [] returnCodeResourceReady = this.modiProperties.getRestNonBloccantePullRequestStateOkHttpStatus();
boolean isReady = false;
for (Integer integer : returnCodeResourceReady) {
if(integer.intValue() == returnCodeInt) {
isReady = true;
break;
}
}
if(isReady) {
if(location==null || "".equals(location)) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SERVIZIO_CORRELATO_NON_PRESENTE,
getErrorHeaderHttpNonPresente(locationHeader)));
return;
}
busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_INTERAZIONE_ASINCRONA_LOCATION, location);
String correlationIdExtracted = ModIUtilities.extractCorrelationId(location, apiContenenteRisorsa, azione, asyncInteractionRole, this.log);
if(correlationIdExtracted!=null && correlationIdExtracted.length()<=255) {
busta.setCollaborazione(correlationIdExtracted);
}
returnCodeAttesi = returnCodeResourceReady;
}
else {
Integer [] returnCodeAttesiNotReady = this.modiProperties.getRestNonBloccantePullRequestStateNotReadyHttpStatus();
returnCodeAttesi = new Integer[returnCodeResourceReady.length+returnCodeAttesiNotReady.length];
int i = 0;
for (int j=0; j < returnCodeAttesiNotReady.length; j++) {
returnCodeAttesi[i] = returnCodeAttesiNotReady[j];
i++;
}
for (int j=0; j < returnCodeResourceReady.length; j++) {
returnCodeAttesi[i] = returnCodeResourceReady[j];
i++;
}
}
}
else {
returnCodeAttesi = this.modiProperties.getRestNonBloccantePullResponseHttpStatus();
}
}
}
}
if(returnCodeAttesi!=null) {
boolean found = false;
for (Integer integer : returnCodeAttesi) {
if(integer.intValue() == returnCodeInt) {
found = true;
break;
}
}
if(!found) {
StringBuilder sb = new StringBuilder();
for (Integer integer : returnCodeAttesi) {
if(sb.length()>0) {
sb.append(",");
}
sb.append(integer.intValue());
}
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.PROFILO_TRASMISSIONE,
"HTTP Status '"+returnCodeInt+"' differente da quello atteso per il profilo non bloccante '"+asyncInteractionType+"' con ruolo '"+asyncInteractionRole+"' (atteso: "+sb.toString()+")"));
}
}
}
public String validateSecurityProfile(OpenSPCoop2Message msg, boolean request, String securityMessageProfile, boolean useKIDtokenHeader, String headerTokenRest,
boolean corniceSicurezza, String patternCorniceSicurezza, String schemaCorniceSicurezza,
boolean includiRequestDigest,
Busta busta, List<Eccezione> erroriValidazione,
ModITruststoreConfig trustStoreCertificati, ModITruststoreConfig trustStoreSsl, ModISecurityConfig securityConfig,
boolean buildSecurityTokenInRequest, ModIHeaderType headerType, boolean integritaCustom, boolean securityHeaderObbligatorio,
Map<String, Object> dynamicMapParameter, Busta datiRichiesta,
IDSoggetto idSoggetto, MsgDiagnostico msgDiag) throws ProtocolException {
if(msg==null) {
throw new ProtocolException("Param msg is null");
}
boolean bufferMessageReadOnly = this.modiProperties.isReadByPathBufferEnabled();
String idTransazione = null;
if(this.context!=null) {
idTransazione = (String)this.context.getObject(org.openspcoop2.core.constants.Costanti.ID_TRANSAZIONE);
}
String securityTokenHeader = headerTokenRest;
List<String> securityTokens = null;
if(request && msg.getTransportRequestContext()!=null) {
securityTokens = msg.getTransportRequestContext().getHeaderValues(securityTokenHeader);
}
else if(!request && msg.getTransportResponseContext()!=null) {
securityTokens = msg.getTransportResponseContext().getHeaderValues(securityTokenHeader);
}
String securityToken = null;
if(securityTokens!=null && !securityTokens.isEmpty()) {
securityToken = securityTokens.get(0);
}
boolean attesoSecurityHeader = securityHeaderObbligatorio;
if(!request) {
try {
if(msg.isFault()) {
attesoSecurityHeader = false;
}
}catch(Exception e) {
throw new ProtocolException(e.getMessage(),e);
}
}
if(securityToken==null || "".equals(securityToken)) {
if(attesoSecurityHeader) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_TOKEN_NON_PRESENTE,
getErrorHeaderHttpNonPresente(securityTokenHeader)));
}
return null;
}
if(securityTokens.size()>1) {
if(attesoSecurityHeader) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_TOKEN_PRESENTE_PIU_VOLTE,
getErrorHeaderHttpPresentePiuVolte(securityTokenHeader)));
}
return null;
}
if(busta!=null && integritaCustom) {
busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_CUSTOM_HEADER,headerTokenRest);
}
String token = securityToken;
if(HttpConstants.AUTHORIZATION.equalsIgnoreCase(securityTokenHeader)) {
if(request) {
if(msg.getTransportRequestContext()==null || msg.getTransportRequestContext().getCredential()==null) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_TOKEN_NON_PRESENTE,
getErrorHeaderHttpNonPresente(HttpConstants.AUTHORIZATION)));
return null;
}
if(msg.getTransportRequestContext().getCredential().getBearerToken()==null) {
if(msg.getTransportRequestContext().getCredential().getUsername()!=null) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_TOKEN_NON_PRESENTE,
getErrorHeaderHttpPrefix(HttpConstants.AUTHORIZATION)+" non presente con prefisso '"+HttpConstants.AUTHORIZATION_PREFIX_BEARER+"'"));
return null;
}
else {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_TOKEN_NON_PRESENTE,
getErrorHeaderHttpNonPresente(HttpConstants.AUTHORIZATION)));
return null;
}
}
token = msg.getTransportRequestContext().getCredential().getBearerToken();
}
else {
if(token.toLowerCase().startsWith(HttpConstants.AUTHORIZATION_PREFIX_BEARER.toLowerCase())){
token = token.substring(HttpConstants.AUTHORIZATION_PREFIX_BEARER.length());
}
else {
if(token.toLowerCase().startsWith(HttpConstants.AUTHORIZATION_PREFIX_BASIC.toLowerCase())){
if(attesoSecurityHeader) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_TOKEN_NON_PRESENTE,
getErrorHeaderHttpPrefix(HttpConstants.AUTHORIZATION)+" non presente con prefisso '"+HttpConstants.AUTHORIZATION_PREFIX_BEARER+"'"));
}
return null;
}
else {
if(attesoSecurityHeader) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_TOKEN_NON_PRESENTE,
getErrorHeaderHttpNonPresente(HttpConstants.AUTHORIZATION)));
}
return null;
}
}
}
}
boolean integritaX509 = false;
if(ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0301.equals(securityMessageProfile) ||
ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0302.equals(securityMessageProfile)) {
integritaX509 = true;
}
boolean integritaKid = false;
if(ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0401.equals(securityMessageProfile) ||
ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0402.equals(securityMessageProfile)) {
integritaKid = true;
}
boolean integrita = integritaX509 || integritaKid;
boolean tokenAudit = corniceSicurezza && !CostantiDB.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_PATTERN_OLD.equals(patternCorniceSicurezza) && schemaCorniceSicurezza!=null;
boolean apiSoap = ServiceBinding.SOAP.equals(msg.getServiceBinding());
String prefix = "";
boolean headerDuplicati = headerType.isHeaderDuplicati();
boolean headerAuthentication = headerType.isUsabledForAuthentication();
if(headerDuplicati || tokenAudit) {
prefix = "[Header '"+headerTokenRest+"'] ";
}
/*
* == signature ==
*/
OpenSPCoop2Message msgToken = null;
try {
msgToken = msg.getFactory().createMessage(MessageType.JSON, MessageRole.NONE,
HttpConstants.CONTENT_TYPE_JSON, token.getBytes(), null, null).getMessage_throwParseException();
}catch(Exception e) {
throw new ProtocolException(e.getMessage(),e);
}
String payloadToken = null;
X509Certificate x509 = null;
String kid = null;
try {
// ** Timestamp **
Long timeToLive = this.modiProperties.getRestSecurityTokenClaimsIatTimeCheckMilliseconds();
if(securityConfig.getCheckTtlIatMilliseconds()!=null) {
timeToLive = securityConfig.getCheckTtlIatMilliseconds();
}
if(timeToLive!=null && msg!=null) {
msg.addContextProperty(ModICostanti.MODIPA_OPENSPCOOP2_MSG_CONTEXT_IAT_TTL_CHECK, timeToLive);
}
MessageSecurityReceiver_jose joseSignature = new MessageSecurityReceiver_jose();
MessageSecurityContextParameters messageSecurityContextParameters = new MessageSecurityContextParameters();
MessageSecurityContext messageSecurityContext = new MessageSecurityContext_impl(messageSecurityContextParameters);
Map<String,Object> secProperties = new HashMap<>();
secProperties.put(SecurityConstants.SECURITY_ENGINE, SecurityConstants.SECURITY_ENGINE_JOSE);
secProperties.put(SecurityConstants.ACTION, SecurityConstants.SIGNATURE_ACTION);
secProperties.put(SecurityConstants.SIGNATURE_MODE, SecurityConstants.SIGNATURE_MODE_COMPACT);
secProperties.put(SecurityConstants.SIGNATURE_DETACHED, SecurityConstants.SIGNATURE_DETACHED_FALSE);
secProperties.put(SecurityConstants.DETACH_SECURITY_INFO, SecurityConstants.TRUE);
secProperties.put(SecurityConstants.JOSE_USE_HEADERS, SecurityConstants.JOSE_USE_HEADERS_TRUE);
secProperties.put(SecurityConstants.JOSE_USE_HEADERS_JWK, SecurityConstants.JOSE_USE_HEADERS_FALSE);
secProperties.put(SecurityConstants.JOSE_USE_HEADERS_JKU, SecurityConstants.JOSE_USE_HEADERS_FALSE);
secProperties.put(SecurityConstants.JOSE_USE_HEADERS_X5T, SecurityConstants.JOSE_USE_HEADERS_FALSE);
if(integritaKid || useKIDtokenHeader) {
secProperties.put(SecurityConstants.JOSE_USE_HEADERS_KID, SecurityConstants.JOSE_USE_HEADERS_TRUE);
secProperties.put(SecurityConstants.JOSE_USE_HEADERS_X5C, SecurityConstants.JOSE_USE_HEADERS_FALSE);
secProperties.put(SecurityConstants.JOSE_USE_HEADERS_X5U, SecurityConstants.JOSE_USE_HEADERS_FALSE);
secProperties.put(SecurityConstants.JOSE_USE_HEADERS_X5T_256, SecurityConstants.JOSE_USE_HEADERS_FALSE);
}
else {
secProperties.put(SecurityConstants.JOSE_USE_HEADERS_KID, SecurityConstants.JOSE_USE_HEADERS_FALSE);
boolean x5c = tokenAudit && apiSoap ? this.modiProperties.isSecurityTokenAuditApiSoapX509RiferimentoX5c() : securityConfig.isX5c();
secProperties.put(SecurityConstants.JOSE_USE_HEADERS_X5C, x5c ? SecurityConstants.JOSE_USE_HEADERS_TRUE: SecurityConstants.JOSE_USE_HEADERS_FALSE);
boolean x5u = tokenAudit && apiSoap ? this.modiProperties.isSecurityTokenAuditApiSoapX509RiferimentoX5u() : securityConfig.isX5u();
secProperties.put(SecurityConstants.JOSE_USE_HEADERS_X5U, x5u ? SecurityConstants.JOSE_USE_HEADERS_TRUE: SecurityConstants.JOSE_USE_HEADERS_FALSE);
boolean x5t = tokenAudit && apiSoap ? this.modiProperties.isSecurityTokenAuditApiSoapX509RiferimentoX5t() : securityConfig.isX5t();
secProperties.put(SecurityConstants.JOSE_USE_HEADERS_X5T_256, x5t ? SecurityConstants.JOSE_USE_HEADERS_TRUE: SecurityConstants.JOSE_USE_HEADERS_FALSE);
}
secProperties.put(SecurityConstants.JOSE_USE_HEADERS_TRUSTSTORE_TYPE, trustStoreCertificati.getSecurityMessageTruststoreType());
if(!trustStoreCertificati.isSecurityMessageTruststoreRemote()) {
secProperties.put(SecurityConstants.JOSE_USE_HEADERS_TRUSTSTORE_FILE, trustStoreCertificati.getSecurityMessageTruststorePath());
}
if(!trustStoreCertificati.isSecurityMessageTruststoreJWK() && !trustStoreCertificati.isSecurityMessageTruststoreRemote()) {
secProperties.put(SecurityConstants.JOSE_USE_HEADERS_TRUSTSTORE_PASSWORD, trustStoreCertificati.getSecurityMessageTruststorePassword());
}
if(trustStoreCertificati.getSecurityMessageTruststoreCRLs()!=null) {
secProperties.put(SecurityConstants.SIGNATURE_CRL, trustStoreCertificati.getSecurityMessageTruststoreCRLs());
}
if(trustStoreCertificati.getSecurityMessageTruststoreOCSPPolicy()!=null) {
secProperties.put(SecurityConstants.SIGNATURE_OCSP, trustStoreCertificati.getSecurityMessageTruststoreOCSPPolicy());
}
if(trustStoreCertificati.isSecurityMessageTruststoreRemote()) {
RemoteKeyType keyType = this.modiProperties.getRemoteKeyType(trustStoreCertificati.getSecurityMessageTruststoreType());
secProperties.put(SecurityConstants.JOSE_USE_HEADERS_TRUSTSTORE_REMOTE_STORE_PROVIDER, new RemoteStoreProvider(this.requestInfo, keyType));
secProperties.put(SecurityConstants.JOSE_USE_HEADERS_TRUSTSTORE_REMOTE_STORE_KEY_TYPE, keyType);
secProperties.put(SecurityConstants.JOSE_USE_HEADERS_TRUSTSTORE_REMOTE_STORE_CONFIG, this.modiProperties.getRemoteStoreConfig(trustStoreCertificati.getSecurityMessageTruststoreType(), idSoggetto));
}
if(securityConfig.isX5u() &&
trustStoreSsl!=null && trustStoreSsl.getSecurityMessageTruststorePath()!=null) {
secProperties.put(SecurityConstants.JOSE_USE_HEADERS_TRUSTSTORE_SSL_FILE, trustStoreSsl.getSecurityMessageTruststorePath());
secProperties.put(SecurityConstants.JOSE_USE_HEADERS_TRUSTSTORE_SSL_TYPE, trustStoreSsl.getSecurityMessageTruststoreType());
secProperties.put(SecurityConstants.JOSE_USE_HEADERS_TRUSTSTORE_SSL_PASSWORD, trustStoreSsl.getSecurityMessageTruststorePassword());
if(trustStoreSsl.getSecurityMessageTruststoreCRLs()!=null) {
secProperties.put(SecurityConstants.JOSE_USE_HEADERS_TRUSTSTORE_SSL_CRL, trustStoreSsl.getSecurityMessageTruststoreCRLs());
}
if(trustStoreSsl.getSecurityMessageTruststoreOCSPPolicy()!=null) {
secProperties.put(SecurityConstants.JOSE_USE_HEADERS_TRUSTSTORE_SSL_OCSP, trustStoreSsl.getSecurityMessageTruststoreOCSPPolicy());
}
}
messageSecurityContext.setIncomingProperties(secProperties, false);
DynamicMapBuilderUtils.injectDynamicMap(busta, this.requestInfo, this.context, this.log);
joseSignature.process(messageSecurityContext, msgToken, busta, this.context);
joseSignature.detachSecurity(messageSecurityContext, msgToken.castAsRest());
ModIRESTSecurity restSecurity = (ModIRESTSecurity) msg.getContextProperty(ModICostanti.MODIPA_OPENSPCOOP2_MSG_CONTEXT_SBUSTAMENTO_REST);
if(restSecurity==null) {
restSecurity = new ModIRESTSecurity(securityTokenHeader, request);
msg.addContextProperty(ModICostanti.MODIPA_OPENSPCOOP2_MSG_CONTEXT_SBUSTAMENTO_REST, restSecurity);
}
else {
restSecurity.getTokenHeaderNames().add(securityTokenHeader);
}
ByteArrayOutputStream bout = new ByteArrayOutputStream();
msgToken.writeTo(bout, true);
bout.flush();
bout.close();
payloadToken = bout.toString();
/** System.out.println("PAYLOAD TOKEN ["+payloadToken+"]"); */
x509 = joseSignature.getX509Certificate();
/** System.out.println("CERTIFICATE ["+x509.getSubjectX500Principal().toString()+"]"); */
kid = joseSignature.getCertificateId();
}catch(Exception e) {
logError("Errore durante la validazione del token di sicurezza: "+e.getMessage(),e);
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_FIRMA_NON_VALIDA,
prefix+e.getMessage(),e));
return token;
}
if(integritaKid || useKIDtokenHeader) {
if(kid==null) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(
request ? CodiceErroreCooperazione.SERVIZIO_APPLICATIVO_FRUITORE_NON_PRESENTE :
CodiceErroreCooperazione.SERVIZIO_APPLICATIVO_EROGATORE_NON_PRESENTE,
prefix+"Riferimento alla chiave (kid) non presente"));
}
else {
if(!headerDuplicati || headerAuthentication) {
busta.addProperty(tokenAudit ? ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_AUDIT_KID : ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_KID,
kid);
if(headerDuplicati) {
this.context.addObject(ModICostanti.MODIPA_CONTEXT_KID_AUTHORIZATION, x509);
}
}
else {
String kidAuthorization = null;
Object oKidAuthorization = this.context.removeObject(ModICostanti.MODIPA_CONTEXT_KID_AUTHORIZATION);
if(oKidAuthorization instanceof String) {
kidAuthorization = (String) oKidAuthorization;
}
if(kidAuthorization!=null) {
if(!kidAuthorization.equals(kid)) {
StringBuilder sb = new StringBuilder();
sb.append(HttpConstants.AUTHORIZATION).append(" ");
sb.append("kid=\"").append(kidAuthorization).append("\"");
sb.append("\n");
sb.append(headerTokenRest).append(" ");
sb.append("kid=\"").append(kid).append("\"");
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(
request ? CodiceErroreCooperazione.SERVIZIO_APPLICATIVO_FRUITORE_NON_VALIDO :
CodiceErroreCooperazione.SERVIZIO_APPLICATIVO_EROGATORE_NON_VALIDO,
"I token '"+HttpConstants.AUTHORIZATION+"' e '"+headerTokenRest+"' risultano firmati da certificati differenti\n"+sb.toString()));
}
}
else {
if(erroriValidazione.isEmpty()) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_TOKEN_NON_PRESENTE,
"Riferimento alla chiave (kid) nell'header '"+HttpConstants.AUTHORIZATION+"' non presente"));
}
}
}
if(request &&
(!headerDuplicati || headerAuthentication)
){
if(msg==null || msg.getTransportRequestContext()==null || msg.getTransportRequestContext().getInterfaceName()==null) {
throw new ProtocolException("ID Porta non presente");
}
IDPortaApplicativa idPA = new IDPortaApplicativa();
idPA.setNome(msg.getTransportRequestContext().getInterfaceName());
PortaApplicativa pa = null;
try {
pa = this.factory.getCachedConfigIntegrationReader(this.state, this.requestInfo).getPortaApplicativa(idPA);
}catch(Exception e) {
throw new ProtocolException(e.getMessage(),e);
}
boolean autenticazioneToken = pa!=null && pa.getGestioneToken()!=null && pa.getGestioneToken().getPolicy()!=null && StringUtils.isNotEmpty(pa.getGestioneToken().getPolicy());
if(autenticazioneToken) {
// l'autenticazione dell'applicativo mittente avviene per token
// Il token rappresenta:
// - un integrity nel caso PDND + Integrity
// - una configurazione errata. In questo caso l'header Authorization non verrà validato con successo (es. certificato x509 non presente nel token).
// Se per caso risultasse corretto non è un problema
}
else {
String clientId = readClientIdSafe(payloadToken);
if(clientId!=null) {
/** PER ADESSO NON SUPPORTATO
identificazioneApplicativoMittente(kid,msg,busta);
*/
}
}
}
}
}
else {
if(x509==null || x509.getSubjectX500Principal()==null) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(
request ? CodiceErroreCooperazione.SERVIZIO_APPLICATIVO_FRUITORE_NON_PRESENTE :
CodiceErroreCooperazione.SERVIZIO_APPLICATIVO_EROGATORE_NON_PRESENTE,
prefix+"Certificato X509 mittente non presente"));
}
else {
if(!headerDuplicati || headerAuthentication) {
busta.addProperty(tokenAudit ? ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_AUDIT_X509_SUBJECT : ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_X509_SUBJECT,
x509.getSubjectX500Principal().toString());
if(x509.getIssuerX500Principal()!=null) {
busta.addProperty(tokenAudit ? ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_AUDIT_X509_ISSUER : ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_X509_ISSUER,
x509.getIssuerX500Principal().toString());
}
if(headerDuplicati) {
this.context.addObject(ModICostanti.MODIPA_CONTEXT_X509_AUTHORIZATION, x509);
}
}
else {
/**
String subjectAuthorization = busta.getProperty(busta.getProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_X509_SUBJECT));
String issuerAuthorization = busta.getProperty(busta.getProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_X509_ISSUER));
String subjectIntegrity = x509.getSubjectX500Principal().toString();
String issuerIntegrity = x509.getIssuerX500Principal().toString();
boolean subjectValid = false;
if(subjectIntegrity!=null && subjectAuthorization!=null) {
subjectValid = CertificateUtils.sslVerify(subjectAuthorization, subjectIntegrity, PrincipalType.subject, this.log);
}
boolean issuerValid = true;
if(issuerAuthorization!=null && !"".equals(issuerAuthorization)) {
if(issuerIntegrity==null) {
issuerValid = false;
}
else {
issuerValid = CertificateUtils.sslVerify(issuerAuthorization, issuerIntegrity, PrincipalType.issuer, this.log);
}
}
else {
issuerValid = (issuerIntegrity == null);
}
if(!subjectValid || !issuerValid){
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(
request ? CodiceErroreCooperazione.SERVIZIO_APPLICATIVO_FRUITORE_NON_VALIDO :
CodiceErroreCooperazione.SERVIZIO_APPLICATIVO_EROGATORE_NON_VALIDO,
"I token '"+HttpConstants.AUTHORIZATION+"' e '"+headerTokenRest+"' risultano firmati da certificati differenti"));
}*/
X509Certificate x509Authorization = null;
Object oX509Authorization = this.context.removeObject(ModICostanti.MODIPA_CONTEXT_X509_AUTHORIZATION);
if(oX509Authorization instanceof X509Certificate) {
x509Authorization = (X509Certificate) oX509Authorization;
}
if(x509Authorization!=null) {
if(!x509Authorization.equals(x509)) {
StringBuilder sb = new StringBuilder();
sb.append(HttpConstants.AUTHORIZATION).append(" ");
sb.append("subject=\"").append(x509Authorization.getSubjectX500Principal().toString()).append("\"");
if(x509Authorization.getIssuerX500Principal()!=null) {
sb.append(" issuer=\"").append(x509Authorization.getIssuerX500Principal().toString()).append("\"");
}
sb.append("\n");
sb.append(headerTokenRest).append(" ");
sb.append("subject=\"").append(x509.getSubjectX500Principal().toString()).append("\"");
if(x509.getIssuerX500Principal()!=null) {
sb.append(" issuer=\"").append(x509.getIssuerX500Principal().toString()).append("\"");
}
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(
request ? CodiceErroreCooperazione.SERVIZIO_APPLICATIVO_FRUITORE_NON_VALIDO :
CodiceErroreCooperazione.SERVIZIO_APPLICATIVO_EROGATORE_NON_VALIDO,
"I token '"+HttpConstants.AUTHORIZATION+"' e '"+headerTokenRest+"' risultano firmati da certificati differenti\n"+sb.toString()));
}
}
else {
if(erroriValidazione.isEmpty()) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_TOKEN_NON_PRESENTE,
"Certificato x509 nell'header '"+HttpConstants.AUTHORIZATION+"' non presente"));
}
}
}
if(request &&
(!headerDuplicati || headerAuthentication)
){
if(msg==null || msg.getTransportRequestContext()==null || msg.getTransportRequestContext().getInterfaceName()==null) {
throw new ProtocolException("ID Porta non presente");
}
IDPortaApplicativa idPA = new IDPortaApplicativa();
idPA.setNome(msg.getTransportRequestContext().getInterfaceName());
PortaApplicativa pa = null;
try {
pa = this.factory.getCachedConfigIntegrationReader(this.state, this.requestInfo).getPortaApplicativa(idPA);
}catch(Exception e) {
throw new ProtocolException(e.getMessage(),e);
}
boolean autenticazioneToken = pa!=null && pa.getGestioneToken()!=null && pa.getGestioneToken().getPolicy()!=null && StringUtils.isNotEmpty(pa.getGestioneToken().getPolicy());
if(autenticazioneToken) {
// l'autenticazione dell'applicativo mittente avviene per token
// Il token rappresenta:
// - un integrity nel caso PDND + Integrity
// - una configurazione errata. In questo caso l'header Authorization non verrà validato con successo (es. certificato x509 non presente nel token).
// Se per caso risultasse corretto non è un problema
}
else {
identificazioneApplicativoMittente(x509,msg,busta,msgDiag);
}
}
}
}
if(request && this.context!=null) {
SecurityToken securityTokenForContext = ModIUtilities.newSecurityToken(this.context);
RestMessageSecurityToken restSecurityToken = new RestMessageSecurityToken();
if(x509!=null) {
restSecurityToken.setCertificate(new CertificateInfo(x509, securityTokenHeader));
}
if(kid!=null) {
restSecurityToken.setKid(kid);
}
restSecurityToken.setToken(token);
restSecurityToken.setHttpHeaderName(securityTokenHeader);
if(tokenAudit) {
securityTokenForContext.setAudit(restSecurityToken);
}
else if(headerDuplicati) {
if(headerAuthentication) {
securityTokenForContext.setAuthorization(restSecurityToken);
}
else {
securityTokenForContext.setIntegrity(restSecurityToken);
}
}
else {
if(HttpConstants.AUTHORIZATION.equalsIgnoreCase(securityTokenHeader)) {
securityTokenForContext.setAuthorization(restSecurityToken);
}
else {
securityTokenForContext.setIntegrity(restSecurityToken);
}
}
}
// NOTA: Inizializzare da qua il dynamicMap altrimenti non ci finisce l'identificazione del mittente effettuata dal metodo sopra 'identificazioneApplicativoMittente'
Map<String, Object> dynamicMap = null;
Map<String, Object> dynamicMapRequest = null;
if(!request) {
dynamicMapRequest = ModIUtilities.removeDynamicMapRequest(this.context);
}
try {
if(dynamicMapRequest!=null) {
dynamicMap = DynamicUtils.buildDynamicMapResponse(msg, this.context, null, this.log, bufferMessageReadOnly, dynamicMapRequest);
}
else {
dynamicMap = DynamicUtils.buildDynamicMap(msg, this.context, datiRichiesta, this.log, bufferMessageReadOnly);
ModIUtilities.saveDynamicMapRequest(this.context, dynamicMap);
}
}catch(Exception e) {
throw new ProtocolException(e.getMessage(),e);
}
if(dynamicMapParameter!=null && dynamicMap!=null) {
dynamicMapParameter.putAll(dynamicMap);
}
try {
JsonNode jsonNode = JSONUtils.getInstance().getAsNode(payloadToken);
if(!(jsonNode instanceof ObjectNode)) {
throw new ProtocolException("Payload del token possiede una struttura non valida");
}
ObjectNode objectNode = (ObjectNode) jsonNode;
if(objectNode.has(Claims.JSON_WEB_TOKEN_RFC_7519_ISSUED_AT)) {
Object iat = objectNode.get(Claims.JSON_WEB_TOKEN_RFC_7519_ISSUED_AT);
if(iat==null) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.ORA_REGISTRAZIONE_NON_PRESENTE,
prefix+getErroreTokenSenzaClaim(Claims.JSON_WEB_TOKEN_RFC_7519_ISSUED_AT)));
}
Date iatDate = toDate(iat, erroriValidazione, CodiceErroreCooperazione.ORA_REGISTRAZIONE_NON_VALIDA, prefix, Claims.JSON_WEB_TOKEN_RFC_7519_ISSUED_AT);
if(iatDate!=null) { // altrimenti viene segnalato errore in erroriValidazione
String iatValue = DateUtils.getSimpleDateFormatMs().format(iatDate);
if(!headerDuplicati || headerAuthentication) {
busta.addProperty(tokenAudit ? ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_AUDIT_IAT : ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_IAT,
iatValue);
}
else {
String iatAuthorization = busta.getProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_IAT);
if(!iatValue.equals(iatAuthorization)) {
busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_REST_INTEGRITY_IAT, iatValue);
}
}
}
}
else {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.ORA_REGISTRAZIONE_NON_PRESENTE,
prefix+getErroreTokenSenzaClaim(Claims.JSON_WEB_TOKEN_RFC_7519_ISSUED_AT)));
}
if(objectNode.has(Claims.JSON_WEB_TOKEN_RFC_7519_EXPIRED)) {
Object exp = objectNode.get(Claims.JSON_WEB_TOKEN_RFC_7519_EXPIRED);
if(exp==null) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SCADENZA_NON_PRESENTE,
prefix+getErroreTokenSenzaClaim(Claims.JSON_WEB_TOKEN_RFC_7519_EXPIRED)));
}
Date expDate = toDate(exp, erroriValidazione, CodiceErroreCooperazione.SCADENZA_NON_VALIDA, prefix, Claims.JSON_WEB_TOKEN_RFC_7519_EXPIRED);
if(expDate!=null) { // altrimenti viene segnalato errore in erroriValidazione
String expValue = DateUtils.getSimpleDateFormatMs().format(expDate);
if(!headerDuplicati || headerAuthentication) {
busta.addProperty(tokenAudit ? ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_AUDIT_EXP : ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_EXP,
expValue);
}
else {
String expAuthorization = busta.getProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_EXP);
if(!expValue.equals(expAuthorization)) {
busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_REST_INTEGRITY_EXP, expValue);
}
}
}
}
else {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SCADENZA_NON_PRESENTE,
prefix+getErroreTokenSenzaClaim(Claims.JSON_WEB_TOKEN_RFC_7519_EXPIRED)));
}
if(objectNode.has(Claims.JSON_WEB_TOKEN_RFC_7519_NOT_TO_BE_USED_BEFORE)) {
Object nbf = objectNode.get(Claims.JSON_WEB_TOKEN_RFC_7519_NOT_TO_BE_USED_BEFORE);
if(nbf!=null) {
Date nbfDate = toDate(nbf, erroriValidazione, CodiceErroreCooperazione.SCADENZA_NON_VALIDA, prefix, Claims.JSON_WEB_TOKEN_RFC_7519_NOT_TO_BE_USED_BEFORE);
if(nbfDate!=null) { // altrimenti viene segnalato errore in erroriValidazione
String nbfValue = DateUtils.getSimpleDateFormatMs().format(nbfDate);
if(!headerDuplicati || headerAuthentication) {
busta.addProperty(tokenAudit ? ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_AUDIT_NBF : ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_NBF,
nbfValue);
}
else {
String nbfAuthorization = busta.getProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_NBF);
if(!nbfValue.equals(nbfAuthorization)) {
busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_REST_INTEGRITY_NBF, nbfValue);
}
}
}
}
}
if(objectNode.has(Claims.JSON_WEB_TOKEN_RFC_7519_AUDIENCE)) {
Object aud = objectNode.get(Claims.JSON_WEB_TOKEN_RFC_7519_AUDIENCE);
if(aud==null) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(
request ? CodiceErroreCooperazione.SERVIZIO_APPLICATIVO_EROGATORE_NON_PRESENTE :
CodiceErroreCooperazione.SERVIZIO_APPLICATIVO_FRUITORE_NON_PRESENTE,
prefix+getErroreTokenSenzaClaim(Claims.JSON_WEB_TOKEN_RFC_7519_AUDIENCE)));
}
else {
String audValue = toString(aud);
if(tokenAudit) {
String audAuthorization = busta.getProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_REST_AUDIENCE);
if(audAuthorization==null || !audValue.equals(audAuthorization)) {
busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_AUDIT_AUDIENCE, audValue);
}
}
else {
if(!headerDuplicati || headerAuthentication) {
busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_REST_AUDIENCE, audValue);
}
else {
String audAuthorization = busta.getProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_REST_AUDIENCE);
if(!audValue.equals(audAuthorization)) {
busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_REST_INTEGRITY_AUDIENCE, audValue);
}
}
}
}
}
else {
if(request || buildSecurityTokenInRequest) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(
request ? CodiceErroreCooperazione.SERVIZIO_APPLICATIVO_EROGATORE_NON_PRESENTE :
CodiceErroreCooperazione.SERVIZIO_APPLICATIVO_FRUITORE_NON_PRESENTE,
prefix+getErroreTokenSenzaClaim(Claims.JSON_WEB_TOKEN_RFC_7519_AUDIENCE)));
}
}
boolean jtiRequired = false;
if(ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM02.equals(securityMessageProfile) ||
ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0302.equals(securityMessageProfile) ||
ModICostanti.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_VALUE_IDAM0402.equals(securityMessageProfile)) {
jtiRequired = true;
}
if(objectNode.has(Claims.JSON_WEB_TOKEN_RFC_7519_JWT_ID)) {
Object jti = objectNode.get(Claims.JSON_WEB_TOKEN_RFC_7519_JWT_ID);
if(jti==null) {
if(jtiRequired) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.IDENTIFICATIVO_MESSAGGIO_NON_PRESENTE,
prefix+getErroreTokenSenzaClaim(Claims.JSON_WEB_TOKEN_RFC_7519_JWT_ID)));
}
}
else {
String id = toString(jti);
if(tokenAudit) {
busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_AUDIT_ID, id);
}
else {
boolean addAsIdBusta = true;
if(headerDuplicati) {
if(headerAuthentication) {
if(!securityConfig.isMultipleHeaderUseJtiAuthorizationAsIdMessaggio()) {
String idActual = busta.getProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_ID);
if(idActual==null || !idActual.equals(id)) {
busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_REST_AUTHORIZATION_ID, id);
}
addAsIdBusta = false;
}
}
else {
if(securityConfig.isMultipleHeaderUseJtiAuthorizationAsIdMessaggio()) {
String idActual = busta.getProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_ID);
if(idActual==null || !idActual.equals(id)) {
busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_REST_INTEGRITY_ID, id);
}
addAsIdBusta = false;
}
else {
// verifico se ho gia' impostato authorization
String idActualAuthorization = busta.getProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_REST_AUTHORIZATION_ID);
if(idActualAuthorization!=null && idActualAuthorization.equals(id)) {
busta.removeProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_REST_AUTHORIZATION_ID);
}
}
}
}
if(addAsIdBusta) {
busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_ID, id);
if(id.length()<=255) {
busta.setID(id);
}
}
}
}
}
else {
if(jtiRequired) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.IDENTIFICATIVO_MESSAGGIO_NON_PRESENTE,
prefix+getErroreTokenSenzaClaim(Claims.JSON_WEB_TOKEN_RFC_7519_JWT_ID)));
}
}
if(!request) {
corniceSicurezza = false; // permessa solo per i messaggi di richiesta
}
boolean readIss = true;
boolean readSub = true;
if(corniceSicurezza) {
if(CostantiDB.MODIPA_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_PATTERN_OLD.equals(patternCorniceSicurezza)) {
readIss = readCorniceSicurezzaCodiceEnteLegacy(objectNode, busta,
erroriValidazione, prefix);
readSub = readCorniceSicurezzaUserLegacy(objectNode, busta,
erroriValidazione, prefix);
readCorniceSicurezzaIpUserLegacy(objectNode, busta,
erroriValidazione, prefix);
}
else {
readCorniceSicurezzaSchema(objectNode, msg, busta,
erroriValidazione, prefix,
schemaCorniceSicurezza, securityConfig.getCorniceSicurezzaSchemaConfig());
}
}
if(readIss &&
objectNode.has(Claims.JSON_WEB_TOKEN_RFC_7519_ISSUER)) {
Object iss = objectNode.get(Claims.JSON_WEB_TOKEN_RFC_7519_ISSUER);
if(iss!=null) {
busta.addProperty(tokenAudit ? ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_AUDIT_ISSUER : ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_REST_ISSUER,
toString(iss));
}
}
if(readSub &&
objectNode.has(Claims.JSON_WEB_TOKEN_RFC_7519_SUBJECT)) {
Object sub = objectNode.get(Claims.JSON_WEB_TOKEN_RFC_7519_SUBJECT);
if(sub!=null) {
busta.addProperty(tokenAudit ? ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_AUDIT_SUBJECT : ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_REST_SUBJECT,
toString(sub));
}
}
Object clientId = readObjectClientId(objectNode);
if(clientId!=null) {
String clientIdValue = toString(clientId);
busta.addProperty(tokenAudit ? ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_AUDIT_CLIENT_ID : ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_REST_CLIENT_ID,clientIdValue);
}
if( (tokenAudit || integritaX509 || integritaKid)
&&
objectNode.has(Costanti.PDND_PURPOSE_ID)
) {
Object purposeId = objectNode.get(Costanti.PDND_PURPOSE_ID);
if(purposeId!=null) {
busta.addProperty(tokenAudit ? ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_AUDIT_PURPOSE_ID : ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_REST_INTEGRITY_PURPOSE_ID,
toString(purposeId));
}
}
String digestHeader = HttpConstants.DIGEST;
String digestValueInHeaderHTTP = null;
if(integrita && !integritaCustom) {
List<String> digests = null;
if(msg!=null) {
if(request && msg.getTransportRequestContext()!=null) {
digests = msg.getTransportRequestContext().getHeaderValues(digestHeader);
}
else if(!request && msg.getTransportResponseContext()!=null) {
digests = msg.getTransportResponseContext().getHeaderValues(digestHeader);
}
}
String digest = null;
if(digests!=null && !digests.isEmpty()) {
digest = digests.get(0);
}
if(digest==null) {
if(msg.castAsRest().hasContent()) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.PROFILO_TRASMISSIONE_NON_PRESENTE,
getErrorHeaderHttpNonPresente(digestHeader)));
}
}
else if(digests.size()>1) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.PROFILO_TRASMISSIONE_PRESENTE_PIU_VOLTE,
getErrorHeaderHttpPresentePiuVolte(digestHeader)));
}
else {
digestValueInHeaderHTTP = toString(digest);
busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_DIGEST, digestValueInHeaderHTTP);
if(request && includiRequestDigest && this.context!=null) {
this.context.addObject(ModICostanti.MODIPA_CONTEXT_REQUEST_DIGEST, digestValueInHeaderHTTP);
}
if(!msg.castAsRest().hasContent()) {
String role = MessageRole.REQUEST.equals(msg.getMessageRole()) ? "richiesta" : "risposta";
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_FIRMA_INTESTAZIONE_NON_VALIDA,
getErrorHeaderHttpPrefix(digestHeader)+" presente in una "+role+" con http payload vuoto"));
}
}
}
if(digestValueInHeaderHTTP!=null) {
// Produco Digest Headers
ByteArrayOutputStream bout = new ByteArrayOutputStream();
msg.castAsRest().writeTo(bout, false, bufferMessageReadOnly, idTransazione);
bout.flush();
bout.close();
List<DigestEncoding> digestEncoding = securityConfig.getDigestEncodingAccepted();
Map<DigestEncoding, String> newDigestValue = null;
boolean formatoSupportato = true;
if(digestValueInHeaderHTTP.startsWith(HttpConstants.DIGEST_ALGO_SHA_256+"=")) {
newDigestValue = HttpUtilities.getDigestHeaderValues(bout.toByteArray(), HttpConstants.DIGEST_ALGO_SHA_256,
digestEncoding.toArray(new DigestEncoding[1]));
}
else if(digestValueInHeaderHTTP.startsWith(HttpConstants.DIGEST_ALGO_SHA_384+"=")) {
newDigestValue = HttpUtilities.getDigestHeaderValues(bout.toByteArray(), HttpConstants.DIGEST_ALGO_SHA_384,
digestEncoding.toArray(new DigestEncoding[1]));
}
else if(digestValueInHeaderHTTP.startsWith(HttpConstants.DIGEST_ALGO_SHA_512+"=")) {
newDigestValue = HttpUtilities.getDigestHeaderValues(bout.toByteArray(), HttpConstants.DIGEST_ALGO_SHA_512,
digestEncoding.toArray(new DigestEncoding[1]));
}
else {
formatoSupportato = false;
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_FIRMA_INTESTAZIONE_NON_VALIDA,
getErrorHeaderHttpPrefix(digestHeader)+" con un formato non supportato"));
}
if(formatoSupportato) {
if(newDigestValue==null || newDigestValue.isEmpty()) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_FIRMA_INTESTAZIONE_NON_VALIDA,
"Calcolo Digest fallito"));
}
else {
boolean valido = false;
for (DigestEncoding de : digestEncoding) {
String check = newDigestValue.get(de);
if(check==null) { // non deve succedere
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_FIRMA_INTESTAZIONE_NON_VALIDA,
"Encoding Digest '"+de+"' fallito"));
}
else if(check.equals(digestValueInHeaderHTTP)){
valido=true;
break;
}
}
if(!valido) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_FIRMA_NON_VALIDA,
getErrorHeaderHttpPrefix(digestHeader)+" possiede un valore non corrispondente al messaggio"));
}
/** else {
// System.out.println("VERIFICATO DIGEST HTTP");
// }*/
}
}
}
String claimSignedHeader = this.modiProperties.getRestSecurityTokenClaimSignedHeaders();
if(integrita && !integritaCustom && objectNode.has(claimSignedHeader)) {
boolean findDigestInClaimSignedHeader = false;
Map<String, List<String>> headerHttpAttesi = new HashMap<>();
Object signedHeaders = objectNode.get(claimSignedHeader);
if(signedHeaders==null) {
if(integrita && msg.castAsRest().hasContent()) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_FIRMA_INTESTAZIONE_NON_PRESENTE,
prefix+getErroreTokenSenzaClaim(claimSignedHeader)));
}
}
else {
readSignedHeaders(signedHeaders, erroriValidazione, prefix, headerDuplicati,
busta, headerHttpAttesi,
claimSignedHeader);
}
if(headerHttpAttesi!=null && !headerHttpAttesi.isEmpty()) {
Iterator<String> headers = headerHttpAttesi.keySet().iterator();
while (headers.hasNext()) {
String hdrName = headers.next();
List<String> hrdAttesiValues = headerHttpAttesi.get(hdrName);
boolean checkHdrAttesiSize = true;
List<String> hdrFound = null;
for (String hdrAttesoValue : hrdAttesiValues) {
boolean valid = false;
String valueInHttpHeader = null;
boolean multiHeader = false;
if(digestHeader.toLowerCase().equalsIgnoreCase(hdrName)) {
checkHdrAttesiSize = false; // il controllo che non esista piu' di un header digest e' stato fatto in precedenza
findDigestInClaimSignedHeader = true;
if(digestValueInHeaderHTTP==null) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_FIRMA_NON_VALIDA,
getErrorHeaderHttpPrefix(hdrName)+", dichiarato tra gli header firmati, non trovato"));
valid = true; // per non far segnalare l'eccezione, che e' stata personalizzata sopra
}
else {
valueInHttpHeader = digestValueInHeaderHTTP;
valid = hdrAttesoValue.equals(digestValueInHeaderHTTP);
/**System.out.println("VALID DIGEST: "+valid);*/
}
}
else {
if(request && msg.getTransportRequestContext()!=null) {
hdrFound = msg.getTransportRequestContext().getHeaderValues(hdrName);
}
else if(!request && msg.getTransportResponseContext()!=null) {
hdrFound = msg.getTransportResponseContext().getHeaderValues(hdrName);
}
if(checkHdrAttesiSize && hdrFound!=null) {
// Fix: per verificare che non esistano altri copie dell'header, oltre a quelli attesi, con valori differenti
if(hrdAttesiValues.size()!=hdrFound.size()) {
logError(getErrorHeaderHttpPrefix(hdrName)+" possiede "+(hdrFound!=null ? hdrFound.size() : 0)+" valori '"+(hdrFound!=null ? hdrFound.toString() : "non presente")+
"' mentre negli header firmati sono presenti "+hrdAttesiValues.size()+" valori '"+hrdAttesiValues.toString()+"'");
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_FIRMA_NON_VALIDA,
getErrorHeaderHttpPrefix(hdrName)+" possiede un numero di valori ("+(hdrFound!=null ? hdrFound.size() : 0)
+") differente rispetto al numero di valori ("+hrdAttesiValues.size()+") definiti negli header firmati"));
valid = true; // per non far segnalare l'eccezione, che e' stata personalizzata sopra
if(valid) {
break; // e' inutile continuare a controllare i valori degli header
}
}
checkHdrAttesiSize=false; // questo controllo per ogni header basta 1 volta, non serve farlo per ogni valore
}
if(hdrFound==null || hdrFound.isEmpty()) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_FIRMA_NON_VALIDA,
getErrorHeaderHttpPrefix(hdrName)+", dichiarato tra gli header firmati, non trovato"));
valid = true; // per non far segnalare l'eccezione, che e' stata personalizzata sopra
if(valid) {
break; // e' inutile continuare a controllare i valori degli header
}
}
else if(hdrFound.size()==1) {
valueInHttpHeader = hdrFound.get(0);
valid = hdrAttesoValue.equals(valueInHttpHeader);
}
else {
multiHeader = true;
valueInHttpHeader = hdrFound.toString();
valid = hdrFound.contains(hdrAttesoValue);
}
/**System.out.println("VALID HDR '"+hdrName+"': "+valid);*/
}
if(!valid) {
String errorMsg = "possiede un valore '"+valueInHttpHeader+"' differente";
String errorExc = "possiede un valore differente";
if(multiHeader) {
errorMsg = "possiede dei valori '"+valueInHttpHeader+"' differenti";
errorExc = "possiede dei valori differenti";
}
logError(getErrorHeaderHttpPrefix(hdrName)+" "+errorMsg+" rispetto a quello presente negli header firmati '"+hdrAttesoValue+"'");
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_FIRMA_NON_VALIDA,
getErrorHeaderHttpPrefix(hdrName)+" "+errorExc+" rispetto a quello presente negli header firmati"));
}
}
}
}
if(integrita && msg.castAsRest().hasContent() &&
!findDigestInClaimSignedHeader) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_FIRMA_INTESTAZIONE_NON_PRESENTE,
getErrorHeaderHttpPrefix(digestHeader)+" non presente nella lista degli header firmati (token claim '"+claimSignedHeader+"')"));
}
}
else {
if(integrita && !integritaCustom && msg.castAsRest().hasContent()) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_FIRMA_INTESTAZIONE_NON_PRESENTE,
prefix+getErroreTokenSenzaClaim(claimSignedHeader)));
}
}
}catch(Exception e) {
logError("Errore durante il processamento del payload del token di sicurezza: "+e.getMessage(),e);
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_TOKEN_NON_VALIDO,
prefix+e.getMessage()));
}
return token;
}
private void readSignedHeaders(Object signedHeaders, List<Eccezione> erroriValidazione, String prefix, boolean headerDuplicati,
Busta busta, Map<String, List<String>> headerHttpAttesi,
String claimSignedHeader) throws ProtocolException {
try {
if(signedHeaders instanceof ArrayNode) {
ArrayNode arrayNode = (ArrayNode) signedHeaders;
if(arrayNode.size()<=0) {
throw new ProtocolException("atteso un array con almeno un valore");
}
for (int i = 0; i < arrayNode.size(); i++) {
JsonNode hdrNode = arrayNode.get(i);
String prefixArray = "array["+i+"]";
if(hdrNode==null) {
throw new ProtocolException(prefixArray+" non possiede un valore");
}
if(!(hdrNode instanceof ObjectNode)) {
throw new ProtocolException(prefixArray+" possiede una struttura errata");
}
ObjectNode oNode = (ObjectNode) hdrNode;
if(oNode.size()<=0) {
throw new ProtocolException(prefixArray+" possiede una struttura senza elementi");
}
Iterator<String> fieldNames = oNode.fieldNames();
while (fieldNames.hasNext()) {
String hdrName = fieldNames.next();
addSignedHeader(oNode, hdrName, headerDuplicati,
busta, headerHttpAttesi, prefixArray);
}
}
}
else {
throw new ProtocolException("atteso un array");
}
}catch(Exception e) {
logError("Errore durante il processamento del claim che definisce gli header HTTP firmati '"+claimSignedHeader+"': "+e.getMessage(),e);
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.SICUREZZA_FIRMA_INTESTAZIONE_NON_VALIDA,
prefix+"Claim '"+claimSignedHeader+"' con un formato non valido; "+ e.getMessage()));
}
}
private void addSignedHeader(ObjectNode oNode, String hdrName, boolean headerDuplicati,
Busta busta, Map<String, List<String>> headerHttpAttesi, String prefixArray) throws ProtocolException {
try {
String hdrValue = toString(oNode.get(hdrName));
if(HttpConstants.AUTHORIZATION.equalsIgnoreCase(hdrName) && headerDuplicati) {
ModIUtilities.addHeaderProperty(busta, hdrName, HttpConstants.AUTHORIZATION_PREFIX_BEARER +"...TOKEN...");
}
else {
ModIUtilities.addHeaderProperty(busta, hdrName, hdrValue);
}
TransportUtils.addHeader(headerHttpAttesi, hdrName, hdrValue);
}catch(Exception e) {
throw new ProtocolException(prefixArray+" possiede header '"+hdrName+"' con un valore non valido: "+e.getMessage(),e);
}
}
private String readClientIdSafe(String payloadToken) {
try {
JsonNode jsonNode = JSONUtils.getInstance().getAsNode(payloadToken);
if(!(jsonNode instanceof ObjectNode)) {
throw new ProtocolException("Payload del token possiede una struttura non valida");
}
ObjectNode objectNode = (ObjectNode) jsonNode;
Object clientIdO = readObjectClientId(objectNode);
if(clientIdO!=null) {
return toString(clientIdO);
}
return null;
}catch(Exception e) {
// ignore
return null;
}
}
private Object readObjectClientId(ObjectNode objectNode) throws ProtocolException {
Object clientId = null;
String claimName = this.modiProperties.getRestSecurityTokenClaimsClientIdHeader();
if(objectNode.has(Claims.INTROSPECTION_RESPONSE_RFC_7662_CLIENT_ID)) {
clientId = objectNode.get(Claims.INTROSPECTION_RESPONSE_RFC_7662_CLIENT_ID);
}
else if(objectNode.has(Claims.OIDC_ID_TOKEN_AZP)) {
clientId = objectNode.get(Claims.OIDC_ID_TOKEN_AZP);
}
else if(objectNode.has(claimName)) {
clientId = objectNode.get(claimName);
}
return clientId;
}
private void readCorniceSicurezzaSchema(ObjectNode objectNode, OpenSPCoop2Message msg, Busta busta,
List<Eccezione> erroriValidazione, String prefix,
String schemaCorniceSicurezza, ModIAuditConfig auditConfig) throws ProtocolException {
if(schemaCorniceSicurezza!=null && StringUtils.isNotEmpty(schemaCorniceSicurezza) && auditConfig!=null) {
readCorniceSicurezzaSchema(objectNode, msg, busta,
erroriValidazione, prefix, auditConfig.getClaims());
}
}
private void readCorniceSicurezzaSchema(ObjectNode objectNode, OpenSPCoop2Message msg, Busta busta,
List<Eccezione> erroriValidazione, String prefix,
List<ModIAuditClaimConfig> claims) throws ProtocolException {
if(claims!=null && !claims.isEmpty()) {
for (ModIAuditClaimConfig modIAuditClaimConfig : claims) {
String claimName = modIAuditClaimConfig.getNome();
if(objectNode.has(claimName)) {
Object o = objectNode.get(claimName);
if(o!=null) {
processCorniceSicurezzaSchemaClaimValue(msg, modIAuditClaimConfig, busta,
erroriValidazione, prefix,
claimName, o);
}
}
else if(modIAuditClaimConfig.isRequired()){
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.MITTENTE_NON_PRESENTE,
prefix+getErroreTokenSenzaClaim(claimName)));
}
}
}
}
private void processCorniceSicurezzaSchemaClaimValue(OpenSPCoop2Message msg, ModIAuditClaimConfig modIAuditClaimConfig, Busta busta,
List<Eccezione> erroriValidazione, String prefix,
String claimName, Object o) throws ProtocolException {
String v = toString(o);
// Trace
if(modIAuditClaimConfig.isTrace()) {
busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_AUDIT_PREFIX+claimName, v);
}
// Validazione
ModIValidazioneAuditClaimValue validator = new ModIValidazioneAuditClaimValue(claimName, v, o, modIAuditClaimConfig);
validator.validate(this.validazioneUtils, erroriValidazione, prefix);
// Forward
String header = modIAuditClaimConfig.getForwardBackend();
if(header!=null && StringUtils.isNotEmpty(header)) {
msg.forceTransportHeader(header, v);
}
}
private boolean readCorniceSicurezzaCodiceEnteLegacy(ObjectNode objectNode, Busta busta,
List<Eccezione> erroriValidazione, String prefix) throws ProtocolException {
boolean readIss = true;
String claimNameCodiceEnte = this.modiProperties.getSicurezzaMessaggioCorniceSicurezzaRestCodiceEnte();
if(Claims.JSON_WEB_TOKEN_RFC_7519_ISSUER.equals(claimNameCodiceEnte)) {
readIss = false;
}
if(objectNode.has(claimNameCodiceEnte)) {
Object codiceEnte = objectNode.get(claimNameCodiceEnte);
if(codiceEnte!=null) {
busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_CORNICE_SICUREZZA_ENTE, toString(codiceEnte));
}
}
else {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.MITTENTE_NON_PRESENTE,
prefix+getErroreTokenSenzaClaim(claimNameCodiceEnte)));
}
return readIss;
}
private boolean readCorniceSicurezzaUserLegacy(ObjectNode objectNode, Busta busta,
List<Eccezione> erroriValidazione, String prefix) throws ProtocolException {
boolean readSub = true;
String claimNameUser = this.modiProperties.getSicurezzaMessaggioCorniceSicurezzaRestUser();
if(Claims.JSON_WEB_TOKEN_RFC_7519_SUBJECT.equals(claimNameUser)) {
readSub = false;
}
if(objectNode.has(claimNameUser)) {
Object user = objectNode.get(claimNameUser);
if(user!=null) {
busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_CORNICE_SICUREZZA_USER, toString(user));
}
}
else {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.MITTENTE_NON_PRESENTE,
prefix+getErroreTokenSenzaClaim(claimNameUser)));
}
return readSub;
}
private void readCorniceSicurezzaIpUserLegacy(ObjectNode objectNode, Busta busta,
List<Eccezione> erroriValidazione, String prefix) throws ProtocolException {
String claimNameIpUser = this.modiProperties.getSicurezzaMessaggioCorniceSicurezzaRestIpuser();
if(objectNode.has(claimNameIpUser)) {
Object userIp = objectNode.get(claimNameIpUser);
if(userIp!=null) {
busta.addProperty(ModICostanti.MODIPA_BUSTA_EXT_PROFILO_SICUREZZA_MESSAGGIO_CORNICE_SICUREZZA_CORNICE_SICUREZZA_USER_IP, toString(userIp));
}
}
else {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.MITTENTE_NON_PRESENTE,
prefix+getErroreTokenSenzaClaim(claimNameIpUser)));
}
}
private Date toDate(Object tmp, List<Eccezione> erroriValidazione, CodiceErroreCooperazione codiceErroreCooperazione,String prefix,String claim) throws ProtocolException {
try {
return toDate(tmp);
}catch(Exception e) {
erroriValidazione.add(this.validazioneUtils.newEccezioneValidazione(codiceErroreCooperazione,
prefix+getErroreTokenClaimNonValido(claim,e),e));
return null;
}
}
private Date toDate(Object tmp) throws ProtocolException {
String tmpV = null;
if(tmp==null) {
throw new ProtocolException("Value undefined");
}
if(tmp instanceof String) {
tmpV = (String) tmp;
}
else {
tmpV = toString(tmp);
}
Date d = TokenUtils.parseTimeInSecond(tmpV);
if(d!=null) {
return d;
}
throw new ProtocolException("Value '"+tmpV+"' not valid");
}
private String toString(Object tmp) {
if(tmp instanceof TextNode) {
TextNode text = (TextNode) tmp;
return text.asText();
}
return tmp.toString();
}
}