I’m using Azure Communication Services for SMS and emails. It works just fine if I use it with an endpoint and an access key or with the connection string itself. However, that’s not a good practice and I would like to authenticate against Azure IAM.
Speaking of it, what role should I assign in the following context?
- In the Azure portal, navigate to the Azure Communication Services resource that you want to use for sending SMS messages.
- Click on the "Access control (IAM)" tab in the left-hand menu.
- Click on the "Add role assignment" button
- Do what?
Here is a link to the documentation https://learn.microsoft.com/en-us/azure/communication-services/concepts/authentication#azure-ad-authentication
I switched to the following overload:
var options = new DefaultAzureCredentialOptions
{
ExcludeInteractiveBrowserCredential = false,
ExcludeManagedIdentityCredential = true,
ExcludeSharedTokenCacheCredential = false,
InteractiveBrowserTenantId = tenantId,
InteractiveBrowserCredentialClientId = clientId,
ManagedIdentityClientId = clientId,
SharedTokenCacheTenantId = tenantId,
TenantId = tenantId,
VisualStudioTenantId = tenantId,
VisualStudioCodeTenantId = tenantId
};
var tokenCredentials = new DefaultAzureCredential(options);
var emailClient = new EmailClient(new Uri(uri), tokenCredentials);
This is the error message that I get after I try to send SMS or an email.
and when I try to do: az login --scope https://communication.azure.com//.default
, it fails with the following message:
Please note that this is happening only for Azure Communication Services. There are other services such as Key Vault, AppConfiguration, etc. that work just fine with IAM.
Code that works but uses Access Key instead of IAM
public sealed class AzureEmailNotificationService
{
private readonly EmailConfiguration _emailConfiguration;
private readonly EmailClient _emailClient;
public AzureEmailNotificationService(IOptions<EmailConfiguration> options)
{
ArgumentNullException.ThrowIfNull(options.Value);
_emailConfiguration = options.Value;
_emailClient = new EmailClient(new Uri(_emailConfiguration.Endpoint), new AzureKeyCredential(_emailConfiguration.AccessKey));
}
public async Task SendAsync(string subject, string message, string recipient, CancellationToken cancellationToken = default)
{
var emailContent = new EmailContent(subject) { PlainText = message };
var emailAddresses = new List<EmailAddress> { new(recipient) };
var emailRecipients = new EmailRecipients(emailAddresses);
await _emailClient.SendAsync(new EmailMessage(_emailConfiguration.From, emailContent, emailRecipients), cancellationToken);
}
}
public sealed class AzureSmsNotificationService
{
private readonly SmsConfiguration _smsConfiguration;
private readonly SmsClient _smsClient;
public AzureSmsNotificationService(IOptions<SmsConfiguration> options)
{
ArgumentNullException.ThrowIfNull(options.Value);
_smsConfiguration = options.Value;
_smsClient = new SmsClient(new Uri(_smsConfiguration.Endpoint), new AzureKeyCredential(_smsConfiguration.AccessKey));
}
public async Task SendAsync(string message, string recipient, CancellationToken cancellationToken = default)
{
await _smsClient.SendAsync(_smsConfiguration.From, recipient, message, cancellationToken: cancellationToken);
}
}
2
Answers
I tried to reproduce the same in my environment and got below results:
When I ran below CLI command same as you, I got same error like this:
Response:
It opened browser where I got same error again after signing in like this:
To resolve the error, try running only
az login
command at first to sign in to your Azure account like this:As for the role assignment, check how you created the service principal.
If you run below CLI command, it will create service principal by assigning it
Contributor
role under subscription with response like this:Response:
Now set environment variables with above values in response as mentioned in this MS Doc
If you want to assign role under your Communication Services from Portal, follow below steps:
Go to Azure Portal -> Your Communication Service -> Access control (IAM) -> Add role assignment
Assign Contributor role to the service principal like this:
Reference:
Azure Active Directory in Communication Services | Microsoft
This is a known problem that is now being discussed internally. We are aiming to add preauthorization for well-known apps such as Az CLI, AzurePowerShell, VS, VSCode.
Assign a security principal (user, group, service principal, or managed identity) that has been assigned a role with the
Microsoft.Communication/CommunicationServices/Write
permission (e.g. Contributor role or a custom role):