PDNDResolver.java
- /*
- * GovWay - A customizable API Gateway
- * https://govway.org
- *
- * Copyright (c) 2005-2025 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.pdd.config;
- import java.io.Serializable;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import org.openspcoop2.core.commons.CoreException;
- import org.openspcoop2.core.constants.Costanti;
- import org.openspcoop2.core.id.IDSoggetto;
- import org.openspcoop2.core.transazioni.utils.CredenzialiMittente;
- import org.openspcoop2.pdd.core.autenticazione.GestoreAutenticazione;
- import org.openspcoop2.pdd.core.keystore.KeystoreException;
- import org.openspcoop2.pdd.core.keystore.RemoteStoreProvider;
- import org.openspcoop2.pdd.core.token.InformazioniToken;
- import org.openspcoop2.pdd.core.token.TokenUtilities;
- import org.openspcoop2.pdd.core.transazioni.Transaction;
- import org.openspcoop2.pdd.core.transazioni.TransactionContext;
- import org.openspcoop2.pdd.core.transazioni.TransactionDeletedException;
- import org.openspcoop2.pdd.core.transazioni.TransactionNotExistsException;
- import org.openspcoop2.protocol.engine.SecurityTokenUtilities;
- import org.openspcoop2.protocol.sdk.Context;
- import org.openspcoop2.protocol.sdk.PDNDTokenInfo;
- import org.openspcoop2.protocol.sdk.PDNDTokenInfoDetails;
- import org.openspcoop2.protocol.sdk.ProtocolException;
- import org.openspcoop2.protocol.sdk.SecurityToken;
- import org.openspcoop2.protocol.sdk.state.RequestInfo;
- import org.openspcoop2.security.SecurityException;
- import org.openspcoop2.security.keystore.cache.GestoreKeystoreCache;
- import org.openspcoop2.utils.UtilsException;
- import org.openspcoop2.utils.certificate.remote.RemoteKeyType;
- import org.openspcoop2.utils.certificate.remote.RemoteStoreClientInfo;
- import org.openspcoop2.utils.certificate.remote.RemoteStoreConfig;
- import org.openspcoop2.utils.json.JSONUtils;
- import com.fasterxml.jackson.databind.JsonNode;
- /**
- * PDNDResolver
- *
- * @author Poli Andrea (poli@link.it)
- * @author $Author$
- * @version $Rev$, $Date$
- */
- public class PDNDResolver {
-
- private Context context;
- private List<RemoteStoreConfig> remoteStores;
-
- public PDNDResolver(Context context, List<RemoteStoreConfig> remoteStores) {
- this.context = context;
- this.remoteStores = remoteStores;
- }
-
-
- public boolean isRemoteStore(String name) {
- return isRemoteStore(name, this.remoteStores);
- }
- public static boolean isRemoteStore(String name, List<RemoteStoreConfig> remoteStores) {
- for (RemoteStoreConfig rsc : remoteStores) {
- if(name.equals(rsc.getStoreName())) {
- return true;
- }
- }
- return false;
- }
-
- public RemoteStoreConfig getRemoteStoreConfig(String name, IDSoggetto idDominio) throws ProtocolException {
- return getRemoteStoreConfig(name, idDominio, this.remoteStores);
- }
- public static RemoteStoreConfig getRemoteStoreConfig(String name, IDSoggetto idDominio, List<RemoteStoreConfig> remoteStores) throws ProtocolException {
- for (RemoteStoreConfig rsc : remoteStores) {
- if(name.equals(rsc.getStoreName())) {
- if(rsc.isMultitenant() && idDominio!=null && idDominio.getNome()!=null) {
- try {
- return rsc.newInstanceMultitenant(idDominio.getNome());
- }catch(Exception e){
- throw new ProtocolException(e.getMessage(),e);
- }
- }
- return rsc;
- }
- }
- return null;
- }
-
- public RemoteStoreConfig getRemoteStoreConfigByTokenPolicy(String name, IDSoggetto idDominio) throws ProtocolException {
- return getRemoteStoreConfigByTokenPolicy(name, idDominio, this.remoteStores);
- }
- public static RemoteStoreConfig getRemoteStoreConfigByTokenPolicy(String name, IDSoggetto idDominio, List<RemoteStoreConfig> remoteStores) throws ProtocolException {
- for (RemoteStoreConfig rsc : remoteStores) {
- if(name.equals(rsc.getTokenPolicy())) {
- if(rsc.isMultitenant() && idDominio!=null && idDominio.getNome()!=null) {
- try {
- return rsc.newInstanceMultitenant(idDominio.getNome());
- }catch(Exception e){
- throw new ProtocolException(e.getMessage(),e);
- }
- }
- return rsc;
- }
- }
- return null;
- }
-
- public RemoteStoreConfig enrichTokenInfo(RequestInfo requestInfo, IDSoggetto idSoggetto,
- InformazioniToken informazioniToken, SecurityToken securityTokenForContext) throws ProtocolException {
- return enrichTokenInfo(requestInfo, false, false, idSoggetto,
- informazioniToken, securityTokenForContext);
- }
- public RemoteStoreConfig enrichTokenInfo(RequestInfo requestInfo, boolean sicurezzaMessaggio, boolean sicurezzaAudit, IDSoggetto idSoggetto) throws ProtocolException {
- Object oInformazioniTokenNormalizzate = null;
- if(this.context!=null) {
- oInformazioniTokenNormalizzate = this.context.getObject(org.openspcoop2.pdd.core.token.Costanti.PDD_CONTEXT_TOKEN_INFORMAZIONI_NORMALIZZATE);
- }
- InformazioniToken informazioniTokenNormalizzate = null;
- if(oInformazioniTokenNormalizzate instanceof InformazioniToken) {
- informazioniTokenNormalizzate = (InformazioniToken) oInformazioniTokenNormalizzate;
- }
-
- SecurityToken securityTokenForContext = SecurityTokenUtilities.readSecurityToken(this.context);
-
- return enrichTokenInfo(requestInfo, sicurezzaMessaggio, sicurezzaAudit, idSoggetto,
- informazioniTokenNormalizzate, securityTokenForContext);
- }
- private RemoteStoreConfig enrichTokenInfo(RequestInfo requestInfo, boolean sicurezzaMessaggio, boolean sicurezzaAudit, IDSoggetto idSoggetto,
- InformazioniToken informazioniToken, SecurityToken securityTokenForContext) throws ProtocolException {
-
- OpenSPCoop2Properties op2Properties = OpenSPCoop2Properties.getInstance();
- RemoteStoreConfig rsc = null;
- try {
- if(op2Properties.isGestoreChiaviPDNDclientInfoEnabled()) {
-
- rsc = getRemoteStoreConfig(idSoggetto);
- if(rsc==null) {
- return rsc;
- }
-
- String clientId = null;
- if(informazioniToken!=null) {
- clientId = informazioniToken.getClientId();
- }
- if(clientId==null) {
- return rsc;
- }
-
- // NOTA: il kid DEVE essere preso dall'eventuale token di integrità, poichè il kid nell'access token è sempre uguale ed è quello della PDND
- String kid = readKid(sicurezzaMessaggio, sicurezzaAudit, securityTokenForContext, clientId);
-
- enrichTokenInfo(requestInfo, idSoggetto,
- informazioniToken, securityTokenForContext,
- rsc, clientId, kid);
- }
- }catch(Exception e) {
- throw new ProtocolException(e.getMessage(),e);
- }
-
- return rsc;
- }
-
- private void enrichTokenInfo(RequestInfo requestInfo, IDSoggetto idSoggetto,
- InformazioniToken informazioniToken, SecurityToken securityTokenForContext,
- RemoteStoreConfig rsc, String clientId, String kid) throws KeystoreException, SecurityException, UtilsException, TransactionNotExistsException, CoreException, TransactionDeletedException {
- /**if(kid.startsWith(REMOTE_STORE_KEY_KID_STARTS_WITH_CLIENT_ID)) {*/
- Object oInfoPDND = null;
- if(this.context!=null) {
- oInfoPDND = this.context.getObject(org.openspcoop2.pdd.core.token.Costanti.PDD_CONTEXT_TOKEN_INFORMAZIONI_PDND_CLIENT_READ);
- }
- if(oInfoPDND instanceof String) {
- String s = (String) oInfoPDND;
- if("true".equals(s)) {
- // chiamata fatta dalla validazione semantica dopo che la raccolta delle informazioni sulla PDND è già stata chiamata in seguito alla validazione del token
- // poiche' il kid non e' presente, e' inutile ri-effettuare la medesima invocazione
- return;
- }
- }
- /**}*/
-
- enrichTokenInfo(securityTokenForContext, informazioniToken, requestInfo, rsc,
- kid, clientId);
-
- if(kid.startsWith(REMOTE_STORE_KEY_KID_STARTS_WITH_CLIENT_ID)) {
- this.context.put(org.openspcoop2.pdd.core.token.Costanti.PDD_CONTEXT_TOKEN_INFORMAZIONI_PDND_CLIENT_READ, "true");
- }
-
- updateCredenzialiTokenPDND(requestInfo, idSoggetto, informazioniToken);
- }
-
- private void updateCredenzialiTokenPDND(RequestInfo requestInfo, IDSoggetto idSoggetto, InformazioniToken informazioniToken) throws TransactionNotExistsException, CoreException, TransactionDeletedException {
- String idTransazione = null;
- if(this.context!=null) {
- idTransazione = (String) this.context.getObject(Costanti.ID_TRANSAZIONE);
- }
- Transaction transaction = TransactionContext.getTransaction(idTransazione);
-
- CredenzialiMittente credenzialiMittente = transaction.getCredenzialiMittente();
- if(credenzialiMittente==null) {
- credenzialiMittente = new CredenzialiMittente();
- transaction.setCredenzialiMittente(credenzialiMittente);
- }
-
- try {
- GestoreAutenticazione.updateCredenzialiTokenPDND(idSoggetto, "ModIValidator", idTransazione,
- informazioniToken, credenzialiMittente,
- null, "ModIValidator.credenzialiPDND", requestInfo,
- this.context);
- }catch(Exception e) {
- throw new CoreException(e.getMessage(),e);
- }
- }
-
-
- private RemoteStoreConfig getRemoteStoreConfig(IDSoggetto idSoggetto) throws ProtocolException {
- Object oTokenPolicy = null;
- if(this.context!=null) {
- oTokenPolicy = this.context.getObject(org.openspcoop2.pdd.core.token.Costanti.PDD_CONTEXT_TOKEN_POLICY);
- }
- String tokenPolicy = null;
- if(oTokenPolicy instanceof String) {
- tokenPolicy = (String) oTokenPolicy;
- }
- if(tokenPolicy==null) {
- return null;
- }
-
- return this.getRemoteStoreConfigByTokenPolicy(tokenPolicy, idSoggetto);
- }
-
- public static final String REMOTE_STORE_KEY_KID_STARTS_WITH_CLIENT_ID = "ClientId--";
- private String readKid(boolean sicurezzaMessaggio, boolean sicurezzaAudit, SecurityToken securityTokenForContext, String clientId) throws UtilsException {
- // NOTA: il kid DEVE essere preso dall'eventuale token di integrità, poichè il kid nell'access token è sempre uguale ed è quello della PDND
- String kid = null;
- if(sicurezzaMessaggio) {
- kid = readKidFromTokenIntegrity(securityTokenForContext);
- }
- if(kid==null && sicurezzaAudit) {
- kid = readKidFromTokenAudit(securityTokenForContext);
- }
- if(kid==null) {
- // Altrimenti utilizzo la struttura dati per ospitare le informazioni sul clientId
- kid = REMOTE_STORE_KEY_KID_STARTS_WITH_CLIENT_ID+clientId;
- }
- return kid;
- }
-
- private String readKidFromTokenIntegrity(SecurityToken securityTokenForContext) throws UtilsException {
- String kid = null;
- if(securityTokenForContext!=null && securityTokenForContext.getIntegrity()!=null) {
- kid = securityTokenForContext.getIntegrity().getKid();
- if(kid==null) {
- kid = securityTokenForContext.getIntegrity().getHeaderClaim("kid");
- }
- }
- return kid;
- }
- private String readKidFromTokenAudit(SecurityToken securityTokenForContext) throws UtilsException {
- String kid = null;
- if(securityTokenForContext!=null && securityTokenForContext.getAudit()!=null) {
- kid = securityTokenForContext.getAudit().getKid();
- if(kid==null) {
- kid = securityTokenForContext.getAudit().getHeaderClaim("kid");
- }
- }
- return kid;
- }
-
-
- private void enrichTokenInfo(SecurityToken securityTokenForContext, InformazioniToken informazioniTokenNormalizzate, RequestInfo requestInfo, RemoteStoreConfig rsc,
- String kid, String clientId) throws KeystoreException, SecurityException, UtilsException {
- RemoteKeyType keyType = RemoteKeyType.JWK; // ignored
- RemoteStoreProvider remoteStoreProvider = new RemoteStoreProvider(requestInfo, keyType);
- RemoteStoreClientInfo rsci = GestoreKeystoreCache.getRemoteStoreClientInfo(requestInfo, kid, clientId, rsc, remoteStoreProvider, this.context);
- if(rsci!=null &&
- (rsci.getClientDetails()!=null || rsci.getOrganizationId()!=null || rsci.getOrganizationDetails()!=null)
- ){
- if(informazioniTokenNormalizzate.getPdnd()==null) {
- informazioniTokenNormalizzate.setPdnd(new HashMap<>());
- }
- if(rsci.getClientDetails()!=null) {
- JSONUtils jsonUtils = JSONUtils.getInstance();
- if(jsonUtils.isJson(rsci.getClientDetails())) {
- JsonNode root = jsonUtils.getAsNode(rsci.getClientDetails());
- PDNDTokenInfoDetails info = new PDNDTokenInfoDetails();
- info.setId(rsci.getClientId());
- info.setDetails(rsci.getClientDetails());
- enrichTokenInfoAddInClaims(jsonUtils, securityTokenForContext, informazioniTokenNormalizzate, root, PDNDTokenInfo.CLIENT_INFO, info);
- }
- }
- if(rsci.getOrganizationDetails()!=null) {
- JSONUtils jsonUtils = JSONUtils.getInstance();
- if(jsonUtils.isJson(rsci.getOrganizationDetails())) {
- JsonNode root = jsonUtils.getAsNode(rsci.getOrganizationDetails());
- PDNDTokenInfoDetails info = new PDNDTokenInfoDetails();
- info.setId(rsci.getOrganizationId());
- info.setDetails(rsci.getOrganizationDetails());
- enrichTokenInfoAddInClaims(jsonUtils, securityTokenForContext, informazioniTokenNormalizzate, root, PDNDTokenInfo.ORGANIZATION_INFO, info);
- }
- }
- }
- }
- private void enrichTokenInfoAddInClaims(JSONUtils jsonUtils, SecurityToken securityTokenForContext, InformazioniToken informazioniTokenNormalizzate, JsonNode root, String type,
- PDNDTokenInfoDetails info) {
- Map<String, Serializable> readClaims = jsonUtils.convertToSimpleMap(root);
- if(!readClaims.isEmpty()) {
- enrichTokenInfoAddInClaims(securityTokenForContext, informazioniTokenNormalizzate,
- type, info,
- readClaims);
- }
- }
- private void enrichTokenInfoAddInClaims(SecurityToken securityTokenForContext, InformazioniToken informazioniTokenNormalizzate,
- String type, PDNDTokenInfoDetails info,
- Map<String, Serializable> readClaims) {
- informazioniTokenNormalizzate.getPdnd().put(type,TokenUtilities.toHashMapSerializable(readClaims));
- String prefix = PDNDTokenInfo.TOKEN_INFO_PREFIX_PDND+type+".";
- Map<String, Serializable> readClaimsSerializable = new HashMap<>();
- if(informazioniTokenNormalizzate.getClaims()!=null) {
- for (Map.Entry<String,Serializable> entry : readClaims.entrySet()) {
- String key = prefix+entry.getKey();
- if(!informazioniTokenNormalizzate.getClaims().containsKey(key)) {
- informazioniTokenNormalizzate.getClaims().put(key, entry.getValue());
- }
- if(entry.getValue() instanceof Serializable) {
- readClaimsSerializable.put(entry.getKey(), entry.getValue());
- }
- }
- }
-
- info.setClaims(readClaimsSerializable);
- if(securityTokenForContext!=null) {
- if(securityTokenForContext.getPdnd()==null) {
- securityTokenForContext.setPdnd(new PDNDTokenInfo());
- }
- securityTokenForContext.getPdnd().setInfo(type, info);
- }
- }
-
- }