Skip to content

Commit

Permalink
Add anonymous auth for ASP.NET Core integration (#7036)
Browse files Browse the repository at this point in the history
  • Loading branch information
pakrym authored Jul 29, 2019
1 parent 2134814 commit 7422e2d
Show file tree
Hide file tree
Showing 9 changed files with 53 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,11 @@ public AzureClientFactoryBuilder ConfigureDefaults(IConfiguration configuration)
return this;
}

IAzureClientBuilder<TClient, TOptions> IAzureClientFactoryBuilderWithCredential.RegisterClientFactory<TClient, TOptions>(Func<TOptions, TokenCredential, TClient> clientFactory)
IAzureClientBuilder<TClient, TOptions> IAzureClientFactoryBuilderWithCredential.RegisterClientFactory<TClient, TOptions>(Func<TOptions, TokenCredential, TClient> clientFactory, bool requiresCredential)
{
var clientRegistration = new ClientRegistration<TClient, TOptions>(DefaultClientName, clientFactory);
clientRegistration.RequiresTokenCredential = requiresCredential;

_serviceCollection.AddSingleton(clientRegistration);

_serviceCollection.TryAddSingleton(typeof(IConfigureOptions<AzureClientCredentialOptions<TClient>>), typeof(DefaultCredentialClientOptionsSetup<TClient>));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ internal class ClientRegistration<TClient, TOptions>
{
public string Name { get; set; }
public object Version { get; set; }
public bool RequiresTokenCredential { get; set; }

private readonly Func<TOptions, TokenCredential, TClient> _factory;

Expand Down Expand Up @@ -43,6 +44,12 @@ public TClient GetClient(TOptions options, TokenCredential tokenCredential)
return _cachedClient;
}


if (RequiresTokenCredential && tokenCredential == null)
{
throw new InvalidOperationException("Client registration requires a TokenCredential. Configure it using UseCredential method.");
}

try
{
_cachedClient = _factory(options, tokenCredential);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ public static object CreateClient(Type clientType, Type optionsType, object opti
{
if (IsCredentialParameter(parameter))
{
if (credential == null)
{
match = false;
break;
}

arguments.Add(credential);
continue;
}
Expand Down
11 changes: 11 additions & 0 deletions sdk/core/Azure.Core.Extensions/tests/AzureClientFactoryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,17 @@ public void SupportsSettingVersion()
Assert.AreEqual(TestClientOptions.ServiceVersion.B, client.Options.Version);
}

[Test]
public void ThrowsIfCredentialIsNullButIsRequired()
{
var serviceCollection = new ServiceCollection();
serviceCollection.AddAzureClients(builder => builder.AddTestClient(new Uri("http://localhost/")).WithCredential((TokenCredential)null));

ServiceProvider provider = serviceCollection.BuildServiceProvider();
InvalidOperationException exception = Assert.Throws<InvalidOperationException>(() => provider.GetService<TestClient>());
Assert.AreEqual("Client registration requires a TokenCredential. Configure it using UseCredential method.", exception.Message);
}

private IConfiguration GetConfiguration(params KeyValuePair<string, string>[] items)
{
return new ConfigurationBuilder().AddInMemoryCollection(items).Build();
Expand Down
12 changes: 12 additions & 0 deletions sdk/core/Azure.Core.Extensions/tests/ClientFactoryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,18 @@ public void CreatesClientSecretCredentials()
Assert.AreEqual("ConfigurationTenantId", clientSecretCredential.TenantId);
}

[Test]
public void IgnoresConstructorWhenCredentialsNull()
{
IConfiguration configuration = GetConfiguration(new KeyValuePair<string, string>("uri", "http://localhost"));

var clientOptions = new TestClientOptions();
var client = (TestClientWithCredentials)ClientFactory.CreateClient(typeof(TestClientWithCredentials), typeof(TestClientOptions), clientOptions, configuration, null);

Assert.AreEqual("http://localhost/", client.Uri.ToString());
Assert.AreSame(clientOptions, client.Options);
}

private IConfiguration GetConfiguration(params KeyValuePair<string, string>[] items)
{
return new ConfigurationBuilder().AddInMemoryCollection(items).Build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@ internal class TestClientWithCredentials : TestClient
{
public TokenCredential Credential { get; }

public TestClientWithCredentials(Uri uri, TestClientOptions options) : base(uri, options)
{
}

public TestClientWithCredentials(Uri uri, TokenCredential credential, TestClientOptions options) : base(uri, options)
{
if (credential == null) throw new ArgumentNullException(nameof(credential));
Credential = credential;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ namespace Azure.Core.Extensions
{
public interface IAzureClientFactoryBuilderWithCredential
{
IAzureClientBuilder<TClient, TOptions> RegisterClientFactory<TClient, TOptions>(Func<TOptions, TokenCredential, TClient> clientFactory) where TOptions: class;
IAzureClientBuilder<TClient, TOptions> RegisterClientFactory<TClient, TOptions>(Func<TOptions, TokenCredential, TClient> clientFactory, bool requiresCredential = true) where TOptions: class;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ public static IAzureClientBuilder<BlobServiceClient, BlobClientOptions> AddBlobS
/// Registers a <see cref="BlobServiceClient"/> instance with the provided <paramref name="serviceUri"/>
/// </summary>
public static IAzureClientBuilder<BlobServiceClient, BlobClientOptions> AddBlobServiceClient<TBuilder>(this TBuilder builder, Uri serviceUri)
where TBuilder: IAzureClientFactoryBuilder
where TBuilder: IAzureClientFactoryBuilderWithCredential
{
return builder.RegisterClientFactory<BlobServiceClient, BlobClientOptions>(options => new BlobServiceClient(serviceUri, options));
return builder.RegisterClientFactory<BlobServiceClient, BlobClientOptions>(
(options, token) => token != null ? new BlobServiceClient(serviceUri, token, options) : new BlobServiceClient(serviceUri, options),
requiresCredential: false);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ public static IAzureClientBuilder<QueueServiceClient, QueueClientOptions> AddQue
/// Registers a <see cref="QueueServiceClient"/> instance with the provided <paramref name="serviceUri"/>
/// </summary>
public static IAzureClientBuilder<QueueServiceClient, QueueClientOptions> AddQueueServiceClient<TBuilder>(this TBuilder builder, Uri serviceUri)
where TBuilder: IAzureClientFactoryBuilder
where TBuilder: IAzureClientFactoryBuilderWithCredential
{
return builder.RegisterClientFactory<QueueServiceClient, QueueClientOptions>(options => new QueueServiceClient(serviceUri, options));
return builder.RegisterClientFactory<QueueServiceClient, QueueClientOptions>(
(options, token) => token != null ? new QueueServiceClient(serviceUri, token, options) : new QueueServiceClient(serviceUri, options),
requiresCredential: false);
}

/// <summary>
Expand Down

0 comments on commit 7422e2d

Please sign in to comment.