[Feature] Aggiunto supporto OAuth2 client_credentials per Salesforce
Implementato il flusso OAuth2 grant_type=client_credentials come alternativa al flusso password gia' esistente per l'autenticazione Salesforce server-to-server. La modifica e' completamente retrocompatibile (default rimane Password). ## Dettaglio modifiche ### CredentialManager/Models/CredentialModels.cs - Aggiunto enum SalesforceGrantType con valori Password e ClientCredentials - Aggiunta proprieta' GrantType (default: Password) su RestApiCredential - Aggiunta proprieta' GrantType (default: Password) su SalesforceCredential ### DataConnection/REST/Configuration/RestServiceOptions.cs - Aggiunta proprieta' SalesforceGrantType per passare il tipo di flusso al client ### DataConnection/REST/Implementations/SalesforceServiceClient.cs - Iniettato ILogger<SalesforceServiceClient> con NullLogger come fallback - Sostituiti ~165 Console.WriteLine con chiamate ILogger appropriate (LogDebug per dettagli, LogInformation per eventi, LogWarning/LogError per problemi) - Aggiunto AuthenticateWithPasswordAsync: incapsula il flusso grant_type=password - Aggiunto AuthenticateWithClientCredentialsAsync: implementa grant_type=client_credentials (richiede solo ClientId e ClientSecret, nessun utente, URL My Domain obbligatorio) - Aggiunto SendTokenRequestAsync: helper condiviso per la POST al token endpoint - Aggiornato AuthenticateAsync() override: instrada al flusso corretto in base a GrantType - Rimosso modificatore static da NormalizeNumericValues (usava _logger, causava CS0120) ### Data_Coupler/Services/DataConnectionFactory.cs - Mappatura del campo GrantType dalle opzioni Salesforce a RestServiceOptions - Passaggio dell'ILogger al costruttore di SalesforceServiceClient ### CredentialManager/Services/CredentialService.cs - SaveRestApiCredentialAsync (blocco Salesforce): serializza GrantType in AdditionalParameters - SaveSalesforceCredentialAsync: aggiunto GrantType nel dizionario iniziale - MapToRestApiCredential: deserializza GrantType da AdditionalParameters con Enum.TryParse - MapToSalesforceCredential: idem per il tipo SalesforceCredential ### DataConnection/CredentialManagement/Services/DataConnectionCredentialService.cs - TestSalesforceOAuthLogin aggiornato: per ClientCredentials invia solo client_id e client_secret (senza username/password/security_token); per Password comportamento invariato ### Data_Coupler/Pages/CredentialManagement.razor - Aggiunto dropdown 'Tipo di Autenticazione OAuth2' nella sezione Salesforce - I campi Username, Password e Security Token vengono nascosti quando si seleziona il flusso ClientCredentials - Alert contestuale: warning My Domain URL per ClientCredentials, info per Password - GrantType propagato correttamente in EditRestApiCredential e TestRestApiConnectionFromModal ### AGENTS.md - Aggiunta sezione di documentazione per la nuova funzionalita' OAuth2 client_credentials
This commit is contained in:
@@ -863,23 +863,39 @@ public class DataConnectionCredentialService : IDataConnectionCredentialService
|
||||
try
|
||||
{
|
||||
var tokenUrl = credential.LoginUrl.TrimEnd('/') + "/services/oauth2/token";
|
||||
List<KeyValuePair<string, string>> tokenData;
|
||||
|
||||
var tokenData = new List<KeyValuePair<string, string>>
|
||||
if (credential.GrantType == CredentialManager.Models.SalesforceGrantType.ClientCredentials)
|
||||
{
|
||||
new("grant_type", "password"),
|
||||
new("username", credential.Username),
|
||||
new("password", credential.Password + credential.SecurityToken),
|
||||
new("client_id", credential.ClientId ?? ""),
|
||||
new("client_secret", credential.ClientSecret ?? "")
|
||||
};
|
||||
// Client Credentials flow — server-to-server, no user
|
||||
tokenData = new List<KeyValuePair<string, string>>
|
||||
{
|
||||
new("grant_type", "client_credentials"),
|
||||
new("client_id", credential.ClientId ?? ""),
|
||||
new("client_secret", credential.ClientSecret ?? "")
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
// Password flow (default)
|
||||
tokenData = new List<KeyValuePair<string, string>>
|
||||
{
|
||||
new("grant_type", "password"),
|
||||
new("username", credential.Username),
|
||||
new("password", credential.Password + credential.SecurityToken),
|
||||
new("client_id", credential.ClientId ?? ""),
|
||||
new("client_secret", credential.ClientSecret ?? "")
|
||||
};
|
||||
}
|
||||
|
||||
var tokenContent = new FormUrlEncodedContent(tokenData);
|
||||
var response = await httpClient.PostAsync(tokenUrl, tokenContent);
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
return (true, $"Connessione Salesforce riuscita!\n\nDettagli:\n- Login URL: {credential.LoginUrl}\n- API Version: {credential.ApiVersion}\n- Sandbox: {credential.IsSandbox}\n- Tipo Auth: OAuth2\n- Timeout: {credential.TimeoutSeconds}s");
|
||||
var flowLabel = credential.GrantType == CredentialManager.Models.SalesforceGrantType.ClientCredentials
|
||||
? "client_credentials" : "password";
|
||||
return (true, $"Connessione Salesforce riuscita!\n\nDettagli:\n- Login URL: {credential.LoginUrl}\n- API Version: {credential.ApiVersion}\n- Sandbox: {credential.IsSandbox}\n- Tipo Auth: OAuth2 ({flowLabel})\n- Timeout: {credential.TimeoutSeconds}s");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user