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 (新增)

相关的核心代码如下:

#region public BaseUserInfo LogOnByUserName(string taskId, BaseUserInfo userInfo, string userName)
        /// <summary>
        /// 按用户名登录(LDAP专用)
        /// </summary>
        /// <param name="userInfo">用户</param>
        /// <param name="userName">用户名</param>
        /// <param name="statusCode">返回状态码</param>
        /// <param name="statusMessage">返回状消息</param>
        /// <returns>用户实体</returns>
        public UserLogOnResult LogOnByUserName(string taskId, BaseUserInfo userInfo, string userName)
        {
            UserLogOnResult result = new UserLogOnResult();
            var parameter = ServiceInfo.Create(taskId, userInfo, MethodBase.GetCurrentMethod());
            ServiceUtil.ProcessUserCenterWriteDb(userInfo,parameter, (dbHelper) =>
            {
                // 先侦测是否在线
                //userLogOnManager.CheckOnLine();
                // 然后获取用户密码
                var userManager = new BaseUserManager(userInfo);
                // 是否从角色判断管理员
                userManager.CheckIsAdministrator = true;
                //根据用户名获取用户信息
                BaseUserEntity userEntity = userManager.GetByUserName(userName);
                
                if (userEntity != null)
                {
                    var baseUserLogOnManager = new BaseUserLogOnManager(userInfo);
                    //获取密码
                    BaseUserLogOnEntity userLogOnEntity = baseUserLogOnManager.GetObject(userEntity.Id);
                    //string password = userLogOnEntity.UserPassword;
                    string openId = userLogOnEntity.OpenId;
                    //再进行登录
                    //result = userManager.LogOnByUserName(userName, password, null, false, "Base");
                    result = userManager.LogOnByOpenId(openId, string.Empty, string.Empty);
                }
                // 登录时会自动记录进行日志记录,所以不需要进行重复日志记录
                // BaseLogManager.Instance.Add(userInfo, this.serviceName, MethodBase.GetCurrentMethod());
            });
            return result;
        }
        #endregion

大家可以看出来BaseUserEntity userEntity = userManager.GetByUserName(userName);这个函数非常重要、但不能随便就调用,安全起见,仅限于集成登录时使用。

前台页面登录部分,其实您可以将自己公司的域信息写到Web.Config或者配置为BaseSystemInfo下的参数

    /// <summary>
    /// LDAP用户的登录操作
    /// </summary>
    private void LDAPUserLogOn(string userName, string password)
    {
        string lDAP = "LDAP://DC=CORP,DC=yourdomain,DC=com";
        string domain = "corpwaiglobal";
        string checkInput = string.Empty;
        try
        {
            string statusCode = string.Empty;
            string statusMessage = string.Empty;
            // 有什么权限的人才可以登录到系统
            string permissionCode = string.Empty;
            // permissionItemCode = "Project.Admin.Access";
            // 登录验证
            string openId = Utilities.GetOpenId();
            BaseUserInfo userInfo = Utilities.LogOnByLDAP(domain, lDAP, userName, password, openId, permissionCode, this.chkPersistCookie.Checked, false, out statusCode, out statusMessage);
            // txtVerifyCode.Text = string.Empty;
            // 登录结果
            if (userInfo!=null)
            {
                this.AfterLogOn(userInfo);
                // 登录成功,重新定向到跳转的页面
                // Page.Response.Redirect(this.ReturnURL);
                // 若是单点登录,还需要把OpenId传递过去,这样在其他子网站里可以获取到OpenId,而不是用户名密码了,可以进行加密登录了
                if (!string.IsNullOrEmpty(this.ReturnURL) && !string.IsNullOrEmpty(userInfo.OpenId))
                {
                    if (this.ReturnURL.IndexOf('?') > 0)
                    {
                        this.ReturnURL = this.ReturnURL + "&OpenId=" + userInfo.OpenId;
                    }
                    else
                    {
                        this.ReturnURL = this.ReturnURL + "?OpenId=" + userInfo.OpenId;
                    }
                }
                Response.Redirect(this.ReturnURL, false);
            }
            else
            {
                //checkInput = "<script>alert('提示信息:" + statusMessage + "');</script>";
                checkInput = "<script>alert('提示信息:请检查你的用户名和密码。');</script>";
                Page.ClientScript.RegisterStartupScript(this.GetType(), "message", checkInput);
                this.txtUserName.Focus();
            }
        }
        catch (System.Exception exception)
        {
            Page.Response.Write(exception.Message);
            checkInput = "<script>alert('提示信息:登录失败,请重试。');</script>";
            Page.ClientScript.RegisterStartupScript(this.GetType(), "message", checkInput);
            this.txtUserName.Focus();
        }
    }

