Reputation: 1070
I'm trying to use Azure Active Directory to handle authentication on a web app. However, when I try to hit an action with the AuthorizeAttribute
, the app throws a OptionsValidationException
. With the following error:
Microsoft.Extensions.Options.OptionsValidationException: The 'Instance' option must be provided.
at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
at Microsoft.Extensions.Options.OptionsMonitor`1.<>c__DisplayClass11_0.<Get>b__0()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy`1.CreateValue()
at System.Lazy`1.get_Value()
at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
at Microsoft.Extensions.Options.OptionsMonitor`1.Get(String name)
at Microsoft.AspNetCore.Authentication.AzureAD.UI.AzureADOpenIdConnectOptionsConfiguration.Configure(String name, OpenIdConnectOptions options)
at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
at Microsoft.Extensions.Options.OptionsMonitor`1.<>c__DisplayClass11_0.<Get>b__0()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy`1.CreateValue()
at System.Lazy`1.get_Value()
at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
at Microsoft.Extensions.Options.OptionsMonitor`1.Get(String name)
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.InitializeAsync(AuthenticationScheme scheme, HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext context, String authenticationScheme)
at Microsoft.AspNetCore.Authentication.AuthenticationService.ChallengeAsync(HttpContext context, String scheme, AuthenticationProperties properties)
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.ChallengeAsync(AuthenticationProperties properties)
at Microsoft.AspNetCore.Authentication.AuthenticationService.ChallengeAsync(HttpContext context, String scheme, AuthenticationProperties properties)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
I can't figure out what is causing this. Here's the code:
Add a package reference to Microsoft.AspNetCore.Authentication.AzureAD.UI
version 3.1.1.
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(defaultScheme: AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options =>
{
options.ClientId = "<client_id_goes_here>";
options.TenantId = "<tenant_id_goes_here>";
});
services.AddControllers();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseDeveloperExceptionPage();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints => endpoints.MapControllers());
}
Using only one controller.
public class HomeController : Controller
{
[Route("")]
[AllowAnonymous]
public string Index() => "Hello Anonymous User!";
[Route("restricted")]
[Authorize]
public string Restricted() => $"Hello, {User.Identity.Name}.";
}
When you run the app and hit the Index action, you get the excepted output:
Hello Anonymous User!
When you hit the /restricted
endpoint, then the exception is thrown.
Upvotes: 9
Views: 19619
Reputation: 1
My Solution to the error: ArgumentNullException: IDW10106: The 'Instance' option must be provided
This error occurred in my .NET Core 8 Razor Pages project, integrated with Entity Framework and connected to an Oracle 19c database. (under Vs.Code/MAC)
Reviewed the configuration in Program.cs
:
I added and corrected the authentication setup for cookies, Google, and Microsoft Azure in the Program.cs
file. The relevant code is as follows:
var builder = WebApplication.CreateBuilder(args);
// Configure authentication with cookies and Google/MS Azure
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddGoogle(options =>
{
IConfigurationSection googleAuthNSection = builder.Configuration.GetSection("Authentication:Google");
options.ClientId = googleAuthNSection["ClientId"] ?? string.Empty;
options.ClientSecret = googleAuthNSection["ClientSecret"] ?? string.Empty;
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddOpenIdConnect("AzureAD", options =>
{
IConfigurationSection MsAzureAuthNSection = builder.Configuration.GetSection("AzureAD");
options.ClientId = MsAzureAuthNSection["ClientId"] ?? string.Empty;
options.ClientSecret = MsAzureAuthNSection["ClientSecret"] ?? string.Empty;
options.Authority = MsAzureAuthNSection["Authority"] ?? string.Empty;
options.ResponseType = "code";
options.CallbackPath = "/signin-oidc"; // Redirect URL after login
options.SaveTokens = true;
});
Updated appsettings.json
:
I corrected the Azure AD configuration in appsettings.json
, making sure that the Instance
property was present and correctly configured:
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "mohamedfmm.********.com",
"ClientId": "#####-####-####-############",
"ClientSecret": "#######-###-####-####-#############",
"TenantId": "######-####-####-####-##############",
"Authority": "https://login.microsoftonline.com/[TenantId]/v2.0",
"CallbackPath": "/signin-oidc"
}
Updated package versions:
I found that my Microsoft.Identity.Web
version was outdated. I upgraded to version 3.2.0
since NuGet did not show the latest version of Microsoft.Identity.Web.UI
. I updated the .csproj
file like this:
<PackageReference Include="Microsoft.Identity.Web" Version="3.2.0" />
<PackageReference Include="Microsoft.Identity.Web.UI" Version="3.2.0" />
Issue with UserSecretsId
:
I realized that my project had UserSecretsId
enabled in the .csproj
file:
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
**<UserSecretsId>aspnet-com.embarques.application-38f49a89-e4ff-4232-9620-996456b13f99</UserSecretsId>**
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>
With UserSecretsId
enabled, the configuration values stored in secrets.json
were used instead of those in appsettings.json
.
Manually updated secrets.json
:
[my path /users/mohamedmtz/.microsoft/usersecrets/aspnet-com.embarques.application-38f49a89-e4ff-4232-9620-996456b13f99]
The problem persisted because the ClientId
, ClientSecret
, and Authority
values updated in appsettings.json
were not reflected in secrets.json
. After manually copying these parameters to secrets.json
, the error stopped appearing, and the application was successfully deployed.
Thank you very much for your contributions.
Upvotes: 0
Reputation: 325
I was getting the same error for my Project. I figured out that the Client ID was not injected to the Appsettings variable as a part of Azure DevOps Pipeline deployment. As a result the Kubernetes pods were missing the Azure AD variables. Tweaking the secrets.yaml in Azure Devops solved the problem.
Upvotes: 2
Reputation: 27528
You didn't provide several configrations that Microsoft.AspNetCore.Authentication.AzureAD.UI
needed in Azure AD authentication , such as Instance
,CallbackPath
. You can modify your codes as below :
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
Then in appsettings.json
,adding bleow configration :
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "xxxx.onmicrosoft.com",
"TenantId": "xxxxxx-a2dd-4fde-bf8f-f75ab18b21ac",
"ClientId": "xxxxxxxxx-a9bb-4722-b615-6dcbdc646326",
"CallbackPath": "/signin-oidc"
},
Of course , you should provide the real domian/tenant/clientid in Azure portal and register https://localhost:xxx/signin-oidc
as redirect url in portal .
Another way is use the Azure AD authentication template : New ASP.NET Core application -->Choose MVC/Razor template -->change authentication-->Work or School Account -->choose your tenant and the template will help config your application to implement Azure AD authentication .
Upvotes: 19