Can someone tell me if SendGrid can be used in a Azure worker role project which does not use .net core? It would also be good to know what is better for using sendgrid for notifications. Worker role or web job or Azure functions?
While trying to use it in a project which is not .NET Core, I get the following error while creating the sendgrid client:
"'System.IO.FileNotFoundException' in SendGrid.dll"
Thanks
-Ravi
Can someone tell me if SendGrid can be used in a Azure worker role project which does not use .net core?
It should work in the Azure worker role. I also do a test , it works correctly on my side. The following is the demo code.
private async Task RunAsync(CancellationToken cancellationToken)
{
var apiKey = "sendgrid APIkey";
var client = new SendGridClient(apiKey);
// TODO: Replace the following with your own logic.
while (!cancellationToken.IsCancellationRequested)
{
Trace.TraceInformation("Working");
var msg = new SendGridMessage
{
From = new EmailAddress("send email", "Sunguiguan"),
Subject = "Hello World from the SendGrid CSharp SDK!",
PlainTextContent = "Hello, Email!",
HtmlContent = "<strong>Hello, Email!</strong>"
};
msg.AddTo(new EmailAddress("another email", "test user"));
client.SendEmailAsync(msg, cancellationToken).Wait(cancellationToken);
await Task.Delay(1000*60, cancellationToken);
}
}
It would also be good to know what is better for using sendgrid for notifications. Worker role or web job or Azure functions?
All of those services could use sendgrid for notification .It depends on what you wanted. We could reference Azure Webjobs vs Azure Functions : How to choose and Azure App Service, Virtual Machines, Service Fabric, and Cloud Services comparison to get more info.
Related
I created a service bus for a learning purpose, and I want to pass messages to it. I went through the official Microsoft documentation which teaches to use the DefaultAzureCredential so that the stored credentials in Visual Studio are gonna get used.
The problem is, I have logged in to Visual studio from my work email, which I use daily. And the new service bus is in a different subscription, and it's attached to my personal email.
So, is there a way to get the service bus to work, without logging in with my personal email, and CLI configurations? Any alternatives for this DefaultAzureCredential object?
Sample code (From Microsoft documentation)
ServiceBusClient client;
const int numOfMessages = 3;
var clientOptions = new ServiceBusClientOptions
{
TransportType = ServiceBusTransportType.AmqpWebSockets
};
client = new ServiceBusClient("asb-test.servicebus.windows.net",
new DefaultAzureCredential(),
clientOptions);
sender = client.CreateSender("email");
using ServiceBusMessageBatch messageBatch = await
sender.CreateMessageBatchAsync();
var result = messageBatch.TryAddMessage(new ServiceBusMessage($"Message"));
if (!result)
{
throw new Exception($"The message is too large to fit in the batch.");
}
try
{
await sender.SendMessagesAsync(messageBatch);
Console.WriteLine($"A batch of {numOfMessages} messages has been published to the queue.");
}
finally
{
await sender.DisposeAsync();
await client.DisposeAsync();
}
If the subscriptions are in the same tenant, this is not a problem, you can still easily assign permissions. But I guess what you mean to say is that the subs are in two different tenants.
You could try to add your work account as a guest user in your personal tenant, then you should also be able to assign it permissions.
I understand that Azure Functions are potentially open endpoints on the internet if I read Microsoft’s documentation correctly and per conversations with a friend who has some experience working with web development paradigms that Azure Functions leverages. A cursory reading of security forums and stack overflow questions on the topic leads me to understand at least a couple options of securing them namely
Azure Active Directory
Shared Access Signatures (SAS) and
Azure Virtual Networks.
Context/ What does my Azure Function do? It manages a blob container related to an ETL of vendor data from a SFTP source to a SQL Endpoint which this ETL utilizes an intermediary blob container for file transfer and long term cold storage of source data. The Azure Function moves the blobs from one container to an archive container after they have been loaded to the SQL endpoint. Why Azure Function to manage the blob containers?
SSIS lacks ability to perform blob manipulation (i.e copy and delete)
Logic App lacks ability to perform a join (of files loaded to SQL endpoint and file names in blob container)
An example of one of the functions is shown here below:
using System.IO;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Net.Http;
using System.Net;
using Microsoft.WindowsAzure.Storage.Blob;
using System.Collections.Generic;
using System.Text;
namespace AFA_ArchiveBlob
{
public static class HttpTrigger_BlobInput
{
[FunctionName("HttpTrigger_BlobInput")]
public static async Task<HttpResponseMessage> Run(
//public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "{name}")] HttpRequest req,
string name,
ILogger log,
[Blob("{name}/blobname",FileAccess.ReadWrite,Connection = "AzureWebJobsStorage")] CloudBlobContainer myCloudBlobContainer
)
{
//Execution Logged.
log.LogInformation($"HttpTrigger_BlobInput - C# HTTP trigger function processed a request.");
//Run the query against the blob to list the contents.
BlobContinuationToken continuationToken = null;
List<IListBlobItem> results = new List<IListBlobItem>();
do
{
var response = await myCloudBlobContainer.ListBlobsSegmentedAsync(continuationToken);
continuationToken = response.ContinuationToken;
results.AddRange(response.Results);
}
while (continuationToken != null);
//Query the names of the blobs. Todo: can this be a single line linq query select instead?
List<string> listBlobNames = new List<string>();
foreach (CloudBlockBlob b in results)
{
listBlobNames.Add(b.Name);
}
//Serialize the list of blob names to json for passing to function caller via return statement
var jsonReturn = JsonConvert.SerializeObject(listBlobNames);
log.LogInformation("Returning the following JSON");
log.LogInformation(jsonReturn);
return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(jsonReturn, Encoding.UTF8, "application/json")
};
}
}
}
Firstly, even though using keys might be convenient, I see that official documentation advises against using keys to secure function endpoint in production scenarios.
I suggest it would be a better choice to go with Azure Active Directory for security.. as explained here Secure an HTTP endpoint in production
How to Implement
I see two possible approaches:
1. Simple Approach: Check that calling application is your Azure logic app specifically
Enable Azure Active Directory Authentication for your Azure Function App. You can simply use Express settings (with create a new Azure AD app)
Enable Managed Service Identity for your Logic App.
Find out appid for Managed Service Identity associated with your logic app.. go to Azure Portal > Azure Active Directory > Enterprise Applications > All Applications > Relevant Service Principal (Explained in more detail with screenshots in another SO post here)
Authenticate your logic app to Azure function using Managed Service Identity as explained here.. Authenticate with managed identity in logic app.. note that resource being accessed will be your Azure function.
In your function code, now you can check that appid claim in access token should exactly match the appid for logic app (i.e. logic app is the one calling your function).. otherwise you can reject the call with Unauthorized exception.
2. A more declarative Approach: Have an application permission defined for Azure function app and check for this permission/role being present in auth token from client calling your function
This approach is a little more declarative, as you define an application permission that needs to be assigned to any application that can call your Azure function.
Enable Azure Active Directory Authentication for your Azure Function App. You can simply use Express settings (with create a new Azure AD app)
Now go to Azure Active Directory > App Registrations > App registration for your function app > Manifest
Add a new application role.. using json like this:
"appRoles": [
{
"allowedMemberTypes": [
"Application"
],
"displayName": "Can invoke my function",
"id": "fc803414-3c61-4ebc-a5e5-cd1675c14bbb",
"isEnabled": true,
"description": "Apps that have this role have the ability to invoke my Azure function",
"value": "MyFunctionValidClient"
}]
Enable Managed Service Identity for your Logic App.
Find out appid for Managed Service Identity associated with your logic app.. as already explained in approach 1 above
Assign the app permission to this managed service identity..
New-AzureADServiceAppRoleAssignment -ObjectId <logicappmsi.ObjectId> -PrincipalId <logicappmsi.ObjectId> -Id "fc803414-3c61-4ebc-a5e5-cd1675c14bbb" -ResourceId <yourfunctionaadapp.ObjectId>
Authenticate your logic app to Azure function using Managed Service Identity.. as already explained in approach 1 above
Now, in the auth token received by your function, you can check that the role claims collection must contain a role named "MyFunctionValidClient" otherwise you can reject the call with Unauthorized exception.
In addition to the above steps explained by #Rohit Below step is important:
Go to Host.json of the function.
Default authLevel : "function" should be changed to "authLevel": "anonymous".
This does not mean anyone can access the function as with Log on AD sign-in authentication required sign user however with managed identity in logic app function authenticate with service principle.
I want to call this API from azure resource manager to get the storage keys:
https://learn.microsoft.com/en-us/rest/api/storagerp/storageaccounts/listkeys
I want to use user authentication for this call and possibly .net sdk.
Is there any .net sdk(Nuget package) I can include in my c# project to call this API? I am seeing many solution which is using .net sdk but they are using AAD app secret, but I cannot use secret in the app since it is a desktop app. I think there should be a way to call these API with user auth and .net sdk.
The Microsoft.Azure.Services.AppAuthentication for .NET library may meet your requirement. It uses the developer's credentials to authenticate during local development. When the solution is later deployed to Azure, the library automatically switches to application credentials.
The Microsoft.Azure.Services.AppAuthentication library supports local development with Microsoft Visual Studio, Azure CLI, or Azure AD Integrated Authentication.
Sample:
using Microsoft.Azure.Management.Storage;
using Microsoft.Azure.Services.AppAuthentication;
using Microsoft.Rest;
namespace ConsoleApp6
{
class Program
{
static void Main(string[] args)
{
AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider();
string accessToken = azureServiceTokenProvider.GetAccessTokenAsync("https://management.azure.com/").Result;
var Credentials = new TokenCredentials(accessToken);
var storageManagementClient = new StorageManagementClient(Credentials);
storageManagementClient.SubscriptionId = "subscription id";
var storageAccountKey = storageManagementClient.StorageAccounts.ListKeysAsync("resource grouop name", "storage account name");
string storage_Account_Key = storageAccountKey.Result.Keys[0].Value;
System.Console.WriteLine(storage_Account_Key);
}
}
}
For more details about the authentication, you could take a look at this link.
We have multiple webapi(microservices). To communicate between these micro services we are using Azure service bus Topic\Subscription. How webapi controller can get the message subscription so that api can process the message and insert to database. I don't want to use any azure functions. I want subscribe message in my webapi(micro service directly).
You may create a client for the topic to subscribe the message and set the options to complete after the necessary process is done.
please find the below sample code, where you can read the subscription messages from a topic.
you can use WindowsAzure.ServiceBus -Nuget Package
Sample Code:
using Microsoft.ServiceBus.Messaging;
using Microsoft.ServiceBus;
var con = "your connection string for the topic";
var topic = "your topic name";
var subclient = SubscriptionClient.CreateFromConnectionString(con, topic, "yourSubscriptionName");
OnMessageOptions options = new OnMessageOptions();
options.AutoComplete = false;
client.OnMessage(message =>
{
Console.WriteLine("Message:" + message.GetBody<string>());
message.Complete();
}, options);
you may put it in separate method and use as needful.
To poll you may create a webjob, or you can place the code which triggers the web api, so that it will poll the messages at the same time.
I want to test an Azure Logic app that uses a service like Twillio to send SMS messages. Unfortunately Twillio doesn't offer SMS support in The Netherlands. What alternatives could we choose to solve this?
I used messagebird.com for this and build their API into a custom API App that I embedded in a Logic App flow:
Client client = Client.CreateDefault("[API KEY]" , null);
Message messageResponse = client.SendMessage(message.Sender,
message.MessageText, new[] { long.Parse(message.Number) });
This could also be implemented in an Azure Function to simplify deployment.