On SC 9.0.2 we want to map an existing user in sitecore automatically to an external identity provider, but get the following error:
[InvalidOperationException: Unable to create a user. Reason: DuplicateUserName]
Sitecore.Owin.Authentication.Identity.MembershipUserStore`1.CreateAsync(TUser user) +475
Microsoft.AspNet.Identity.<CreateAsync>d__0.MoveNext() +961
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() +31
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +60
Sitecore.Owin.Authentication.Services.<ResolveApplicationUserAsync>d__13.MoveNext() +949
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() +31
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +60
Sitecore.Owin.Authentication.Identity.<HandleFailureAsync>d__16.MoveNext() +548
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() +31
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +60
Sitecore.Owin.Authentication.Pipelines.Initialize.<<HandleExternalLoginCallbackUrl>b__10_1>d.MoveNext() +1341
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() +31
We override the ExternalUserBuilder:
public class CustomExternalUserBuilder : Sitecore.Owin.Authentication.Services.ExternalUserBuilder
{
public bool IsPersistentUser { get; private set; }
public override ApplicationUser BuildUser(UserManager<ApplicationUser> userManager, ExternalLoginInfo externalLoginInfo)
{
var userName = $"custom\\{externalLoginInfo.ExternalIdentity.FindFirstValue("preferred_username")}";
return new ApplicationUser(userName)
{
IsVirtual = !this.IsPersistentUser
};
}
}
and the UserAttachResolver:
public class CustomUserAttachResolver : UserAttachResolver
{
public override UserAttachResolverResult Resolve(UserAttachContext context)
{
UserManager<ApplicationUser> userManager = context.OwinContext.GetUserManager();
var user = userManager.FindByName(context.OwinContext.Request.User.Identity.Name);
if(user != null)
{
return new UserAttachResolverResult(UserAttachResolverResultStatus.Attach);
}
return new UserAttachResolverResult(UserAttachResolverResultStatus.New);
}
}
But allthough the CustomUserAttachResolver
is added to the serviceConfigurator, it is never called. I tried to remove the existing UserAttachResolver
, but I guess it's too late and that the DefaultApplicationUserResolver
is already instantiated with the existing UserAttachResolver
.
serviceCollection.AddSingleton<UserAttachResolver, CustomUserAttachResolver>();
and it's being hit (after the owin one). I've also tried to remove theUserAttachResolver
from the serviceCollection before adding, but didn't work either.