Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • ianhoughton 281 posts 605 karma points c-trib
    Dec 08, 2022 @ 10:03
    ianhoughton
    0

    Can't get Azure ADB2C login working for members

    I've added Azure ADB2C login for members to my umb10 site, but I have a few issues:

    a) I can only get the sign in to work if I add this bit of code:

    signInManager.SignInAsync(user, true) 
    

    during the OnTicketReceived event handler. Without it, IsAutheticated is always false for the user.

    b) the OnAutoLinking & OnExternalLogin callbacks in my AzureB2CMembersExternalLoginProviderOptions class never seem to be fired

    c) if i retrieve a user with:

    memberManager.FindByNameAsync(name).GetAwaiter().GetResult()
    

    the user doesn't have any roles assigned to it (but it does if i retrieve the same user with:

    memberService.GetByEmail(email)
    

    This is my code:

    public static IUmbracoBuilder ConfigureAuthenticationMembers(this IUmbracoBuilder builder)
    {
        builder.Services.ConfigureOptions<AzureB2CMembersExternalLoginProviderOptions>();
        builder.AddMemberExternalLogins(logins =>
        {
            logins.AddMemberLogin(
                membersAuthenticationBuilder =>
                {
                    membersAuthenticationBuilder.AddMicrosoftAccount(
                        membersAuthenticationBuilder.SchemeForMembers(AzureB2CMembersExternalLoginProviderOptions.SchemeName),
                        options =>
                        {
                            var config = builder.Config;
    
                            options.Scope.Add("openid");
                            options.Scope.Add("profile");
                            options.Scope.Add("email");
                            options.Scope.Add("phone");
                            options.Scope.Add("address");
    
                            options.CallbackPath = "/signin-microsoft";
                            options.ClientId = "xxxx";
                            options.ClientSecret = "xxxx";
                            options.SaveTokens = true;
    
                            //options.Events.OnRedirectToAuthorizationEndpoint = OnRedirectToAuthorizationEndpoint;
                            options.Events.OnTicketReceived = OnTicketReceived;
                            options.Events.OnAccessDenied = OnAccessDenied;
                        });
                });
        });
    
        return builder;
    }
    
    private static Task OnTicketReceived(TicketReceivedContext arg)
    {
        var logger = arg.HttpContext.RequestServices.GetService<ILogger>();
        try
        {
            var objectidentifier = arg.Principal?.Claims.FirstOrDefault(c => c.Type.Equals(Constants.Identity.NameIdentifierSchema))?.Value;
            if (!string.IsNullOrEmpty(objectidentifier))
            {
                var state = arg.Properties.Items[Constants.Identity.State];
    
                logger.Information($"Signed in ADB2C user: [{objectidentifier}]");
    
                //Now, make sure a membership user is in sync with the currently logged in user
                UpdateOrInsertMembershipMember(objectidentifier, arg.HttpContext);
    
                IMemberSignInManager signInManager = arg.HttpContext.RequestServices.GetService<IMemberSignInManager>();
                IMemberManager memberManager = arg.HttpContext.RequestServices.GetService<IMemberManager>();
                var user = memberManager.FindByNameAsync(objectidentifier).GetAwaiter().GetResult();
    
                // Roles are empty at this point !!!
                var roles = user.Roles;
    
                signInManager.SignInAsync(user, true);
    
                var umbracoContextFactory = arg.HttpContext.RequestServices.GetService<IUmbracoContextFactory>();
    
                using (var ctx = umbracoContextFactory.EnsureUmbracoContext())
                {
                    var portal = ctx.UmbracoContext.Content.GetAtRoot().First(x => x.IsDocumentType(Portal.ModelTypeAlias));
                    var accountPending = portal.FirstChild<AccountPending>();
                    arg.Response.Redirect(accountPending.Url());
                }
            }
            else
            {
                logger.Error("Unable to retrieve the object identifier from the ADB2C Identity");
            }
        }
        catch (Exception e)
        {
            logger.Error(e.Message, e);
        }
    
        return Task.FromResult(0);
    }
    
    private static async Task UpdateOrInsertMembershipMember(string objectidentifier, HttpContext context)
    {
        var configuration = context.RequestServices.GetService<IConfiguration>();
        var appSettings = configuration.GetSection("AppSettings");
    
        var email = $"{objectidentifier}@{appSettings["ida-UmbracoMemberEmail"]}";
    
        var memberService = context.RequestServices.GetService<IMemberService>();
        var publishedSnapshotAccessor = context.RequestServices.GetService<IPublishedSnapshotAccessor>();
    
        var member = memberService.GetByEmail(email);
        if (member != null)
        {
            member.Username = objectidentifier;
            member.Name = objectidentifier;
            member.LastLoginDate = DateTime.Now;
            memberService.Save(member);
        }
        else
        {
            member = memberService.CreateMember(objectidentifier, email, objectidentifier, AzureAdmember.ModelTypeAlias);
            member.LastLoginDate = DateTime.Now;
            member.SetValue(AzureAdmember.GetModelPropertyType(publishedSnapshotAccessor, x => x.Language).Alias, Constants.Culture.BaseCulture);
            memberService.Save(member);
    
            //After the user was created add it to the New role.
            memberService.AssignRole(objectidentifier, Constants.MemberGroups.New);
        }
    
        // Roles are correct when user is retrieved from the memberservice
        var rolesTest = memberService.GetAllRoles(objectidentifier);
    }
    

    Note: I'm using .AddMicrosoftAccount and NOT .AddOpenIdConnect

Please Sign in or register to post replies

Write your reply to:

Draft