/// <summary>绑定用户,用户未有效绑定或需要强制绑定时</summary> /// <param name="uc"></param> /// <param name="client"></param> public virtual IManageUser OnBind(UserConnect uc, OAuthClient client) { var log = LogProvider.Provider; var prv = Provider; var mode = ""; // 如果未登录,需要注册一个 var user = prv.Current; if (user == null) { // 匹配UnionId if (user == null && !client.UnionID.IsNullOrEmpty()) { var list = UserConnect.FindAllByUnionId(client.UnionID); //// 排除当前项,选择登录次数最多的用户 //list = list.Where(e => e.ID != uc.ID && e.UserID > 0).ToList(); // 选择登录次数最多的用户 var ids = list.Where(e => e.Enable && e.UserID > 0).Select(e => e.UserID).Distinct().ToArray(); var users = ids.Select(e => User.FindByID(e)).Where(e => e != null).ToList(); if (users.Count > 0) { mode = "UnionID"; user = users.OrderByDescending(e => e.Logins).FirstOrDefault(); } } var set = Setting.Current; var cfg = OAuthConfig.FindByName(client.Name); //if (!cfg.AutoRegister) throw new InvalidOperationException($"绑定[{cfg}]要求本地已登录!"); if (user == null && !set.AutoRegister && !cfg.AutoRegister) { log?.WriteLog(typeof(User), "SSO登录", false, $"无法找到[{client.Name}]的[{client.NickName}]在本地的绑定,且没有打开自动注册,准备进入登录页面,利用其它登录方式后再绑定", 0, user + ""); return(null); } // 先找用户名,如果存在,就加上提供者前缀,直接覆盖 var name = client.UserName; if (name.IsNullOrEmpty()) { name = client.NickName; } if (user == null && !name.IsNullOrEmpty()) { // 强制绑定本地用户时,没有前缀 if (set.ForceBindUser) { mode = "UserName"; user = prv.FindByName(name); } else { mode = "Provider-UserName"; name = client.Name + "_" + name; user = prv.FindByName(name); } } // 匹配Code if (user == null && set.ForceBindUserCode) { mode = "UserCode"; if (!client.UserCode.IsNullOrEmpty()) { user = User.FindByCode(client.UserCode); } } // 匹配Mobile if (user == null && set.ForceBindUserMobile) { mode = "UserMobile"; if (!client.Mobile.IsNullOrEmpty()) { user = User.FindByMobile(client.Mobile); } } // 匹配Mail if (user == null && set.ForceBindUserMail) { mode = "UserMail"; if (!client.Mail.IsNullOrEmpty()) { user = User.FindByMail(client.Mail); } } // QQ、微信 等不返回用户名 if (user == null && name.IsNullOrEmpty()) { // OpenID和AccessToken不可能同时为空 var openid = client.OpenID; if (openid.IsNullOrEmpty()) { openid = client.AccessToken; } // 过长,需要随机一个较短的 var num = openid.GetBytes().Crc(); mode = "OpenID-Crc"; name = client.Name + "_" + num.ToString("X8"); user = prv.FindByName(name); } if (user == null) { mode = "Register"; // 新注册用户采用魔方默认角色 var rid = Role.GetOrAdd(set.DefaultRole).ID; //if (rid == 0 && client.Items.TryGetValue("roleid", out var roleid)) rid = roleid.ToInt(); //if (rid <= 0) rid = GetRole(client.Items, rid < -1); // 注册用户,随机密码 user = prv.Register(name, Rand.NextString(16), rid, true); //if (user is User user2) user2.RoleIDs = GetRoles(client.Items, rid < -2).Join(); } } uc.UserID = user.ID; uc.Enable = true; // 写日志 log?.WriteLog(typeof(User), "绑定", true, $"[{user}]依据[{mode}]绑定到[{client.Name}]的[{client.NickName}]", user.ID, user + ""); return(user); }