Auto create and link backoffice account (OAuth integration)
I'm trying to integrate Umbraco with IdentityServer. I have managed to authenticate using the IdentityServer, but I still need to log in with Umbraco credentials and link the accounts to be able to use them interchangeably.
I've encountered this post: http://issues.umbraco.org/issue/U4-6753, which pretty much says that using SetExternalSignAutoLinkOptions should do the trick, but it doesn't for me. Even when using it, with new ExternalSignInAutoLinkOptions(autoLinkExternalAccount: true) I still get the
The requested provider has not been linked to to an account
error, when trying to log in using the IdentityServer.
I've managed to get this working. There were two issues, first of all, the AuthenticationType gets "Umbraco." prepended, which then fails in BackOfficeController, because AuthenticationType is now "Umbraco.https://localhost:12345", while LoginProvider is still "https://localhost:12345"
var authType = OwinContext.Authentication.GetExternalAuthenticationTypes().FirstOrDefault(x => x.AuthenticationType == loginInfo.Login.LoginProvider);
if (authType == null)
{
Logger.Warn<BackOfficeController>("Could not find external authentication provider registered: " + loginInfo.Login.LoginProvider);
return false;
}
2nd problem was the null value of loginInfo.ExternalIdentity.Name, which was taken from ClaimsIdentity.Name (which was null itself).
var autoLinkUser = new BackOfficeIdentityUser()
{
Email = loginInfo.Email,
Name = loginInfo.ExternalIdentity.Name,
UserTypeAlias = userType.Alias,
AllowedSections = autoLinkOptions.GetDefaultAllowedSections(UmbracoContext, loginInfo),
Culture = autoLinkOptions.GetDefaultCulture(UmbracoContext, loginInfo),
UserName = loginInfo.Email
};
By claims transforming I now have a proper ClaimsIdentity object, with Name filled in:
var idAuth = new OpenIdConnectAuthenticationOptions();
idAuth.Notifications = new OpenIdConnectAuthenticationNotifications
{
SecurityTokenValidated = async n =>
{
var id = n.AuthenticationTicket.Identity;
// we want to keep first name, last name, subject and roles
var givenName = id.FindFirst(System.Security.Claims.ClaimTypes.GivenName);
var familyName = id.FindFirst(System.Security.Claims.ClaimTypes.Surname);
var roles = id.FindAll(System.Security.Claims.ClaimTypes.Role);
// create new identity and set name and role claim type
var nid = new ClaimsIdentity(
id.AuthenticationType,
System.Security.Claims.ClaimTypes.GivenName,
System.Security.Claims.ClaimTypes.Role);
nid.AddClaim(givenName);
nid.AddClaim(familyName);
nid.AddClaims(roles);
nid.AddClaim(id.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier));
nid.AddClaim(id.FindFirst(System.Security.Claims.ClaimTypes.Email));
n.AuthenticationTicket = new AuthenticationTicket(
nid,
n.AuthenticationTicket.Properties);
}
};
Great that you worked this out. There's a few providers that will require the same type of logic ... we need to get the official Umb docs updated with this info.
I am having the issue that users are being created with the Name claim, but that is "LastName, FirstName MI" and I want to use the givenname and surname. I tried to use this Notifications approach, but that has yet to prove successful. Any general advice on how to go about achieving my desired goal?
I have tried sending just the givenname and surname in notifications, and I have tried sending a new name claimtype in notifications, and that has not been successful. I am connecting to ADFS.
Notifications = new WsFederationAuthenticationNotifications { // from https://our.umbraco.com/forum/developers/api-questions/73317-auto-create-and-link-backoffice-account#comment-235064
SecurityTokenValidated = async n => {
var id = n.AuthenticationTicket.Identity;
// we want to keep first name, last name
var givenName = id.FindFirst(ClaimTypes.GivenName);
var familyName = id.FindFirst(ClaimTypes.Surname);
var name = new Claim(ClaimTypes.Name, $"{givenName} {familyName}");
// create new identity and set name and role claim type
var nid = new ClaimsIdentity(
id.AuthenticationType,
ClaimTypes.GivenName,
ClaimTypes.Role);
nid.AddClaim(givenName);
nid.AddClaim(familyName);
nid.AddClaim(name);
nid.AddClaim(id.FindFirst(ClaimTypes.NameIdentifier));
nid.AddClaim(id.FindFirst(ClaimTypes.Email));
n.AuthenticationTicket = new AuthenticationTicket(
nid,
n.AuthenticationTicket.Properties);
}
}
};
Hi Bartosz, I'm also trying to use identity server within umbraco. Do you have an email address I could contact you on to ask just a couple of questions about the handling & maintaining the claims from the external provider.
Auto create and link backoffice account (OAuth integration)
I'm trying to integrate Umbraco with IdentityServer. I have managed to authenticate using the IdentityServer, but I still need to log in with Umbraco credentials and link the accounts to be able to use them interchangeably.
I've encountered this post: http://issues.umbraco.org/issue/U4-6753, which pretty much says that using SetExternalSignAutoLinkOptions should do the trick, but it doesn't for me. Even when using it, with
new ExternalSignInAutoLinkOptions(autoLinkExternalAccount: true)
I still get theerror, when trying to log in using the IdentityServer.
My code is below:
I've managed to get this working. There were two issues, first of all, the AuthenticationType gets "Umbraco." prepended, which then fails in BackOfficeController, because AuthenticationType is now "Umbraco.https://localhost:12345", while LoginProvider is still "https://localhost:12345"
What prepends the "Umbraco." bit is done in
, but adding the lower bit, after calling the upper method fixed the issue.
2nd problem was the null value of loginInfo.ExternalIdentity.Name, which was taken from ClaimsIdentity.Name (which was null itself).
By claims transforming I now have a proper ClaimsIdentity object, with Name filled in:
Great that you worked this out. There's a few providers that will require the same type of logic ... we need to get the official Umb docs updated with this info.
Hi, could you send me all code?
I am having the issue that users are being created with the Name claim, but that is "LastName, FirstName MI" and I want to use the givenname and surname. I tried to use this
Notifications
approach, but that has yet to prove successful. Any general advice on how to go about achieving my desired goal?I have tried sending just the givenname and surname in notifications, and I have tried sending a new name claimtype in notifications, and that has not been successful. I am connecting to ADFS.
Hi Bartosz, I'm also trying to use identity server within umbraco. Do you have an email address I could contact you on to ask just a couple of questions about the handling & maintaining the claims from the external provider.
cheers
my email is: [email protected]
is working on a reply...