c# - Azure AD B2C Stuck on Redirect Url - Stack Overflow

admin2025-04-19  0

I've got a Blazor .NET 8 Server app. It is using B2C for authentication and is behind an application gateway.

After successful login, some users are getting redirected to the redirect url:

The app gets stuck here and users are presented with correlation error:

correlation_error

If user updates the url and removes signin-oidc so they are now just going to they are successfully logged in to the home page.

My B2C is configured like this:

"AzureAdB2C": {
    "Instance": ";,
    "ClientId": "",
    "Domain": "my-b2c.onmicrosoft",
    "ObjectId": "",
    "TenantId": "",
    "ClientSecret": "",
    "CallbackPath": "/signin-oidc",
    "SignUpSignInPolicyId": "B2C_1_MyB2C_SignIn",
    "SignedOutCallbackPath": "/signout",
}

B2C is configured with as a redirect url.

The strange thing is that this does not happen for every user at every login.

-- Update --

Adding more information via screenshots:
Here is the url sent for B2C login:
b2c-url

Here is my B2C App Registration Authentication:
b2c-redirects

Since my app is using a custom domain configured in my Application Gateway, I've coded my startup to set the redirect url if it is set in Environment Variables/appsettings:

if (!string.IsNullOrEmpty(builder.Configuration.GetValue<string>($"{authType}:CustomRedirectBaseUrl")))
{
    var redirectUrlBase = builder.Configuration.GetValue<string>($"{authType}:CustomRedirectBaseUrl");
    var redirectUrl = redirectUrlBase + builder.Configuration.GetValue<string>($"{authType}:CallbackPath");

    logger.LogInformation($"Custom redirect url is found: {redirectUrl}");

    builder.Services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, opts =>
    {
        opts.Events = new OpenIdConnectEvents
        {
            OnRedirectToIdentityProvider = async context =>
            {
                logger.LogInformation($"OnRedirectToIdentityProvider: RedirectUri set to '{redirectUrl}'");
                context.ProtocolMessage.RedirectUri = redirectUrl;
                await Task.Yield();
            },
            OnRedirectToIdentityProviderForSignOut = async context =>
            {
                logger.LogInformation($"OnRedirectToIdentityProviderForSignOut: PostLogoutRedirectUri set to '{redirectUrlBase}'");
                context.ProtocolMessage.PostLogoutRedirectUri = redirectUrlBase;
                await Task.Yield();
            }
        };
    });
}

My redirect url in Environment Variables (Azure Web App): env-variables

Here are my logs showing the system is setting the redirect url: logs

I've got a Blazor .NET 8 Server app. It is using B2C for authentication and is behind an application gateway.

After successful login, some users are getting redirected to the redirect url: https://example/signin-oidc

The app gets stuck here and users are presented with correlation error:

correlation_error

If user updates the url and removes signin-oidc so they are now just going to https://example they are successfully logged in to the home page.

My B2C is configured like this:

"AzureAdB2C": {
    "Instance": "https://my-b2c.b2clogin",
    "ClientId": "",
    "Domain": "my-b2c.onmicrosoft",
    "ObjectId": "",
    "TenantId": "",
    "ClientSecret": "",
    "CallbackPath": "/signin-oidc",
    "SignUpSignInPolicyId": "B2C_1_MyB2C_SignIn",
    "SignedOutCallbackPath": "/signout",
}

B2C is configured with https://example/signin-oidc as a redirect url.

The strange thing is that this does not happen for every user at every login.

-- Update --

Adding more information via screenshots:
Here is the url sent for B2C login:
b2c-url

Here is my B2C App Registration Authentication:
b2c-redirects

Since my app is using a custom domain configured in my Application Gateway, I've coded my startup to set the redirect url if it is set in Environment Variables/appsettings:

if (!string.IsNullOrEmpty(builder.Configuration.GetValue<string>($"{authType}:CustomRedirectBaseUrl")))
{
    var redirectUrlBase = builder.Configuration.GetValue<string>($"{authType}:CustomRedirectBaseUrl");
    var redirectUrl = redirectUrlBase + builder.Configuration.GetValue<string>($"{authType}:CallbackPath");

    logger.LogInformation($"Custom redirect url is found: {redirectUrl}");

    builder.Services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, opts =>
    {
        opts.Events = new OpenIdConnectEvents
        {
            OnRedirectToIdentityProvider = async context =>
            {
                logger.LogInformation($"OnRedirectToIdentityProvider: RedirectUri set to '{redirectUrl}'");
                context.ProtocolMessage.RedirectUri = redirectUrl;
                await Task.Yield();
            },
            OnRedirectToIdentityProviderForSignOut = async context =>
            {
                logger.LogInformation($"OnRedirectToIdentityProviderForSignOut: PostLogoutRedirectUri set to '{redirectUrlBase}'");
                context.ProtocolMessage.PostLogoutRedirectUri = redirectUrlBase;
                await Task.Yield();
            }
        };
    });
}

My redirect url in Environment Variables (Azure Web App): env-variables

Here are my logs showing the system is setting the redirect url: logs

Share edited Mar 4 at 18:43 user29875125 asked Mar 3 at 20:43 user29875125user29875125 12 bronze badges 2
  • 1 please provide the code that you've tried. – Sirra Sneha Commented Mar 3 at 23:52
  • The strange thing is that this does not happen for every user at every login. --> so that the error records in the screenshot occurred intermittently? It so, then I'm afraid it's more likely a network issue or something else but not code issue.... – Tiny Wang Commented Mar 4 at 10:24
Add a comment  | 

2 Answers 2

Reset to default 0

I created a sample Blazor server (.NET 8) application and successfully authenticated using Azure AD B2C.

