umbraco / Umbraco.Cloud.Issues

Public issue tracker for Umbraco Cloud
26 stars 2 forks source link

Umbraco.Cloud.Identity.Cms 13 doesn't seem to work with MemberAuthenticationBuilder.AddMicrosoftIdentityWebApp #734

Open AlexanderWagner82 opened 7 months ago

AlexanderWagner82 commented 7 months ago

Issue description

Hi

I'm upgrading my clients site from 10 to 13 and they have a B2C login for their members (see code bellow).

It seems that the version of Microsoft.Identity.Web (version 1.25.9) that Umbraco.Cloud.Identity.Cms is using doesn't work with MemberAuthenticationBuilder.AddMicrosoftIdentityWebApp. After I've logged in on the B2C-login page I get this error:

IDX40001: Issuer 'https://[Instance]/[TenantId]/v2.0' does not match any of the valid issuers provided for this application.

If I remove Umbraco.Cloud.Identity.Cms and only uses MicroSoft.Identity.Web 1.16.0 (that worked for Umbraco.Cloud.Identity.Cms 10) or 2.7.0 (latest stable) it works.

I found this post about that error but upgrading MicroSoft.Identity.Web to a version higher than the one that Umbraco.Cloud.Identity.Cms uses only results in crashes when the site is starting up.

Removing Umbraco.Cloud.Identity.Cms isn't really ideal either, as you can imagine.

builder.AddMemberExternalLogins(logins => { logins.AddMemberLogin( membersAuthenticationBuilder => { membersAuthenticationBuilder.AddMicrosoftIdentityWebApp( options => { options.ResponseType = OpenIdConnectResponseType.Code; options.Instance = aadInstance; options.Domain = tenant; options.ClientId = clientId; options.ClientSecret = clientSecret; options.SignUpSignInPolicyId = signInPolicyId; options.CallbackPath = "/umbraco-b2c-members-signin"; options.Events.OnTokenValidated = context => { var principal = context.Principal; if (principal is null) throw new InvalidOperationException("No claims found.");

                    if (!principal.HasClaim(x => x.Type == ClaimTypes.Email))
                    {
                        var loggedInEmail = principal.Claims.FirstOrDefault(c => c.Type.Equals("emails"))?.Value;

                        if (!string.IsNullOrEmpty(loggedInEmail))
                        {
                            var emailClaim = new Claim(ClaimTypes.Email, loggedInEmail);
                            var identity = (ClaimsIdentity)principal.Identity;
                            identity.AddClaim(emailClaim);
                        }
                    }

                    return Task.CompletedTask;
                };
                options.Events.OnRemoteFailure = async context =>
                {
                    var errorMessage = GetErrorMessage(context.Failure);
                    if (errorMessage.Contains("AADB2C90091"))
                    {
                        context.Response.Redirect("/");
                    }
                    else
                    {
                        context.Response.Redirect(string.Format("{0}?error={1}", failedPage, errorMessage));
                    }
                };
                options.Scope.Add(options.ClientId);
            }, 
            openIdConnectScheme: membersAuthenticationBuilder.SchemeForMembers(AzureB2CMembersExternalLoginProviderOptions.SchemeName));
    });

});

Adding this seems to solve the problem, but it's not really a good idea from a security perspective so best approach would be if Umbraco.Cloud.Identity.Cms supported a later version of MicroSoft.Identity.Web

options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false };

sajumb commented 7 months ago

Hi @AlexanderWagner82, Thank you for your detailed report on the B2C login issue after upgrading from Umbraco 10 to 13. We appreciate your insights and the workaround you've identified involving Microsoft.Identity.Web.

We're reviewing the compatibility of Umbraco.Cloud.Identity.Cms with newer versions of Microsoft.Identity.Web to address the challenges you've highlighted. We'll keep you posted on our progress.