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

Update blob storage handler #32

Merged
merged 4 commits into from
Aug 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Azure.Core" Version="1.38.0" />
<PackageReference Include="Azure.Identity" Version="1.11.4" />
<PackageReference Include="Azure.Storage.Blobs" Version="12.19.1" />
<PackageReference Include="Azure.Storage.Files.Shares" Version="12.17.1" />
<PackageReference Include="Azure.Core" Version="1.42.0" />
<PackageReference Include="Azure.Identity" Version="1.12.0" />
<PackageReference Include="Azure.Storage.Blobs" Version="12.21.1" />
<PackageReference Include="Azure.Storage.Files.Shares" Version="12.19.1" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
<PackageReference Include="System.Dynamic.Runtime" Version="4.3.0" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@

using Azure.Core;
using Azure.Identity;
using Microsoft.Identity.Client;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;

Expand Down Expand Up @@ -61,6 +63,12 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage
await ObtainAccessToken();
}

// don't attempt to make the call without a token
if (string.IsNullOrWhiteSpace(_accessToken) == true)
{
throw new CredentialUnavailableException("An access token wasn't available. Please check auth settings to ensure one can be created.");
}

while (tries < _maxRetries)
{
tries++;
Expand Down Expand Up @@ -127,14 +135,22 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage

private async Task<AccessToken> ObtainAccessToken(CancellationToken cancellationToken = default)
{
if (!string.IsNullOrEmpty(_authCredentials.ManagedIdentityClientId))
if (_authCredentials.X509Certificate2 != null)
{
return await GetTokenUsingX509Certificate2Async(_authCredentials.X509Certificate2, cancellationToken);
}

if (string.IsNullOrEmpty(_authCredentials.ManagedIdentityClientId) == false)
{
return await GetClientAssertionTokenAsync(cancellationToken);
}
else

if (string.IsNullOrEmpty(_authCredentials.Key) == false)
{
return await GetTokenUsingClientSecretAsync(cancellationToken);
}

return default;
}

private async Task<AccessToken> GetClientAssertionTokenAsync(CancellationToken cancellationToken)
Expand All @@ -152,12 +168,12 @@ private async Task<AccessToken> GetClientAssertionTokenAsync(CancellationToken c
cancellationToken
);

if (!string.IsNullOrEmpty(token.Token))
if (string.IsNullOrEmpty(token.Token) == false)
{
_accessToken = token.Token;
}

return token;
return default;
}

/// <summary>
Expand All @@ -177,9 +193,27 @@ private async Task<string> GetTokenUsingManagedIdentityAsync(CancellationToken c
return token.Token;
}

private async Task<AccessToken> GetTokenUsingClientSecretAsync(CancellationToken cancellationToken)
private async Task<AccessToken> GetTokenUsingX509Certificate2Async(X509Certificate2 x509Certificate2, CancellationToken cancellationToken)
{
var app = ConfidentialClientApplicationBuilder.Create(_authCredentials.ClientId)
.WithCertificate(_authCredentials.X509Certificate2, sendX5C: true)
.WithAuthority(_authCredentials.Authority)
.Build();

var authResult = await app.AcquireTokenForClient(new[] { "https://manage.devcenter.microsoft.com/.default" })
.ExecuteAsync(cancellationToken)
.ConfigureAwait(false);

if (string.IsNullOrEmpty(authResult.AccessToken) == false)
{
_accessToken = authResult.AccessToken;
}

return default;
}

private async Task<AccessToken> GetTokenUsingClientSecretAsync(CancellationToken cancellationToken)
{
var credential = new ClientSecretCredential(
_authCredentials.TenantId,
_authCredentials.ClientId,
Expand All @@ -191,12 +225,12 @@ private async Task<AccessToken> GetTokenUsingClientSecretAsync(CancellationToken
cancellationToken
);

if (!string.IsNullOrEmpty(token.Token))
if (string.IsNullOrEmpty(token.Token) == false)
{
_accessToken = token.Token;
}

return token;
return default;
}

//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,48 @@
Licensed under the MIT license. See LICENSE file in the project root for full license information.
--*/

using System.Security.Cryptography.X509Certificates;
using System.Text.Json.Serialization;

namespace Microsoft.Devices.HardwareDevCenterManager.Utility;

public class AuthorizationHandlerCredentials
{
[JsonPropertyName("key")]
public string Key { get; set; }

[JsonPropertyName("clientId")]
public string ClientId { get; set; }
// used for Azure
[JsonPropertyName("authority")]
public string Authority { get; set; }

[JsonPropertyName("tenantId")]
public string TenantId { get; set; }

[JsonPropertyName("url")]
public System.Uri Url { get; set; }

[JsonPropertyName("urlPrefix")]
public System.Uri UrlPrefix { get; set; }
[JsonPropertyName("clientId")]
public string ClientId { get; set; }

// used for managed identity
[JsonPropertyName("managedIdentityClientId")]
public string ManagedIdentityClientId { get; set; }

[JsonPropertyName("scope")]
public string Scope { get; set; }

// used for certificate
[JsonPropertyName("x509Certificate2")]
public X509Certificate2 X509Certificate2 { get; set; }

[JsonPropertyName("x509Certificate2Name")]
public string X509Certificate2Name { get; set; }

[JsonPropertyName("keyVaultUrl")]
public string KeyVaultUrl { get; set; }

// used for client credentials
[JsonPropertyName("key")]
public string Key { get; set; }

// used for HDC
[JsonPropertyName("url")]
public System.Uri Url { get; set; }

[JsonPropertyName("urlPrefix")]
public System.Uri UrlPrefix { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ public class BlobStorageHandler
/// <summary>
/// Handles upload and download of files for HDC Azure Blob Storage URLs
/// </summary>
/// <param name="SASUrl">URL String to the blob</param>
public BlobStorageHandler(string SASUrl)
/// <param name="sasUrl">URL String to the blob</param>
public BlobStorageHandler(string sasUrl)
{
_blockBlobClient = new BlockBlobClient(new Uri(SASUrl));
_blockBlobClient = new BlockBlobClient(new Uri(sasUrl));
}

/// <summary>
Expand All @@ -35,8 +35,8 @@ public async Task Upload(string filePath)
{
try
{
using System.IO.FileStream fileStream = new(filePath, FileMode.Open, FileAccess.Read);
await _blockBlobClient.UploadAsync(fileStream, null, default);
using System.IO.FileStream fileStream = File.OpenRead(filePath);
await _blockBlobClient.UploadAsync(fileStream);
}
catch (RequestFailedException rfe)
{
Expand Down
Loading