C#开发中Windows域认证登录2016(扩展吉日嘎拉GPM系统V4.2)
2013年搞公司的OA时,为了统一用户登录,将Windows AD的用户和OA的账号对接,OA用户名的规则就是使用Windows AD的用户名,格式举例:Troy.Cui,原理就是先进行域服务器的认证,认证完毕使用自定义的函数根据用户名读取出OA的用户信息,然后读取出用户名和密码信息,最后使用获取到的用户名和密码进行正常的登录。当时的文章:《C#开发中Windows域认证登录2(扩展吉日嘎拉GPM系统)》,本周打算OA中开发在线培训的功能,也想借此机会升级一下底层的应用DotNet.Business和DotNet.Utilities,第一个要升级的项目就是这个Windows域账号登录。
升级涉及到的文件如下:
DotNet.Business\DataAccess\Manager.User\BaseUserManager.LogOn.LDAP.cs (新增)
DotNet.Business\Service\LogOnService.LDAP.cs
DotNet.Business\WebUtilities\Utilities.LogOn.LDAP.cs
DotNet.IService\ILogOnService.LDAP.cs - 这个要将ILogOnService.cs接口写成partical (新增)
相关的核心代码如下:
1 #region public BaseUserInfo LogOnByUserName(string taskId, BaseUserInfo userInfo, string userName) 2 /// <summary> 3 /// 按用户名登录(LDAP专用) 4 /// </summary> 5 /// <param name="userInfo">用户</param> 6 /// <param name="userName">用户名</param> 7 /// <param name="statusCode">返回状态码</param> 8 /// <param name="statusMessage">返回状消息</param> 9 /// <returns>用户实体</returns> 10 public UserLogOnResult LogOnByUserName(string taskId, BaseUserInfo userInfo, string userName) 11 { 12 UserLogOnResult result = new UserLogOnResult(); 13 var parameter = ServiceInfo.Create(taskId, userInfo, MethodBase.GetCurrentMethod()); 14 ServiceUtil.ProcessUserCenterWriteDb(userInfo,parameter, (dbHelper) => 15 { 16 // 先侦测是否在线 17 //userLogOnManager.CheckOnLine(); 18 // 然后获取用户密码 19 var userManager = new BaseUserManager(userInfo); 20 // 是否从角色判断管理员 21 userManager.CheckIsAdministrator = true; 22 //根据用户名获取用户信息 23 BaseUserEntity userEntity = userManager.GetByUserName(userName); 24 25 if (userEntity != null) 26 { 27 var baseUserLogOnManager = new BaseUserLogOnManager(userInfo); 28 //获取密码 29 BaseUserLogOnEntity userLogOnEntity = baseUserLogOnManager.GetObject(userEntity.Id); 30 //string password = userLogOnEntity.UserPassword; 31 string openId = userLogOnEntity.OpenId; 32 //再进行登录 33 //result = userManager.LogOnByUserName(userName, password, null, false, "Base"); 34 result = userManager.LogOnByOpenId(openId, string.Empty, string.Empty); 35 } 36 // 登录时会自动记录进行日志记录,所以不需要进行重复日志记录 37 // BaseLogManager.Instance.Add(userInfo, this.serviceName, MethodBase.GetCurrentMethod()); 38 }); 39 return result; 40 } 41 #endregion
大家可以看出来BaseUserEntity userEntity = userManager.GetByUserName(userName);这个函数非常重要、但不能随便就调用,安全起见,仅限于集成登录时使用。
前台页面登录部分,其实您可以将自己公司的域信息写到Web.Config或者配置为BaseSystemInfo下的参数
1 /// <summary> 2 /// LDAP用户的登录操作 3 /// </summary> 4 private void LDAPUserLogOn(string userName, string password) 5 { 6 string lDAP = "LDAP://DC=CORP,DC=yourdomain,DC=com"; 7 string domain = "corpwaiglobal"; 8 string checkInput = string.Empty; 9 try 10 { 11 string statusCode = string.Empty; 12 string statusMessage = string.Empty; 13 // 有什么权限的人才可以登录到系统 14 string permissionCode = string.Empty; 15 // permissionItemCode = "Project.Admin.Access"; 16 // 登录验证 17 string openId = Utilities.GetOpenId(); 18 BaseUserInfo userInfo = Utilities.LogOnByLDAP(domain, lDAP, userName, password, openId, permissionCode, this.chkPersistCookie.Checked, false, out statusCode, out statusMessage); 19 // txtVerifyCode.Text = string.Empty; 20 // 登录结果 21 if (userInfo!=null) 22 { 23 this.AfterLogOn(userInfo); 24 // 登录成功,重新定向到跳转的页面 25 // Page.Response.Redirect(this.ReturnURL); 26 // 若是单点登录,还需要把OpenId传递过去,这样在其他子网站里可以获取到OpenId,而不是用户名密码了,可以进行加密登录了 27 if (!string.IsNullOrEmpty(this.ReturnURL) && !string.IsNullOrEmpty(userInfo.OpenId)) 28 { 29 if (this.ReturnURL.IndexOf('?') > 0) 30 { 31 this.ReturnURL = this.ReturnURL + "&OpenId=" + userInfo.OpenId; 32 } 33 else 34 { 35 this.ReturnURL = this.ReturnURL + "?OpenId=" + userInfo.OpenId; 36 } 37 } 38 Response.Redirect(this.ReturnURL, false); 39 } 40 else 41 { 42 //checkInput = "<script>alert('提示信息:" + statusMessage + "');</script>"; 43 checkInput = "<script>alert('提示信息:请检查你的用户名和密码。');</script>"; 44 Page.ClientScript.RegisterStartupScript(this.GetType(), "message", checkInput); 45 this.txtUserName.Focus(); 46 } 47 } 48 catch (System.Exception exception) 49 { 50 Page.Response.Write(exception.Message); 51 checkInput = "<script>alert('提示信息:登录失败,请重试。');</script>"; 52 Page.ClientScript.RegisterStartupScript(this.GetType(), "message", checkInput); 53 this.txtUserName.Focus(); 54 } 55 }
此文首发博客园,个人博客地址:http://www.cuiwenyuan.com/shanghai/post/Windows-AD-Logon-Intergrated-with-Jirigala-GPM-DotNet-Business-2016.html