asp.net-coreazure-active-directoryidentityserver4microsoft-account

Login with Microsoft External Account -Issue when the user cancels the consent prompt during authentication


I'm using Microsoft external authentication in a .NET 5 Razor Pages application, and I'm encountering an issue when the user cancels the consent prompt during authentication. The behavior works as expected for personal Microsoft accounts — when a user cancels, they are redirected back to the login page successfully. However, when a work account user cancels, I receive the following exception:

An unhandled exception occurred while processing the request. Exception: consent_required;Description=AADSTS65004: User declined to consent to access the app. Trace ID: 88696573-49b5-472b-8db9-40bd03711600 Correlation ID: 9babdc71-9c05-4910-8f29-c5b3aa6b5cc1 Timestamp: 2024-10-14 06:05:38Z;Uri=https://login.microsoftonline.com/error?code=65004 Unknown location

Exception: An error was encountered while handling the remote login.** Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler<TOptions>.HandleRequestAsync()**

public static class MicrosoftAuthExtension
{
    public static void AddMicrosoftAuth(this IServiceCollection services, IConfiguration configuration)
    {
        services.AddAuthentication()
            .AddMicrosoftAccount(options =>
            {
                IConfigurationSection microsoftAuthNSection = configuration.GetSection("Authentication:Microsoft");
                options.ClientId = microsoftAuthNSection["ClientId"];
                options.ClientSecret = microsoftAuthNSection["ClientSecret"];
                options.CallbackPath = new PathString("/Identity/Account/MicrosoftExternalAccountCallBack");
                options.AccessDeniedPath = new PathString("/Identity/Account/Login");
                options.SaveTokens = true;
            });
    }
}

enter image description here

I’ve set options.AccessDeniedPath to redirect back to the login page if consent is denied.

This works fine for personal accounts, but throws an exception for work accounts.

Does anyone know why this might be happening only for work accounts, and how I can handle this gracefully for both personal and work accounts? Any help would be appreciated!


Solution

  • We can Invoke OnRemoteFailure when there is a remote failure.

    Here is the sample code

    services.AddAuthentication().AddMicrosoftAccount(options =>
    {
       IConfigurationSection microsoftAuthNSection = configuration.GetSection("Authentication:Microsoft");
       options.ClientId = microsoftAuthNSection["ClientId"];
       options.ClientSecret = microsoftAuthNSection["ClientSecret"];
       options.CallbackPath = new PathString("/Identity/Account/MicrosoftExternalAccountCallBack");
       options.AccessDeniedPath = new PathString("/Identity/Account/Login");
       options.SaveTokens = true;
    
       options.Events = new Microsoft.AspNetCore.Authentication.OAuth.OAuthEvents
       {
           OnRemoteFailure = context =>
           {
               if (context.Request.Query["error"] == "consent_required")
               {
                   context.Response.Redirect("/Identity/Account/Login?error=consent_declined");
                   context.HandleResponse(); 
                   return Task.CompletedTask;
               }
    
               context.Response.Redirect("/Identity/Account/Login?error=unexpected_error");
               context.HandleResponse();
               return Task.CompletedTask;
           }
       };
    });