fix #5531 - external login single sign-on for multiple sites

This commit is contained in:
sbwalker
2025-08-27 13:54:30 -04:00
parent 9a6195edf1
commit edad9e6b3c

View File

@ -476,8 +476,26 @@ namespace Oqtane.Extensions
else else
{ {
var logins = await _identityUserManager.GetLoginsAsync(identityuser); var logins = await _identityUserManager.GetLoginsAsync(identityuser);
var login = logins.FirstOrDefault(item => item.LoginProvider == (providerType + ":" + alias.SiteId.ToString())); // check if any logins exist for this user and provider type for any site
if (login == null) var login = logins.FirstOrDefault(item => item.LoginProvider.StartsWith(providerType));
if (login != null || !bool.Parse(httpContext.GetSiteSettings().GetValue("ExternalLogin:VerifyUsers", "true")))
{
// external login using existing user account - link automatically
user = _users.GetUser(identityuser.UserName);
user.SiteId = alias.SiteId;
var _notifications = httpContext.RequestServices.GetRequiredService<INotificationRepository>();
string url = httpContext.Request.Scheme + "://" + alias.Name;
string body = "You Recently Used An External Account To Sign In To Our Site.\n\n" + url + "\n\nThank You!";
var notification = new Notification(user.SiteId, user, "User Account Notification", body);
_notifications.AddNotification(notification);
// add user login
await _identityUserManager.AddLoginAsync(identityuser, new UserLoginInfo(providerType + ":" + user.SiteId.ToString(), id, providerName));
_logger.Log(user.SiteId, LogLevel.Information, "ExternalLogin", Enums.LogFunction.Create, "External Login Linkage Created For User {Username} And Provider {Provider}", user.Username, providerName);
}
else
{ {
if (bool.Parse(httpContext.GetSiteSettings().GetValue("ExternalLogin:VerifyUsers", "true"))) if (bool.Parse(httpContext.GetSiteSettings().GetValue("ExternalLogin:VerifyUsers", "true")))
{ {
@ -495,24 +513,6 @@ namespace Oqtane.Extensions
_logger.Log(alias.SiteId, LogLevel.Information, "ExternalLogin", Enums.LogFunction.Create, "External Login Linkage Verification For Provider {Provider} Sent To {Email}", providerName, email); _logger.Log(alias.SiteId, LogLevel.Information, "ExternalLogin", Enums.LogFunction.Create, "External Login Linkage Verification For Provider {Provider} Sent To {Email}", providerName, email);
} }
else else
{
// external login using existing user account - link automatically
user = _users.GetUser(identityuser.UserName);
user.SiteId = alias.SiteId;
var _notifications = httpContext.RequestServices.GetRequiredService<INotificationRepository>();
string url = httpContext.Request.Scheme + "://" + alias.Name;
string body = "You Recently Used An External Account To Sign In To Our Site.\n\n" + url + "\n\nThank You!";
var notification = new Notification(user.SiteId, user, "User Account Notification", body);
_notifications.AddNotification(notification);
// add user login
await _identityUserManager.AddLoginAsync(identityuser, new UserLoginInfo(providerType + ":" + user.SiteId.ToString(), id, providerName));
_logger.Log(user.SiteId, LogLevel.Information, "ExternalLogin", Enums.LogFunction.Create, "External Login Linkage Created For User {Username} And Provider {Provider}", user.Username, providerName);
}
}
else
{ {
// provider keys do not match // provider keys do not match
identity.Label = ExternalLoginStatus.ProviderKeyMismatch; identity.Label = ExternalLoginStatus.ProviderKeyMismatch;
@ -520,19 +520,40 @@ namespace Oqtane.Extensions
} }
} }
} }
}
// manage user // manage user
if (user != null) if (user != null)
{ {
// manage roles // manage roles
var _roles = httpContext.RequestServices.GetRequiredService<IRoleRepository>();
var _userRoles = httpContext.RequestServices.GetRequiredService<IUserRoleRepository>(); var _userRoles = httpContext.RequestServices.GetRequiredService<IUserRoleRepository>();
var userRoles = _userRoles.GetUserRoles(user.UserId, user.SiteId).ToList(); var userRoles = _userRoles.GetUserRoles(user.UserId, user.SiteId).ToList();
// if user is signing in to a new site
if (userRoles.Count == 0)
{
// add auto assigned roles to user for site
var roles = _roles.GetRoles(user.SiteId).Where(item => item.IsAutoAssigned).ToList();
foreach (var role in roles)
{
var userrole = new UserRole();
userrole.UserId = user.UserId;
userrole.RoleId = role.RoleId;
userrole.EffectiveDate = null;
userrole.ExpiryDate = null;
userrole.IgnoreSecurityStamp = true;
_userRoles.AddUserRole(userrole);
}
userRoles = _userRoles.GetUserRoles(user.UserId, user.SiteId).ToList();
}
// process any role claims
if (!string.IsNullOrEmpty(httpContext.GetSiteSettings().GetValue("ExternalLogin:RoleClaimType", ""))) if (!string.IsNullOrEmpty(httpContext.GetSiteSettings().GetValue("ExternalLogin:RoleClaimType", "")))
{ {
// external roles // external roles
if (claimsPrincipal.Claims.Any(item => item.Type == httpContext.GetSiteSettings().GetValue("ExternalLogin:RoleClaimType", ""))) if (claimsPrincipal.Claims.Any(item => item.Type == httpContext.GetSiteSettings().GetValue("ExternalLogin:RoleClaimType", "")))
{ {
var _roles = httpContext.RequestServices.GetRequiredService<IRoleRepository>();
var allowhostrole = bool.Parse(httpContext.GetSiteSettings().GetValue("ExternalLogin:AllowHostRole", "false")); var allowhostrole = bool.Parse(httpContext.GetSiteSettings().GetValue("ExternalLogin:AllowHostRole", "false"));
var roles = _roles.GetRoles(user.SiteId, allowhostrole).ToList(); var roles = _roles.GetRoles(user.SiteId, allowhostrole).ToList();