Skip to content

Commit

Permalink
Add DefaultAzureFluentCredential
Browse files Browse the repository at this point in the history
  • Loading branch information
jongio committed Jan 14, 2020
1 parent bc652f1 commit 4b5380a
Show file tree
Hide file tree
Showing 8 changed files with 167 additions and 3 deletions.
28 changes: 27 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ This repo is a place for us to share ideas and extensions to the Azure Identity
## DefaultAzureMgmtCredential

### .NET
The `DefaultAzureMgmtCredential` class allows you to use all the goodness of `Azure.Identity.DefaultAzureCredential` in the Azure Management libraries. You can use it in place of `ServiceClientCredential` when calling your Azure Management APIs. The Azure Management libraries will be updated to support Azure Identity and Azure Core in early 2020, so this should just be used a a stopgap between now and then.

Example usage:
Expand Down Expand Up @@ -46,4 +45,31 @@ using Microsoft.Azure.Management.CosmosDB.Models;
var client = new CosmosDBManagementClient(new DefaultAzureMgmtCredential());
```

## DefaultAzureFluentCredential

The `DefaultAzureFluentCredential` class allows you to use all the goodness of `Azure.Identity.DefaultAzureCredential` in the [Azure Management **Fluent** libraries](https://github.com/Azure/azure-libraries-for-net). You can use it in place of `AzureCredentials` when calling your Azure Management Fluent APIs.

### Resource Group

```
dotnet add package JonGallant.Azure.Identity.Extensions
dotnet add package Microsoft.Azure.Management.Fluent --version 1.30.0
```

Use `DefaultAzureFluentCredential` in place of `AzureCredentials`:

```csharp
using JonGallant.Azure.Identity.Extensions;
using Microsoft.Azure.Management.ResourceManager.Fluent;

var creds = new DefaultAzureFluentCredential(tenantId, AzureEnvironment.AzureGlobalCloud);

