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 anonymous auth for ASP.NET Core integration #7036

Merged
merged 2 commits into from
Jul 29, 2019
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 @@ -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