ApiKeyUtilities.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.core.autenticazione;
- import java.util.List;
- import org.openspcoop2.core.config.ServizioApplicativo;
- import org.openspcoop2.core.config.driver.db.DriverConfigurazioneDB;
- import org.openspcoop2.core.id.IDServizioApplicativo;
- import org.openspcoop2.core.id.IDSoggetto;
- import org.openspcoop2.core.registry.Soggetto;
- import org.openspcoop2.core.registry.driver.db.DriverRegistroServiziDB;
- import org.openspcoop2.pdd.core.PdDContext;
- import org.openspcoop2.pdd.core.connettori.InfoConnettoreIngresso;
- import org.openspcoop2.utils.crypt.PasswordGenerator;
- import org.openspcoop2.utils.io.Base64Utilities;
- /**
- * ApiKeyUtilities
- *
- * @author Andrea Poli (apoli@link.it)
- * @author $Author$
- * @version $Rev$, $Date$
- */
- public class ApiKeyUtilities {
- public static String getKey(boolean apiKey,
- boolean header, boolean cookie, boolean queryParameter,
- String nomeHeader, String nomeCookie, String nomeQueryParameter,
- InfoConnettoreIngresso infoConnettore, PdDContext pddContext, boolean throwException,
- StringBuilder fullCredential) throws AutenticazioneException {
-
- String tipo = apiKey ? "ApiKey" : "AppId";
-
- String key = null;
-
- // viene usato l'ordine della specifica
-
- if(queryParameter) {
- if(nomeQueryParameter==null && throwException) {
- throw new AutenticazioneException("Nome del parametro della query, da cui estrarre l'"+tipo+", non indicato");
- }
- if(nomeQueryParameter!=null && infoConnettore!=null && infoConnettore.getUrlProtocolContext()!=null) {
- key = infoConnettore.getUrlProtocolContext().getParameterFirstValue(nomeQueryParameter);
- if(key!=null && "".equals(key.trim())) {
- key = null;
- }
- }
- }
- if(key!=null) {
- if(fullCredential.length()>0) {
- fullCredential.append("\n");
- }
- fullCredential.append(tipo).append(" (query) '").append(nomeQueryParameter);
- if(!apiKey) { // l'api key non deve essere tracciata come per la password.
- fullCredential.append(": ").append(key);
- }
- fullCredential.append("'");
- return key;
- }
-
- if(header) {
- if(nomeHeader==null && throwException) {
- throw new AutenticazioneException("Nome dell'header, da cui estrarre l'"+tipo+", non indicato");
- }
- if(nomeHeader!=null && infoConnettore!=null && infoConnettore.getUrlProtocolContext()!=null) {
- key = infoConnettore.getUrlProtocolContext().getHeaderFirstValue(nomeHeader);
- if(key!=null && "".equals(key.trim())) {
- key = null;
- }
- }
- }
- if(key!=null) {
- if(fullCredential.length()>0) {
- fullCredential.append("\n");
- }
- fullCredential.append(tipo).append(" (http) '").append(nomeHeader);
- if(!apiKey) { // l'api key non deve essere tracciata come per la password.
- fullCredential.append(": ").append(key);
- }
- fullCredential.append("'");
- return key;
- }
-
- if(cookie) {
- if(nomeCookie==null && throwException) {
- throw new AutenticazioneException("Nome del cookie, da cui estrarre l'"+tipo+", non indicato");
- }
- if(nomeCookie!=null && infoConnettore!=null && infoConnettore.getUrlProtocolContext()!=null) {
- key = infoConnettore.getUrlProtocolContext().getCookieValue(nomeCookie);
- if(key!=null && "".equals(key.trim())) {
- key = null;
- }
- }
- }
- if(key!=null) {
- if(fullCredential.length()>0) {
- fullCredential.append("\n");
- }
- fullCredential.append(tipo).append(" (cookie) '").append(nomeCookie);
- if(!apiKey) { // l'api key non deve essere tracciata come per la password.
- fullCredential.append(": ").append(key);
- }
- fullCredential.append("'");
- return key;
- }
-
- if(throwException) {
- throw new AutenticazioneException(tipo+" non presente nella richiesta");
- }
-
- return null;
- }
-
- private static final String SOGGETTO_SEPARATOR = ".";
- public static final String APPLICATIVO_SOGGETTO_SEPARATOR = "@";
- private static final int MAX_ALREADY_EXISTS = 5000;
- private static final String SEPARATOR_ALREADY_EXISTS = ".";
-
- public static String toAppId(String protocollo, IDSoggetto idSoggetto, boolean multipleApiKeys, DriverRegistroServiziDB driver) throws Exception {
- String appId = _toAppId(protocollo, idSoggetto);
- if(!_existsAppId(appId, multipleApiKeys, idSoggetto, driver)) {
- return appId;
- }
- for (int i = 2; i < MAX_ALREADY_EXISTS; i++) {
- IDSoggetto idSoggettoAlreadyExists = new IDSoggetto(idSoggetto.getTipo(), idSoggetto.getNome()+SEPARATOR_ALREADY_EXISTS+i);
- String appIdAlreadyExists = _toAppId(protocollo, idSoggettoAlreadyExists);
- if(!_existsAppId(appIdAlreadyExists, multipleApiKeys, idSoggetto, driver)) {
- return appIdAlreadyExists;
- }
- }
- throw new Exception("Generazione appId univoco non riuscita dopo "+MAX_ALREADY_EXISTS+" tentativi");
- }
- private static String _toAppId(String protocollo, IDSoggetto idSoggetto) throws Exception {
- // non va bene perchè due nomi uguali di due protocolli differenti, vengono identici.
- //return org.openspcoop2.protocol.engine.utils.NamingUtils.getLabelSoggetto(protocollo, idSoggetto.getTipo(), idSoggetto.getNome());
- if(idSoggetto==null || idSoggetto.getTipo()==null || idSoggetto.getNome()==null) {
- throw new Exception("Identificativo soggetto non definito");
- }
- return idSoggetto.getNome()+SOGGETTO_SEPARATOR+idSoggetto.getTipo();
- }
- private static boolean _existsAppId(String appId, boolean multipleApiKeys, IDSoggetto idSoggetto, DriverRegistroServiziDB driver) throws Exception {
- Soggetto soggetto = driver.soggettoWithCredenzialiApiKey(appId, multipleApiKeys);
- if(soggetto==null) {
- return false;
- }
- boolean isSame = false;
- if(soggetto.getTipo().equals(idSoggetto.getTipo()) &&
- soggetto.getNome().equals(idSoggetto.getNome()) ) {
- isSame = true;
- }
- return !isSame;
- }
-
- public static String toAppId(String protocollo, IDServizioApplicativo idSA, boolean multipleApiKeys, DriverConfigurazioneDB driver) throws Exception {
- String appId = _toAppId(protocollo, idSA.getNome(), idSA.getIdSoggettoProprietario());
- if(!_existsAppId(appId, multipleApiKeys, idSA, driver)) {
- return appId;
- }
- for (int i = 2; i < MAX_ALREADY_EXISTS; i++) {
- String appIdAlreadyExists = _toAppId(protocollo, idSA.getNome()+SEPARATOR_ALREADY_EXISTS+i, idSA.getIdSoggettoProprietario());
- if(!_existsAppId(appIdAlreadyExists, multipleApiKeys, idSA, driver)) {
- return appIdAlreadyExists;
- }
- }
- throw new Exception("Generazione appId univoco non riuscita dopo "+MAX_ALREADY_EXISTS+" tentativi");
- }
- private static String _toAppId(String protocollo, String nomeSA, IDSoggetto idSoggetto) throws Exception {
- return nomeSA+APPLICATIVO_SOGGETTO_SEPARATOR+ _toAppId(protocollo, idSoggetto);
- }
- private static boolean _existsAppId(String appId, boolean multipleApiKeys, IDServizioApplicativo idSA, DriverConfigurazioneDB driver) throws Exception {
- List<ServizioApplicativo> saList = driver.servizioApplicativoWithCredenzialiApiKeyList(appId, multipleApiKeys);
- if (saList==null || saList.isEmpty()) {
- return false;
- }
- boolean isSame = false;
- for (ServizioApplicativo servizioApplicativo : saList) {
- if(!servizioApplicativo.getNome().equals(idSA.getNome())) {
- continue;
- }
- if(!servizioApplicativo.getTipoSoggettoProprietario().equals(idSA.getIdSoggettoProprietario().getTipo())) {
- continue;
- }
- if(!servizioApplicativo.getNomeSoggettoProprietario().equals(idSA.getIdSoggettoProprietario().getNome())) {
- continue;
- }
- isSame = true;
- break;
- }
- return !isSame;
- }
-
- private static final String PREFIX_SEPARATOR_API_KEY = ".";
- private static final String PREFIX_SEPARATOR_API_KEY_REGEXP = "\\.";
-
- private static String getPrefixForApiKey(String protocollo, IDSoggetto idSoggetto, DriverRegistroServiziDB driver) throws Exception {
- boolean multipleApiKeys = false;
- String appId = toAppId(protocollo, idSoggetto, multipleApiKeys, driver);
- return Base64Utilities.encodeAsString(appId.getBytes())+PREFIX_SEPARATOR_API_KEY;
- }
- public static ApiKey newApiKey(String protocollo, IDSoggetto idSoggetto, int length, DriverRegistroServiziDB driver) throws Exception {
- ApiKey apiKey = new ApiKey();
- String password = getPassword(length);
- String apiKeyToken = getPrefixForApiKey(protocollo, idSoggetto, driver)+Base64Utilities.encodeAsString(password.getBytes());
- apiKey.setApiKey(apiKeyToken);
- apiKey.setPassword(password);
- return apiKey;
- }
-
- private static String getPrefixForApiKey(String protocollo, IDServizioApplicativo idSA, DriverConfigurazioneDB driver) throws Exception {
- boolean multipleApiKeys = false;
- String appId = toAppId(protocollo, idSA, multipleApiKeys, driver);
- return Base64Utilities.encodeAsString(appId.getBytes())+PREFIX_SEPARATOR_API_KEY;
- }
- public static ApiKey newApiKey(String protocollo, IDServizioApplicativo idSA, int length, DriverConfigurazioneDB driver) throws Exception {
- ApiKey apiKey = new ApiKey();
- String password = getPassword(length);
- String apiKeyToken = getPrefixForApiKey(protocollo, idSA, driver)+Base64Utilities.encodeAsString(password.getBytes());
- apiKey.setApiKey(apiKeyToken);
- apiKey.setPassword(password);
- return apiKey;
- }
-
- public static String encodeApiKey(String appId, String password) throws Exception {
- return Base64Utilities.encodeAsString(appId.getBytes())+
- PREFIX_SEPARATOR_API_KEY+
- Base64Utilities.encodeAsString(password.getBytes());
- }
-
- public static String[] decodeApiKey(String apiKeyBase64) throws Exception {
- if(!apiKeyBase64.contains(PREFIX_SEPARATOR_API_KEY)) {
- throw new Exception("Formato non corretto");
- }
- String [] tmp = apiKeyBase64.split(PREFIX_SEPARATOR_API_KEY_REGEXP);
- if(tmp==null || tmp.length!=2){
- throw new Exception("Formato non corretto (.)");
- }
- try {
- tmp[0] = new String(Base64Utilities.decode(tmp[0]));
- }catch(Exception e) {
- throw new Exception("Formato non corretto (appId)",e);
- }
- try {
- tmp[1] = new String(Base64Utilities.decode(tmp[1]));
- }catch(Exception e) {
- throw new Exception("Formato non corretto (appKey)",e);
- }
- return tmp;
- }
-
-
- public static ApiKey newMultipleApiKey(int length) throws Exception {
- ApiKey apiKey = new ApiKey();
- String password = getPassword(length);
- String apiKeyToken = encodeMultipleApiKey(password);
- apiKey.setApiKey(apiKeyToken);
- apiKey.setPassword(password);
- return apiKey;
- }
-
- public static String decodeMultipleApiKey(String apiKeyBase64) throws Exception {
- return new String(Base64Utilities.decode(apiKeyBase64));
- }
- public static String encodeMultipleApiKey(String password) throws Exception {
- return Base64Utilities.encodeAsString(password.getBytes());
- }
-
- private static String getPassword(int length) throws Exception {
- PasswordGenerator pwdGenerator = PasswordGenerator.DEFAULT;
- return pwdGenerator.generate(length);
- }
- }