吉日嘎拉C#快速开发平台V4.0到V4.2升级记

目前我用的版本是4.0的,也有近2年没更新了,狠了狠心升级一下,没想到真的行动起来,也没那么难!

用了3天时间,将吉日嘎拉的代码升级到了4.2版本,并让原来的DotNet.WebApplication正常运行起来,比料想的顺利。这里简单记录一下升级中的心得。

使用到的工具:

1、BeyondCompare 试用版 – 比较程序文件

2、SQLDelta 14天试用版 – 比较数据库表结构变化(及数据变化)

3、VS2010 – 保证升级后WebApplication好用

4、MSSQL 2008 R2 – 标配数据库

最新代码的亮点:

1、分离出了DotNet.Model

2、分离出来DotNet.IService

3、DotNet.Business新增Redis缓存

4、DotNet.Utilities新增众多BaseSystemInfo参数和底层函数:数据库读写分离等

5、新增DotNet.UserCenter,用于其它程序如WebApp、安卓、苹果端调用

6、用户登录日志表完善、强大

7、数据库访问增加跟踪及底层文本日志

8、增加DotNet.MVC项目,BS端的用户及权限管理(还未研究)

相关截图:

1、数据库UserCenter更新

2、项目及解决方案截图

注意事项:

1、SqlDelta生成部署的代码后,还需要手动更新老记录中一些字段的值

UPDATE [UserCenterV40].[dbo].[BaseUser]
SET IsAdministrator=1,UserName='Administrator',NickName='Administrator'
WHERE UserName='Admin'
UPDATE BaseModule SET AuthorizedDays=0
UPDATE BaseUserLogOn SET OpenIdTimeout = GETDATE() 
UPDATE BaseUserContact SET MobileVerificationDate = GETDATE()

2、DotNet.WebApplication中有很多登录及读取权限的函数需要更新BaseSystemInfo.SystemCode

本文是升级记录的第1篇,后继会继续记录研究DotNet.MVC项目后的心得,敬请期待。

后记:请大家不要问我要源码,如需购买请直接联系吉日嘎拉,他的博客园的主页地址:http://www.cnblogs.com/jirigala/

终于跟吉日嘎拉见了一面

这几年,我经常跟做技术的几个好朋友提到一个人,那就是吉日嘎拉,一个在技术上我崇拜的人,一个在软件行业有建树的偶像。他能够坚持一件事情10多年,他的产品,他的人能够被众多同行所接受,并且他还在坚持。

想去杭州见见吉日嘎拉是我的一个几年前的念头,每隔几个月都会冒出来,想跟他学习C#开发以及他的通用权限管理及快速开发平台,这几年来,相继也购买了学习版、个人开发版,但一直未能用起来,见面的事情也一直拖着,心想着何时才能专程去杭州呢?怎想到他今年居然来了上海工作(年薪不方便透漏,但绝对很高),更没想到公司的老板还是希望我们自己开发自己的内部办公平台,有了这个机缘,我打算说服老板让公司购买这套开发平台,在正式购买之前,我想先用起来这个系统(先用我的个人开发版进行开发),让老板看到一些应用,看到开发的效率和可见性的投资回报。看了几天的学习视频,实际操作了Winform的应用,收获很大,但还是遇到实际使用部署方面的疑问,想亲自请教他一下,本希望他能抽时间出来,我到他公司拜访的,没想到我一说明问题,他居然说月底亲自过来一趟。

今天中午,QQ上临时约了一下,几个小时后,在我公司见到了期待已久的吉日嘎拉,不过可惜的是晚上下了班,因为他是请了1小时假从青浦赶过来的,路途也堵。晚上我们就在我家门口的丰收日吃了顿便饭,席间了解到吉日的近况,饭后花了半个小时不到,打开我的笔记本,几分钟就把我遇到的调试问题搞定,同时回答了我近期的不少疑问。现在想想,这人和人的差别真大呀,他作为程序员曾经也是公司技术骨干,年薪近30万,自己也出来创业过,失败过,但一直坚持自己的这个理想和兴趣,持续的改进和完善这个权限管理系统及快速开发平台,能够被大型国企、银行金融企业、外资企业、中小型软件创业团队、个人程序员所接受,付费用户达到600多个,自己的产品能被他现在的一家全国前5的物流快递公司使用,并担负起2年内完成所有内部系统的重构、整合工作,这所有一切背后的坚持都值得我去学习和仰望。“近朱者赤”,希望以此为契机吧,能够专注在某一方面有所建树,能够在职业、事业发展方面越走越宽,越走越稳固。

另外,吉日送了一本他写的书《程序员,你伤不起》给我,还签了名,看来不仅是技术上需要向他学习,在处事上更需要向他学习。