Skip to content

Commit 072e458

Browse files
committed
Ensure AzureADOptions.Instance is set
Fixes #6022
1 parent a677fd2 commit 072e458

File tree

3 files changed

+69
-1
lines changed

3 files changed

+69
-1
lines changed

src/Azure/AzureAD/Authentication.AzureAD.UI/src/AzureADAuthenticationBuilderExtensions.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ public static AuthenticationBuilder AddAzureADBearer(
6060

6161
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IConfigureOptions<AzureADOptions>, AzureADOptionsConfiguration>());
6262

63+
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IValidateOptions<AzureADOptions>, AzureADOptionsValidation>());
64+
6365
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IConfigureOptions<JwtBearerOptions>, AzureADJwtBearerOptionsConfiguration>());
6466

6567
builder.Services.Configure(scheme, configureOptions);
@@ -115,6 +117,8 @@ public static AuthenticationBuilder AddAzureAD(
115117

116118
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IConfigureOptions<AzureADOptions>, AzureADOptionsConfiguration>());
117119

120+
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IValidateOptions<AzureADOptions>, AzureADOptionsValidation>());
121+
118122
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IConfigureOptions<OpenIdConnectOptions>, AzureADOpenIdConnectOptionsConfiguration>());
119123

120124
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IConfigureOptions<CookieAuthenticationOptions>, AzureADCookieOptionsConfiguration>());
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.using Microsoft.AspNetCore.Authorization;
3+
4+
using Microsoft.Extensions.Options;
5+
6+
namespace Microsoft.AspNetCore.Authentication.AzureAD.UI
7+
{
8+
internal class AzureADOptionsValidation : IValidateOptions<AzureADOptions>
9+
{
10+
public ValidateOptionsResult Validate(string name, AzureADOptions options)
11+
{
12+
if (string.IsNullOrEmpty(options.Instance))
13+
{
14+
return ValidateOptionsResult.Fail($"The '{nameof(AzureADOptions.Instance)}' option must be provided.");
15+
}
16+
17+
return ValidateOptionsResult.Success;
18+
}
19+
}
20+
}

src/Azure/AzureAD/Authentication.AzureAD.UI/test/AzureADAuthenticationBuilderExtensionsTests.cs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.using Microsoft.AspNetCore.Authorization;
33

44
using System;
5+
using Microsoft.AspNetCore.Authentication.AzureAD.UI;
56
using Microsoft.AspNetCore.Authentication.Cookies;
67
using Microsoft.AspNetCore.Authentication.JwtBearer;
78
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
8-
using Microsoft.AspNetCore.Authentication.AzureAD.UI;
99
using Microsoft.Extensions.DependencyInjection;
1010
using Microsoft.Extensions.Logging;
1111
using Microsoft.Extensions.Logging.Abstractions;
@@ -237,6 +237,28 @@ public void AddAzureAD_ThrowsWhenCookieSchemeIsAlreadyInUse()
237237
Assert.Equal(expectedMessage, exception.Message);
238238
}
239239

240+
[Fact]
241+
public void AddAzureAD_ThrowsWhenInstanceIsNotSet()
242+
{
243+
// Arrange
244+
var services = new ServiceCollection();
245+
services.AddSingleton<ILoggerFactory>(new NullLoggerFactory());
246+
247+
services.AddAuthentication()
248+
.AddAzureAD(o => { });
249+
250+
var provider = services.BuildServiceProvider();
251+
var azureADOptionsMonitor = provider.GetService<IOptionsMonitor<AzureADOptions>>();
252+
253+
var expectedMessage = "The 'Instance' option must be provided.";
254+
255+
// Act & Assert
256+
var exception = Assert.Throws<OptionsValidationException>(
257+
() => azureADOptionsMonitor.Get(AzureADDefaults.AuthenticationScheme));
258+
259+
Assert.Contains(expectedMessage, exception.Failures);
260+
}
261+
240262
[Fact]
241263
public void AddAzureADBearer_AddsAllAuthenticationHandlers()
242264
{
@@ -400,5 +422,27 @@ public void AddAzureADBearer_ThrowsWhenBearerSchemeIsAlreadyInUse()
400422

401423
Assert.Equal(expectedMessage, exception.Message);
402424
}
425+
426+
[Fact]
427+
public void AddAzureADBearer_ThrowsWhenInstanceIsNotSet()
428+
{
429+
// Arrange
430+
var services = new ServiceCollection();
431+
services.AddSingleton<ILoggerFactory>(new NullLoggerFactory());
432+
433+
services.AddAuthentication()
434+
.AddAzureADBearer(o => { });
435+
436+
var provider = services.BuildServiceProvider();
437+
var azureADOptionsMonitor = provider.GetService<IOptionsMonitor<AzureADOptions>>();
438+
439+
var expectedMessage = "The 'Instance' option must be provided.";
440+
441+
// Act & Assert
442+
var exception = Assert.Throws<OptionsValidationException>(
443+
() => azureADOptionsMonitor.Get(AzureADDefaults.AuthenticationScheme));
444+
445+
Assert.Contains(expectedMessage, exception.Failures);
446+
}
403447
}
404448
}

0 commit comments

Comments
 (0)