Skip to content
This repository was archived by the owner on Jan 5, 2026. It is now read-only.

Commit 1e6eb61

Browse files
authored
add token credential authentication to BlobsTranscriptStore (#6813)
1 parent f8e195f commit 1e6eb61

2 files changed

Lines changed: 88 additions & 0 deletions

File tree

libraries/Microsoft.Bot.Builder.Azure.Blobs/BlobsTranscriptStore.cs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using System.Net;
1010
using System.Threading.Tasks;
1111
using Azure;
12+
using Azure.Core;
1213
using Azure.Storage;
1314
using Azure.Storage.Blobs;
1415
using Azure.Storage.Blobs.Models;
@@ -51,6 +52,22 @@ public BlobsTranscriptStore(string dataConnectionString, string containerName, J
5152
{
5253
}
5354

55+
/// <summary>
56+
/// Initializes a new instance of the <see cref="BlobsTranscriptStore"/> class.
57+
/// </summary>
58+
/// <param name="blobServiceUri">A Uri referencing the blob container that includes the name of the account and the name of the container.</param>
59+
/// <param name="tokenCredential">The token credential to authenticate to the Azure storage.</param>
60+
/// <param name="containerName">Name of the Blob container where entities will be stored.</param>
61+
/// <param name="jsonSerializer">If passing in a custom JsonSerializer, we recommend the following settings:
62+
/// <para>jsonSerializer.TypeNameHandling = TypeNameHandling.None.</para>
63+
/// <para>jsonSerializer.NullValueHandling = NullValueHandling.Include.</para>
64+
/// <para>jsonSerializer.ContractResolver = new DefaultContractResolver().</para>
65+
/// </param>
66+
public BlobsTranscriptStore(Uri blobServiceUri, TokenCredential tokenCredential, string containerName, JsonSerializer jsonSerializer = null)
67+
: this(blobServiceUri, tokenCredential, containerName, default, jsonSerializer)
68+
{
69+
}
70+
5471
/// <summary>
5572
/// Initializes a new instance of the <see cref="BlobsTranscriptStore"/> class.
5673
/// </summary>
@@ -99,6 +116,59 @@ public BlobsTranscriptStore(string dataConnectionString, string containerName, S
99116
}, isThreadSafe: true);
100117
}
101118

119+
/// <summary>
120+
/// Initializes a new instance of the <see cref="BlobsTranscriptStore"/> class.
121+
/// </summary>
122+
/// <param name="blobServiceUri">A Uri referencing the blob container that includes the name of the account and the name of the container.</param>
123+
/// <param name="tokenCredential">The token credential to authenticate to the Azure storage.</param>
124+
/// <param name="containerName">Name of the Blob container where entities will be stored.</param>
125+
/// <param name="storageTransferOptions">Used for providing options for parallel transfers <see cref="StorageTransferOptions"/>.</param>
126+
/// <param name="jsonSerializer">If passing in a custom JsonSerializer, we recommend the following settings:
127+
/// <para>jsonSerializer.TypeNameHandling = TypeNameHandling.None.</para>
128+
/// <para>jsonSerializer.NullValueHandling = NullValueHandling.Include.</para>
129+
/// <para>jsonSerializer.ContractResolver = new DefaultContractResolver().</para>
130+
/// </param>
131+
public BlobsTranscriptStore(Uri blobServiceUri, TokenCredential tokenCredential, string containerName, StorageTransferOptions storageTransferOptions, JsonSerializer jsonSerializer = null)
132+
{
133+
if (blobServiceUri == null)
134+
{
135+
throw new ArgumentNullException(nameof(blobServiceUri));
136+
}
137+
138+
if (tokenCredential == null)
139+
{
140+
throw new ArgumentNullException(nameof(tokenCredential));
141+
}
142+
143+
if (string.IsNullOrEmpty(containerName))
144+
{
145+
throw new ArgumentNullException(nameof(containerName));
146+
}
147+
148+
_storageTransferOptions = storageTransferOptions;
149+
150+
_jsonSerializer = jsonSerializer ?? JsonSerializer.Create(new JsonSerializerSettings
151+
{
152+
NullValueHandling = NullValueHandling.Ignore,
153+
Formatting = Formatting.Indented,
154+
MaxDepth = null,
155+
});
156+
157+
// Triggers a check for the existance of the container
158+
_containerClient = new Lazy<BlobContainerClient>(
159+
() =>
160+
{
161+
var containerClient = new BlobContainerClient(blobServiceUri, tokenCredential);
162+
if (!_checkedContainers.Contains(containerName))
163+
{
164+
containerClient.CreateIfNotExistsAsync().Wait();
165+
_checkedContainers.Add(containerName);
166+
}
167+
168+
return containerClient;
169+
}, isThreadSafe: true);
170+
}
171+
102172
/// <summary>
103173
/// Initializes a new instance of the <see cref="BlobsTranscriptStore"/> class.
104174
/// </summary>

tests/Microsoft.Bot.Builder.Azure.Tests/BlobsTranscriptStoreTests.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using System.Threading;
1111
using System.Threading.Tasks;
1212
using Azure;
13+
using Azure.Core;
1314
using Azure.Storage.Blobs;
1415
using Azure.Storage.Blobs.Models;
1516
using Microsoft.Bot.Builder.Azure.Blobs;
@@ -50,13 +51,30 @@ public void ConstructorValidation()
5051
"containerName",
5152
JsonSerializer.Create(new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All }));
5253

54+
var blobServiceUri = new Uri("https://storage.net/");
55+
56+
var mockCredential = new Mock<TokenCredential>();
57+
mockCredential
58+
.Setup(c => c.GetTokenAsync(It.IsAny<TokenRequestContext>(), It.IsAny<CancellationToken>()))
59+
.ReturnsAsync(new AccessToken("fake-token", DateTimeOffset.UtcNow.AddHours(1)));
60+
5361
// No dataConnectionString. Should throw.
5462
Assert.Throws<ArgumentNullException>(() => new BlobsTranscriptStore(null, "containerName"));
5563
Assert.Throws<ArgumentNullException>(() => new BlobsTranscriptStore(string.Empty, "containerName"));
5664

5765
// No containerName. Should throw.
5866
Assert.Throws<ArgumentNullException>(() => new BlobsTranscriptStore(ConnectionString, null));
5967
Assert.Throws<ArgumentNullException>(() => new BlobsTranscriptStore(ConnectionString, string.Empty));
68+
69+
// No URI. Should throw.
70+
Assert.Throws<ArgumentNullException>(() => new BlobsTranscriptStore(blobServiceUri: null, mockCredential.Object, "containerName"));
71+
72+
// No tokenCredential. Should throw.
73+
Assert.Throws<ArgumentNullException>(() => new BlobsTranscriptStore(blobServiceUri, null, "containerName"));
74+
75+
// No containerName. Should throw.
76+
Assert.Throws<ArgumentNullException>(() => new BlobsTranscriptStore(blobServiceUri, mockCredential.Object, null));
77+
Assert.Throws<ArgumentNullException>(() => new BlobsTranscriptStore(blobServiceUri, mockCredential.Object, string.Empty));
6078
}
6179

6280
[Fact]

0 commit comments

Comments
 (0)