DuplicateUserName error using Identity

Claudio Bley asked on August 2, 2021 12:33

Hi.

We have a .NET 5 app with external auth provided by Azure AD B2C. We are using Xperience 13.0.32, currently.

We did integrate the Identity module as per the documentation and as demonstrated by the Medio Clinic example code.

Now, sometimes when a new user signs in, we run into an DuplicateUserName error:

User validation failed: DuplicateUserName.

In startup.cs we have:

        services.AddScoped<IMessageService, MessageService>();
        services.AddScoped<IPasswordHasher<MyUser>, Kentico.Membership.PasswordHasher<MyUser>>();

        services.AddApplicationIdentity<MyUser, ApplicationRole>()
            .AddApplicationDefaultTokenProviders()
            .AddUserStore<ApplicationUserStore<MyUser>>()
            .AddRoleStore<ApplicationRoleStore<ApplicationRole>>()
            .AddUserManager<UserManager>()
            .AddSignInManager<MySignInManager>();

I can trigger the error by deleting the user via the admin app. When I try to login again, the login fails when trying to create the user in the backing store:

// Attempts to create the user in the Xperience database
IdentityResult result = await CreateAsync(user);

How can I fix this? Thanks!

\edit: I added logging in a few places, and it showed an exception that was suppressed before:

    Message: Unable to access repository configuration file 'C:\inetpub\wwwroot\Kentico13\CMS\App_Data\CIRepository\repository.config'. This is typically a result of improperly configured permissions for the file.

    Exception type: CMS.ContinuousIntegration.RepositoryConfigurationException
    Stack trace:
    at CMS.ContinuousIntegration.Internal.FileSystemRepositoryConfigurationBuilder.LoadConfigurationFile()
    at CMS.ContinuousIntegration.Internal.FileSystemRepositoryConfigurationBuilder.LoadConfigurationFromFileOrInfos()
    at CMS.ContinuousIntegration.FileSystemRepositoryManager..ctor(IFileSystemRepositoryConfigurationBuilder configurationBuilder)
    at CMS.ContinuousIntegration.FileSystemRepositoryManager.GetInstance()
    at CMS.ContinuousIntegration.ContinuousIntegrationHelper.GetDependentObjectsWhereConditionsInternal(ObjectTypeInfo typeInfo, IWhereCondition dependencyWhere)
    at CMS.ContinuousIntegration.ContinuousIntegrationHelper.GetDependentObjectsWhereConditions(ObjectTypeInfo typeInfo, IWhereCondition dependencyWhere)
    at CMS.ContinuousIntegration.Internal.ContinuousIntegrationEventHandling.<>c__DisplayClass8_0.b__0(BaseInfo info, Action`2 action)
    at CMS.ContinuousIntegration.Internal.ContinuousIntegrationEventHandling.<>c__DisplayClass8_0.b__1()
    at CMS.DataEngine.AbstractInfoBase`1.ExecuteWithOriginalDataCore(Action action)
    at CMS.DataEngine.AbstractInfoBase`1.ExecuteWithOriginalData(Action action)
    at CMS.ContinuousIntegration.Internal.ContinuousIntegrationEventHandling.BaseInfoUpdateBefore(BaseInfo baseInfo, CMSEventArgs eventArgs)
    at CMS.ContinuousIntegration.ContinuousIntegrationHandlers.UpdateInnerBefore(Object sender, ObjectEventArgs e)
    at CMS.Base.AbstractHandler.CallEventHandler[TArgs](EventHandler`1 h, TArgs e)
    at CMS.Base.AbstractHandler.Raise[TArgs](String partName, List`1 list, TArgs e, Boolean important)
    at CMS.Base.AdvancedHandler`2.RaiseBefore(TArgs e)
    at CMS.Base.AdvancedHandler`2.RaiseBefore(TArgs e)
    at CMS.Base.AdvancedHandler`2.RaiseBefore(TArgs e)
    at CMS.Base.AdvancedHandler`2.StartEvent(TArgs e, Boolean allowEvent)
    at CMS.DataEngine.AbstractInfoBase`1.UpdateData()
    at CMS.DataEngine.AbstractInfoBase`1.GeneralizedInfoWrapper.UpdateData()
    at CMS.DataEngine.AbstractInfoProvider`3.SetInfo(TInfo info)
    at CMS.Membership.UserInfoProvider.SetUserInfoInternal(UserInfo user)
    at CMS.Membership.UserInfoProvider.Set(UserInfo info)
    at Kentico.Membership.ApplicationUserStore`1.UpdateAsync(TUser user, CancellationToken cancellationToken)
    at Microsoft.AspNetCore.Identity.UserManager`1.UpdateUserAsync(TUser user)
    at Microsoft.AspNetCore.Identity.UserManager`1.AddLoginAsync(TUser user, UserLoginInfo login)
    at Identity.UserManager.CreateExternalUser(ExternalLoginInfo loginInfo) in C:\home\site\repository\Identity\UserManager.cs:line 96
    at Identity.AccountManager.SignInExternalAsync(ExternalLoginInfo loginInfo) in C:\home\site\repository\Identity\AccountManager.cs:line 75

    Message: Access to the path 'C:\inetpub\wwwroot\Kentico13\CMS\App_Data\CIRepository' is denied.

    Exception type: System.UnauthorizedAccessException
    Stack trace:
    at System.IO.FileSystem.CreateDirectory(String fullPath, Byte[] securityDescriptor)
    at System.IO.Directory.CreateDirectory(String path)
    at CMS.FileSystemStorage.Directory.CreateDirectory(String path)
    at CMS.IO.Directory.CreateDirectory(String path)
    at CMS.ContinuousIntegration.DefaultRepositoryConfigurationFileCreator.StoreInitial(IMainObjectTypeProvider mainObjectTypeProvider, String path)
    at CMS.ContinuousIntegration.Internal.FileSystemRepositoryConfigurationBuilder.LoadConfigurationFile()

I tried disabling the continuous integration feature in the admin app. But that does not make a difference - I still see these exceptions.

What is the continuous integration trying to do in the live app?

Where does the path C:\inetpub\wwwroot\Kentico13\CMS\App_Data\CIRepository come from? The app is running in Azure, under \home\...?

Recent Answers


Claudio Bley answered on August 2, 2021 20:14

At least I figured out where the path is set: it's just the CMSCIRepositoryPath app setting.

I suppose that the duplicate user error was just the consequential effect of the exception that was raised before.

However, I would have expected that the app does not start if the CMS CI repository path is such a vital component, and trying to create that some time later is just asking for trouble...

0 votesVote for this answer Mark as a Correct answer

Claudio Bley answered on August 4, 2021 12:07

I can reproduce the error after deleting a user via the admin app.

Trying to login with that user again, calls the CreateAsync method of the UserManager which insists that the given User Name already exists.

After restarting the app, the call to CreateAsync succeeds.

Seems to be a caching issue? But why is a mutating call cached somewhere? I'll open a support case.

0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.