Проблемы с отправкой электронной почты в средах qa и prod. Тестирование и разработка работают.
Ошибка:
Код: generalException Сообщение: при отправке запроса произошла ошибка. В этом процессе аутентификации используется неправильное приложение (publi c или конфиденциальное). Потенциальная проблема: URI перенаправления действителен, но он был настроен для неправильного типа приложения. Проверьте конфигурацию приложения, используемого на портале регистрации приложений. Подробнее см. https://aka.ms/msal-net-invalid-client. Исходное исключение: AADSTS7000215: указан неверный секретный ключ клиента. Идентификатор трассировки: dd40b2e6-4ede-4f94-9d08-14533d138d00 Идентификатор корреляции: 3ca08d24-5634-4c99-93ba-4df9a45292bd Метка времени: 2020-03-02 06: 49: 12Z
Получите следующий HTTP-статус по запросу sendt. 200 https://.vault.azure.net: 443 / secrets / MailClientSecret /? Api-version = 7.0 200 https://login.microsoftonline.com: 443 / common / discovery / instance? Api-version = 1.1 & authorization_endpoint = https% 3A% 2F% 2Flogin.microsoftonline. com% 2F % 2Fauth2% 2Fv2.0% 2 Разрешить
200 https://login.microsoftonline.com: 443 / / v2.0 / .well-known / openid-configuration
401 (не утвержден) https://login.microsoftonline.com: 443 / / oauth2 / v2.0 / токен
public async Task SendMail(string[] tooAdress, string subject, string body, FileAttachment[] fileAttachments)
{
if (tooAdress.Length > 0)
{
string overRideEmail = Configuration.GetValue<string>("Email:OverrideRecipientNotProductionEmail");
if (Environment.EnvironmentName != Environments.Production || overRideEmail.Length > 0)
{
var email = new List<string>();
email.Add(overRideEmail);
tooAdress = email.ToArray();
subject = Environment.EnvironmentName + " - " + subject;
}
// The app registration should be configured to require access to permissions
// sufficient for the Microsoft Graph API calls the app will be making, and
// those permissions should be granted by a tenant administrator.
var scopes = new string[] { "https://graph.microsoft.com/.default" };
// Configure the MSAL client as a confidential client
var clientId = Configuration.GetValue<string>("AzureAD:ClientId");
var tennantId = Configuration.GetValue<string>("AzureAD:TenantId");
var senderObjectId = Configuration.GetValue<string>("Email:MailBoxSenderObjectId");
var clientSecret = LoadClientSecretFromKeyVault(Configuration).Result;
string secret = Uri.EscapeUriString(clientSecret.Value);
var confidentialClient = ConfidentialClientApplicationBuilder
.Create(clientId)
.WithAuthority($"https://login.microsoftonline.com/"+ tennantId + "/v2.0")
.WithClientSecret(secret)
.Build();
// Build the Microsoft Graph client. As the authentication provider, set an async lambda
// which uses the MSAL client to obtain an app-only access token to Microsoft Graph,
// and inserts this access token in the Authorization header of each API request.
GraphServiceClient graphServiceClient =
new GraphServiceClient(new DelegateAuthenticationProvider(async (requestMessage) => {
// Retrieve an access token for Microsoft Graph (gets a fresh token if needed).
var authResult = await confidentialClient
.AcquireTokenForClient(scopes)
.ExecuteAsync();
// Add the access token in the Authorization header of the API request.
requestMessage.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
})
);
//Make attachment
MessageAttachmentsCollectionPage attachments = new MessageAttachmentsCollectionPage();
foreach (FileAttachment fileStream in fileAttachments) {
attachments.Add(fileStream);
}
//Make recipients
List<Recipient> toRecipients = new List<Recipient>();
foreach (string emailAdress in tooAdress) {
toRecipients.Add(new Recipient
{
EmailAddress = new EmailAddress
{
Address = emailAdress.Trim()
}
});
}
// Make a Microsoft Graph API query
var message = new Message
{
Subject = subject,
Body = new ItemBody
{
ContentType = BodyType.Text,
Content = body
},
ToRecipients = toRecipients,
Attachments = attachments
};
var saveToSentItems = true;
await graphServiceClient.Users[senderObjectId]
.SendMail(message, saveToSentItems)
.Request()
.PostAsync();
}
}
/// <summary>
/// Loads the client secret from a KeyVault in Azure.
/// </summary>
/// <example>
/// var conStr = LoadConnectionStringFromKeyVault(getConfig(), getServices()).Result.Value;
/// </example>
/// <param name="config">Environment config</param>
/// <returns>The connection string</returns>
private async Task<SecretBundle> LoadClientSecretFromKeyVault(IConfiguration config)
{
AzureServiceTokenProvider tokenProvider = new AzureServiceTokenProvider();
KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(tokenProvider.KeyVaultTokenCallback));
var vaultUrl = $"https://{config.GetValue<string>("KeyVault:VaultName")}.vault.azure.net/secrets/{config.GetValue<string>("KeyVault:MailClientSecretKeyName")}";
return await keyVaultClient.GetSecretAsync(vaultUrl).ConfigureAwait(false);
}
}