var resourceGroup = Azure.Authenticate(creds)
.WithSubscription(subId)
.ResourceGroups
.Define(name)
.WithRegion(region)
.Create();
```

More to come soon. Please file a GitHub issue with any questions/suggestions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using DotNetEnv;
using Microsoft.Azure.Management.ResourceManager.Fluent;
using System;
using Xunit;

namespace JonGallant.Azure.Identity.Extensions.Tests.Fluent
{
public class ResourceGroupTests
{
[Fact]
public void CreateAzCredsTest()
{
Env.Load("../../../.env");

var creds = new DefaultAzureFluentCredential(Environment.GetEnvironmentVariable("AZURE_TENANT_ID"), AzureEnvironment.AzureGlobalCloud);

var name = Environment.GetEnvironmentVariable("AZURE_RESOURCE_GROUP") + Guid.NewGuid().ToString("n").Substring(0, 8);

var resourceGroup = Microsoft.Azure.Management.Fluent.Azure.Authenticate(creds).
WithSubscription(Environment.GetEnvironmentVariable("AZURE_SUBSCRIPTION_ID")).
ResourceGroups.Define(name).WithRegion(Environment.GetEnvironmentVariable("AZURE_REGION")).Create();

Assert.Equal(resourceGroup.Name, name);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
<PackageReference Include="DotNetEnv" Version="1.4.0" />
<PackageReference Include="Microsoft.Azure.Management.ApplicationInsights" Version="0.2.0-preview" />
<PackageReference Include="Microsoft.Azure.Management.CosmosDB" Version="1.0.1" />
<PackageReference Include="Microsoft.Azure.Management.Fluent" Version="1.30.0" />
<PackageReference Include="Microsoft.Azure.Management.ResourceManager" Version="3.0.0-preview" />
<PackageReference Include="Microsoft.Azure.Management.ResourceManager.Fluent" Version="1.30.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using System;
using Xunit;

namespace JonGallant.Azure.Identity.Extensions.Tests
namespace JonGallant.Azure.Identity.Extensions.Tests.Mgmt
{
public class AppInsightsTests
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
using System.Collections.Generic;
using Xunit;

namespace JonGallant.Azure.Identity.Extensions.Tests
namespace JonGallant.Azure.Identity.Extensions.Tests.Mgmt
{
public class CosmosDBTests
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using DotNetEnv;
using Microsoft.Azure.Management.ResourceManager;
using Microsoft.Azure.Management.ResourceManager.Models;
using System;
using System.Collections.Generic;
using Xunit;

namespace JonGallant.Azure.Identity.Extensions.Tests.Mgmt
{
public class ResourceGroupTests
{
[Fact]
public void CreateResourceGroupTest()
{
Env.Load("../../../.env");

var client = new ResourceManagementClient(new DefaultAzureMgmtCredential());
client.SubscriptionId = Environment.GetEnvironmentVariable("AZURE_SUBSCRIPTION_ID");

var name = Environment.GetEnvironmentVariable("AZURE_RESOURCE_GROUP") + Guid.NewGuid().ToString("n").Substring(0, 8);

var rg = new ResourceGroup(location:Environment.GetEnvironmentVariable("AZURE_REGION"), name:name);

var result = client.ResourceGroups.CreateOrUpdate(name, rg);

Assert.Equal(result.Name, name);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using Microsoft.Azure.Management.ResourceManager.Fluent;
using Microsoft.Azure.Management.ResourceManager.Fluent.Authentication;
using Microsoft.Rest;
using Microsoft.Rest.Azure.Authentication;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;

namespace JonGallant.Azure.Identity.Extensions
{
public class DefaultAzureFluentCredential : AzureCredentials
{
private IDictionary<Uri, ServiceClientCredentials> credentialsCache;

public DefaultAzureFluentCredential(string tenantId, AzureEnvironment environment) : base(default(DeviceCredentialInformation), tenantId, environment)
{
credentialsCache = new ConcurrentDictionary<Uri, ServiceClientCredentials>();
}

public async override Task ProcessHttpRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{

// BEING COPY FROM FLUENT
var adSettings = new ActiveDirectoryServiceSettings
{
AuthenticationEndpoint = new Uri(Environment.AuthenticationEndpoint),
TokenAudience = new Uri(Environment.ManagementEndpoint),
ValidateAuthority = true
};

string url = request.RequestUri.ToString();
if (url.StartsWith(Environment.GraphEndpoint, StringComparison.OrdinalIgnoreCase))
{
adSettings.TokenAudience = new Uri(Environment.GraphEndpoint);
}

string host = request.RequestUri.Host;
if (host.EndsWith(Environment.KeyVaultSuffix, StringComparison.OrdinalIgnoreCase))
{
var resource = new Uri(Regex.Replace(Environment.KeyVaultSuffix, "^.", "https://"));
if (credentialsCache.ContainsKey(new Uri(Regex.Replace(Environment.KeyVaultSuffix, "^.", "https://"))))
{
adSettings.TokenAudience = resource;
}
else
{
using (var r = new HttpRequestMessage(request.Method, url))
{
var response = await new HttpClient().SendAsync(r).ConfigureAwait(false);

if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized && response.Headers.WwwAuthenticate != null)
{
var header = response.Headers.WwwAuthenticate.ElementAt(0).ToString();
var regex = new Regex("authorization=\"([^\"]+)\"");
var match = regex.Match(header);
adSettings.AuthenticationEndpoint = new Uri(match.Groups[1].Value);
regex = new Regex("resource=\"([^\"]+)\"");
match = regex.Match(header);
adSettings.TokenAudience = new Uri(match.Groups[1].Value);
}
}
}
}

// END COPY FROM FLUENT

if (!credentialsCache.ContainsKey(adSettings.TokenAudience))
{
credentialsCache[adSettings.TokenAudience] = new DefaultAzureMgmtCredential();
}
await credentialsCache[adSettings.TokenAudience].ProcessHttpRequestAsync(request, cancellationToken);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

<ItemGroup>
<PackageReference Include="Azure.Identity" Version="1.1.0" />
<PackageReference Include="Microsoft.Azure.Management.ResourceManager.Fluent" Version="1.30.0" />
<PackageReference Include="Microsoft.Rest.ClientRuntime" Version="2.3.21" />
</ItemGroup>

Expand Down

0 comments on commit 4b5380a

Please sign in to comment.