Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Token Credential Samples with DTFx.AzureStorage v1 and v2 #1118

Merged
merged 12 commits into from
Jun 26, 2024
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Azure.Identity" Version="1.11.0" />
<PackageReference Include="Microsoft.Azure.DurableTask.AzureStorage" Version="1.17.3" />
</ItemGroup>

</Project>
72 changes: 72 additions & 0 deletions samples/ManagedIdentitySample/DTFx.AzureStorage v1.x/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using Azure.Core;
using Azure.Identity;
using DurableTask.AzureStorage;
using DurableTask.Core;
using Microsoft.WindowsAzure.Storage.Auth;

internal class Program
{
private static async Task Main(string[] args)
{
// Create credential based on the configuration
var credential = new DefaultAzureCredential();
string[] scopes = new string[] { "https://storage.azure.com/.default" }; // Scope for Azure Storage

static Task<NewTokenAndFrequency> RenewTokenFuncAsync(object state, CancellationToken cancellationToken)
{
var credential = new DefaultAzureCredential();
var initialToken = credential.GetToken(new TokenRequestContext(new[] { "https://storage.azure.com/.default" }));
var expiresAfter = initialToken.ExpiresOn - DateTimeOffset.UtcNow - TimeSpan.FromMinutes(10);
return Task.FromResult(new NewTokenAndFrequency(initialToken.Token, expiresAfter));
}

// Get the token
var accessToken = await credential.GetTokenAsync(new Azure.Core.TokenRequestContext(scopes));

var service = new AzureStorageOrchestrationService(new AzureStorageOrchestrationServiceSettings
{
StorageAccountDetails = new StorageAccountDetails
{
AccountName = "YourStorageAccount",
EndpointSuffix = "core.windows.net",
StorageCredentials = new StorageCredentials(new Microsoft.WindowsAzure.Storage.Auth.TokenCredential(
accessToken.Token,
RenewTokenFuncAsync,
null,
TimeSpan.FromMinutes(5)))
}
});

var client = new TaskHubClient(service);
var worker = new TaskHubWorker(service);

worker.AddTaskOrchestrations(typeof(SampleOrchestration));
worker.AddTaskActivities(typeof(SampleActivity));

await worker.StartAsync();

var instance = await client.CreateOrchestrationInstanceAsync(typeof(SampleOrchestration), "World");

var result = await client.WaitForOrchestrationAsync(instance, TimeSpan.FromMinutes(1));

Console.WriteLine($"Orchestration result : {result.Output}");

await worker.StopAsync();
}
}

public class SampleOrchestration : TaskOrchestration<string, string>
{
public override async Task<string> RunTask(OrchestrationContext context, string input)
{
return await context.ScheduleTask<string>(typeof(SampleActivity), input);
}
}

public class SampleActivity : TaskActivity<string, string>
{
protected override string Execute(TaskContext context, string input)
{
return "Hello, " + input + "!";
}
}
19 changes: 19 additions & 0 deletions samples/ManagedIdentitySample/DTFx.AzureStorage v1.x/ReadMe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Token Credential Sample

This sample demonstrates how to configure a Identity based connection when using DurableTask.AzureStorage v1.x as the orchestration provider for a Durable Task project.

> Note:
> Identity based connection **is not supported** with .NET framework 4.x with DurableTask.AzureStorage v1.x

## Configuration Prerequisites

Before running this sample, you must

1. Create a new Azure Storage account or reuse an existing one
2. Create your identity in the Azure Portal. Detailed instructions can be found [here](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app?tabs=certificate)
3. Assign Role-based Access Controls (RBAC) of the storage account created in step 1 to the identity created in step 2 with [these instructions](https://learn.microsoft.com/azure/role-based-access-control/role-assignments-portal-managed-identity#Overview).
* Storage Queue Data Contributor
* Storage Blob Data Contributor
* Storage Table Data Contributor
4. Add the identity required information to your app's configuration.
5. Set `AccountName` to the name of the storage account. AccountName can be replaced with Storage Account BlobServiceUri, TableServiceUri and QueueServiceUri.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Azure.DurableTask.AzureStorage" Version="2.0.0-rc.3" />
<PackageReference Include="Azure.Identity" Version="1.11.0" />
</ItemGroup>

</Project>
53 changes: 53 additions & 0 deletions samples/ManagedIdentitySample/DTFx.AzureStorage v2.x/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using DurableTask.AzureStorage;
using DurableTask.Core;
using Azure.Identity;

internal class Program
{
private static async Task Main(string[] args)
{
var credential = new DefaultAzureCredential();

// Pass the credential created to the StorageAccountClientProvider to start an AzureStorageOrchestrationService
var service = new AzureStorageOrchestrationService(new AzureStorageOrchestrationServiceSettings
{
StorageAccountClientProvider = new StorageAccountClientProvider("AccountName", credential),
});

var client = new TaskHubClient(service);
var worker = new TaskHubWorker(service);

worker.AddTaskOrchestrations(typeof(SampleOrchestration));
worker.AddTaskActivities(typeof(SampleActivity));

await worker.StartAsync();

var instance = await client.CreateOrchestrationInstanceAsync(typeof(SampleOrchestration), "World");

var result = await client.WaitForOrchestrationAsync(instance, TimeSpan.FromMinutes(1));

Console.WriteLine($"Orchestration result : {result.Output}");

await worker.StopAsync();
}
}

public class SampleOrchestration : TaskOrchestration<string, string>
{
public override async Task<string> RunTask(OrchestrationContext context, string input)
{
await context.ScheduleTask<string>(typeof(SampleActivity), input);

return "Orchestrator Finished!";
}
}

public class SampleActivity : TaskActivity<string, string>
{
protected override string Execute(TaskContext context, string input)
{
Console.WriteLine("saying hello to " + input);
return "Hello " + input + "!";
}
}

16 changes: 16 additions & 0 deletions samples/ManagedIdentitySample/DTFx.AzureStorage v2.x/ReadMe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Token Credential Sample

This sample demonstrates how to configure a Identity based connection when using DurableTask.AzureStorage v2.x as the orchestration provider for a Durable Task project.

## Configuration Prerequisites

Before running this sample, you must

1. Create a new Azure Storage account or reuse an existing one
2. Create your identity in the Azure Portal. Detailed instructions can be found [here](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app?tabs=certificate)
3. Assign Role-based Access Controls (RBAC) of the storage account created in step 1 to the identity created in step 2 with [these instructions](https://learn.microsoft.com/azure/role-based-access-control/role-assignments-portal-managed-identity#Overview).
* Storage Queue Data Contributor
* Storage Blob Data Contributor
* Storage Table Data Contributor
4. Add the identity information to your app or configuration. In the sample here, client secret credential requires clientId, clientSecret and tenantId.
5. Set `AccountName` to the name of the storage account. AccountName can be replaced with Storage Account BlobServiceUri, TableServiceUri and QueueServiceUri.
Loading