c22b4a2613
NUOVE FUNZIONALITÀ: - Aggiunto modulo CredentialManager per gestione centralizzata credenziali - Implementata UI Blazor per gestione credenziali (CredentialManagement.razor) - Supporto completo per credenziali database (SQL Server, MySQL, PostgreSQL, Oracle, SQLite, DB2, SAP HANA) - Gestione unificata REST API con supporto specifico per SAP B1 Service Layer e Salesforce - Test reali di connessione per database, SAP B1 e Salesforce OAuth2 - Selezione dinamica tipo servizio REST (Generico, SAP B1, Salesforce) con campi specifici - Persistenza sicura di credenziali con crittografia password e campi sensibili COMPONENTI AGGIUNTI: - CredentialManager/Models/: CredentialEntity, CredentialModels (DatabaseCredential, RestApiCredential, SapB1ServiceLayerCredential, SalesforceCredential) - CredentialManager/Services/: CredentialService, EncryptionService, DatabaseInitializer - CredentialManager/Data/: CredentialDbContext con Entity Framework - DataConnection/CredentialManagement/: Interfacce e servizi di integrazione - Data_Coupler/Pages/CredentialManagement.razor: UI completa per gestione credenziali MIGLIORAMENTI UI: - Form dinamica per REST API con campi specifici per tipo servizio - Validazione campi obbligatori per Salesforce (ClientId, ClientSecret, SecurityToken) - Test connessione in tempo reale dalla modale di inserimento/modifica - Rimozione sezioni separate per SAP B1 e Salesforce (ora unificate in REST API) - Gestione stato loading durante operazioni async PERSISTENZA AVANZATA: - Campo RestServiceType aggiunto a CredentialEntity con migrazione automatica - Serializzazione campi specifici Salesforce/SAP B1 in AdditionalParameters JSON - Mapping bidirezionale tra entità database e modelli business - Gestione nullability e conversioni tipo sicure SICUREZZA: - Crittografia AES-256 per password e token sensibili - Gestione sicura ConnectionString database - Validazione input e sanitizzazione dati TESTING E CONNETTIVITÀ: - Test autenticazione reale SAP B1 Service Layer - Test OAuth2 Salesforce con supporto Connected App - Test connettività database multi-provider - Logging dettagliato per debugging e monitoraggio CONFIGURAZIONE: - Dependency injection per tutti i servizi - Configurazione Entity Framework con SQLite - Tasks VS Code per build e run - Gestione connection string centralizzata CORREZIONI: - Risolti errori nullability in CredentialService - Aggiunto using Microsoft.JSInterop per IJSRuntime - Fix compilazione e warning Files modificati: 35+ file tra nuovi e aggiornati
140 lines
4.4 KiB
C#
140 lines
4.4 KiB
C#
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace CredentialManager.Services;
|
|
|
|
/// <summary>
|
|
/// Interfaccia per il servizio di crittografia
|
|
/// </summary>
|
|
public interface IEncryptionService
|
|
{
|
|
string Encrypt(string plainText);
|
|
string Decrypt(string encryptedText);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Servizio per la crittografia delle password cross-platform
|
|
/// </summary>
|
|
public class EncryptionService : IEncryptionService
|
|
{
|
|
private readonly byte[] _key;
|
|
private readonly byte[] _iv;
|
|
|
|
public EncryptionService()
|
|
{
|
|
// Chiave e IV derivati da una stringa fissa (in produzione dovrebbero essere configurabili)
|
|
var keySource = "CredentialManager2025KeyForEncryption!";
|
|
var ivSource = "CredMgr2025IV!";
|
|
|
|
using var sha256 = SHA256.Create();
|
|
_key = sha256.ComputeHash(Encoding.UTF8.GetBytes(keySource));
|
|
_iv = new byte[16];
|
|
Array.Copy(Encoding.UTF8.GetBytes(ivSource), _iv, Math.Min(16, ivSource.Length));
|
|
}
|
|
|
|
public string Encrypt(string plainText)
|
|
{
|
|
if (string.IsNullOrEmpty(plainText))
|
|
return string.Empty;
|
|
|
|
try
|
|
{
|
|
// Su Windows, usa ProtectedData se disponibile
|
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
|
{
|
|
return EncryptWithProtectedData(plainText);
|
|
}
|
|
|
|
// Su altre piattaforme, usa AES
|
|
return EncryptWithAes(plainText);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new InvalidOperationException("Errore durante la crittografia", ex);
|
|
}
|
|
}
|
|
|
|
public string Decrypt(string encryptedText)
|
|
{
|
|
if (string.IsNullOrEmpty(encryptedText))
|
|
return string.Empty;
|
|
|
|
try
|
|
{
|
|
// Su Windows, usa ProtectedData se disponibile
|
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
|
{
|
|
return DecryptWithProtectedData(encryptedText);
|
|
}
|
|
|
|
// Su altre piattaforme, usa AES
|
|
return DecryptWithAes(encryptedText);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new InvalidOperationException("Errore durante la decrittografia", ex);
|
|
}
|
|
} private string EncryptWithProtectedData(string plainText)
|
|
{
|
|
byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
|
|
byte[] entropy = Encoding.UTF8.GetBytes("CredentialManager2025");
|
|
|
|
if (OperatingSystem.IsWindows())
|
|
{
|
|
byte[] encryptedBytes = ProtectedData.Protect(plainTextBytes, entropy, DataProtectionScope.CurrentUser);
|
|
return Convert.ToBase64String(encryptedBytes);
|
|
}
|
|
|
|
// Fallback ad AES se non su Windows
|
|
return EncryptWithAes(plainText);
|
|
}
|
|
|
|
private string DecryptWithProtectedData(string encryptedText)
|
|
{
|
|
if (OperatingSystem.IsWindows())
|
|
{
|
|
byte[] encryptedBytes = Convert.FromBase64String(encryptedText);
|
|
byte[] entropy = Encoding.UTF8.GetBytes("CredentialManager2025");
|
|
byte[] decryptedBytes = ProtectedData.Unprotect(encryptedBytes, entropy, DataProtectionScope.CurrentUser);
|
|
return Encoding.UTF8.GetString(decryptedBytes);
|
|
}
|
|
|
|
// Fallback ad AES se non su Windows
|
|
return DecryptWithAes(encryptedText);
|
|
}
|
|
|
|
private string EncryptWithAes(string plainText)
|
|
{
|
|
using var aes = Aes.Create();
|
|
aes.Key = _key;
|
|
aes.IV = _iv;
|
|
|
|
using var encryptor = aes.CreateEncryptor();
|
|
using var msEncrypt = new MemoryStream();
|
|
using var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write);
|
|
using var swEncrypt = new StreamWriter(csEncrypt);
|
|
|
|
swEncrypt.Write(plainText);
|
|
swEncrypt.Close();
|
|
|
|
return Convert.ToBase64String(msEncrypt.ToArray());
|
|
}
|
|
|
|
private string DecryptWithAes(string encryptedText)
|
|
{
|
|
byte[] cipherBytes = Convert.FromBase64String(encryptedText);
|
|
|
|
using var aes = Aes.Create();
|
|
aes.Key = _key;
|
|
aes.IV = _iv;
|
|
|
|
using var decryptor = aes.CreateDecryptor();
|
|
using var msDecrypt = new MemoryStream(cipherBytes);
|
|
using var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read);
|
|
using var srDecrypt = new StreamReader(csDecrypt);
|
|
|
|
return srDecrypt.ReadToEnd();
|
|
}
|
|
}
|