Jossean Yamil
Jossean Yamil

Reputation: 1070

ASP.NET Core 3.1 Azure AD Authentication throws OptionsValidationException

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.

Startup Class

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());
}

Home Controller

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

Answers (3)

Mohamed Martinez
Mohamed Martinez

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)

Steps I followed to resolve the issue:

  1. 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;
    });
    
  2. 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"
    }
    
  3. 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" />
    
  4. 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.

  5. 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

Purushottam.Prasad
Purushottam.Prasad

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

Nan Yu
Nan Yu

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

Related Questions