Please refer this blog for creating the application and configuring Azure B2C authentication.

Make sure you're defining the correct policy name, domain, or instance in your appsettings.json.

appsettings.json:


{
"AzureAdB2C": {
"Instance": "https://{ Azure B2C Domain Name}.b2clogin/tfp/",
"ClientId": "<Client-Id>",
"CallbackPath": "/signin-oidc",
"Domain": "{ Azure B2C Domain Name}.onmicrosoft",
"SignUpSignInPolicyId": "B2C_1_Blazorsigninsingup",
"ResetPasswordPolicyId": "",
"EditProfilePolicyId": ""
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

My program.cs file:

using blazorb2c.Components;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.Identity.Web.UI;
using Microsoft.Identity.Web;
using System.Reflection;
using System.Security.Claims;
using System.Linq.Dynamic.Core;
using blazorb2c.Components;
namespace BlazorAzureB2C
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);
        
            builder.Configuration.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
            
            var env = builder.Environment;
            builder.Configuration.AddJsonFile($"appsettings{env.EnvironmentName}.json", optional: true);
            builder.Configuration.AddEnvironmentVariables()
                .AddUserSecrets(Assembly.GetExecutingAssembly(), true);
                 builder.Services.AddRazorComponents()
                .AddInteractiveServerComponents()
                .AddMicrosoftIdentityConsentHandler();
            builder.Services.AddCascadingAuthenticationState();
            builder.Services.AddHttpClient();
            builder.Services.AddHttpContextAccessor();
            builder.Services.AddScoped<HttpContextAccessor>();
                        builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
                .AddMicrosoftIdentityWebApp(options =>
                {
                    builder.Configuration.Bind("AzureAdB2C", options);
                    options.Events = new OpenIdConnectEvents
                    {
                        OnRedirectToIdentityProvider = async ctxt =>
                        {
                            await Task.Yield();
                        },
                        OnAuthenticationFailed = async ctxt =>
                        {
                            
                            await Task.Yield();
                        },
                        OnSignedOutCallbackRedirect = async ctxt =>
                        {
                            ctxt.HttpContext.Response.Redirect(ctxt.Options.SignedOutRedirectUri);
                            ctxt.HandleResponse();
                            await Task.Yield();
                        },
                        OnTicketReceived = async ctxt =>
                        {
                            if (ctxt.Principal != null)
                            {
                                if (ctxt.Principal.Identity is ClaimsIdentity identity)
                                {
                                    var colClaims = await ctxt.Principal.Claims.ToDynamicListAsync();
                                    var IdentityProvider = colClaims.FirstOrDefault(
                                        c => c.Type == "http://schemas.microsoft/identity/claims/identityprovider")?.Value;
                                    var Objectidentifier = colClaims.FirstOrDefault(
                                        c => c.Type == "http://schemas.xmlsoap./ws/2005/05/identity/claims/nameidentifier")?.Value;
                                    var EmailAddress = colClaims.FirstOrDefault(
                                        c => c.Type == "http://schemas.xmlsoap./ws/2005/05/identity/claims/emailaddress")?.Value;
                                    var FirstName = colClaims.FirstOrDefault(
                                        c => c.Type == "http://schemas.xmlsoap./ws/2005/05/identity/claims/givenname")?.Value;
                                    var LastName = colClaims.FirstOrDefault(
                                        c => c.Type == "http://schemas.xmlsoap./ws/2005/05/identity/claims/surname")?.Value;
                                    var AzureB2CFlow = colClaims.FirstOrDefault(
                                        c => c.Type == "http://schemas.microsoft/claims/authnclassreference")?.Value;
                                    var auth_time = colClaims.FirstOrDefault(
                                        c => c.Type == "auth_time")?.Value;
                                    var DisplayName = colClaims.FirstOrDefault(
                                        c => c.Type == "name")?.Value;
                                    var idp_access_token = colClaims.FirstOrDefault(
                                        c => c.Type == "idp_access_token")?.Value;
                                }
                            }
                            await Task.Yield();
                        },
                    };
                });
            builder.Services.AddControllersWithViews()
                .AddMicrosoftIdentityUI();
            var app = builder.Build();
            
            if (!app.Environment.IsDevelopment())
            {
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseRouting();
            app.UseAuthentication();
            app.UseAuthorization();
            app.MapControllers();
            app.UseAntifery();
            app.MapRazorComponents<App>()
                .AddInteractiveServerRenderMode();
            app.Run();
        }
    }
}

Add the correct Redirect URI to your Azure B2C app registration as shown below.

I've successfully authenticated to Azure B2C.

I ended up getting a working solution:

  1. Added middleware to intercept requests to /signin-oidc and /MicrosoftIdentity/Account/Error and redirect back to home page

  2. Added empty razor page with path of /signin-oidc and /MicrosoftIdentity/Account/Error

My home page auto redirects to /MicrosoftIdentity/Account/SignIn if the user is not authenticated.

Any of the requests coming to /signin-oidc are not registered as authenticated, the home page re directs them to b2c login, and they are quickly returned to the home page and logged in.

Good user path:

  1. Navigate to https://www.example

  2. User not authenticated and auto-redirected to b2c login

    1. Enter Credentials & 2FA
  3. Redirected and logged into https://www.example

Troublesome user path:

  1. Navigate to https://www.example

  2. Auto-redirected to b2c login

    1. Enter Credentials & 2FA
  3. Redirected and not logged into https://www.example/signin-oidc

  4. Middleware redirects to https://www.example

  5. User not authenticated and auto-redirected to b2c login

    1. No inputs are required here
  6. Redirected and logged into https://www.example

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1745073099a283404.html

最新回复(0)