コード例 #1
0
ファイル: AccountController.cs プロジェクト: zszqwe/anycmd
        public ActionResult GetPlistCatalogAccounts(GetPlistCatalogAccounts input)
        {
            if (!ModelState.IsValid)
            {
                return(ModelState.ToJsonResult());
            }
            input.IncludeDescendants = input.IncludeDescendants ?? false;
            List <DicReader> data;

            if (string.IsNullOrEmpty(input.CatalogCode))
            {
                if (!AcSession.IsDeveloper())
                {
                    throw new ValidationException("对不起,您没有查看全部管理员的权限");
                }
                else
                {
                    data = GetRequiredService <IPrivilegeQuery>().GetPlistCatalogAccountTrs(input.Key.SafeTrim(),
                                                                                            input.CatalogCode, input.IncludeDescendants.Value, input);
                }
            }
            else
            {
                data = GetRequiredService <IPrivilegeQuery>().GetPlistCatalogAccountTrs(input.Key.SafeTrim(),
                                                                                        input.CatalogCode, input.IncludeDescendants.Value, input);
            }

            Debug.Assert(input.Total != null, "requestData.total != null");
            return(this.JsonResult(new MiniGrid <Dictionary <string, object> > {
                total = input.Total.Value, data = data
            }));
        }
コード例 #2
0
ファイル: AccountController.cs プロジェクト: zszqwe/anycmd
 public ActionResult GetAccountInfo()
 {
     if (AcSession.Identity.IsAuthenticated)
     {
         var account = AcSession.Account;
         return(this.JsonResult(new
         {
             isLogined = AcSession.Identity.IsAuthenticated,
             loginName = AcSession.IsDeveloper() ? string.Format("{0}(开发人员)", account.LoginName) : account.LoginName,
             wallpaper = string.Empty,
             backColor = string.Empty,
             menus = AcSession.AccountPrivilege.AuthorizedMenus.Cast <IMenu>().ToList().Select(m => new
             {
                 id = m.Id,
                 text = m.Name,
                 pid = m.ParentId,
                 url = m.Url,
                 img = m.Icon
             }),
             roles = AcSession.AccountPrivilege.Roles,
             groups = AcSession.AccountPrivilege.Groups
         }));
     }
     else
     {
         return(this.JsonResult(new ResponseData {
             success = false, msg = "对不起,您没有登录"
         }.Error()));
     }
 }
コード例 #3
0
        private IAcSession GetAcSessionByLoginName(IAcDomain acDomain, string loginName)
        {
            if (EmptyAcDomain.SingleInstance.Equals(acDomain))
            {
                return(AcSessionState.Empty);
            }
            var storage   = acDomain.GetRequiredService <IAcSessionStorage>();
            var acSession = storage.GetData(acDomain.Config.CurrentAcSessionCacheKey) as IAcSession;

            if (acSession != null)
            {
                return(acSession);
            }
            var account = AcSessionState.AcMethod.GetAccountByLoginName(acDomain, loginName);

            if (account == null)
            {
                return(AcSessionState.Empty);
            }
            var sessionEntity = AcSessionState.AcMethod.GetAcSessionEntity(acDomain, account.Id);

            if (sessionEntity != null)
            {
                if (!sessionEntity.IsAuthenticated)
                {
                    return(AcSessionState.Empty);
                }
                acSession = new AcSessionState(acDomain, sessionEntity);
            }
            else
            {
                // 使用账户标识作为会话标识会导致一个账户只有一个会话
                // TODO:支持账户和会话的一对多,为会话级的动态责任分离做准备
                var accountState    = AccountState.Create(account);
                var identity        = new AnycmdIdentity(account.LoginName);
                var acSessionEntity = new AcSession
                {
                    Id                 = account.Id,
                    AccountId          = account.Id,
                    AuthenticationType = identity.AuthenticationType,
                    Description        = null,
                    IsAuthenticated    = identity.IsAuthenticated,
                    IsEnabled          = 1,
                    LoginName          = account.LoginName
                };
                AcSessionState.AcMethod.AddAcSession(acDomain, acSessionEntity);
                acSession = new AcSessionState(acDomain, account.Id, accountState);
            }
            storage.SetData(acDomain.Config.CurrentAcSessionCacheKey, acSession);
            return(acSession);
        }
コード例 #4
0
        public IAcSession CreateSession(IAcSession subject, Guid sessionId, AccountState account)
        {
            var identity        = new AnycmdIdentity(account.LoginName);
            var acSessionEntity = new AcSession(sessionId)
            {
                AccountId          = account.Id,
                AuthenticationType = identity.AuthenticationType,
                Description        = null,
                IsAuthenticated    = identity.IsAuthenticated,
                IsEnabled          = 1,
                LoginName          = account.LoginName
            };

            AcSessionState.AcMethod.AddAcSession(_acDomain, acSessionEntity);

            return(new AcSessionState(_acDomain, sessionId, account));
        }
コード例 #5
0
ファイル: FunctionController.cs プロジェクト: zszqwe/anycmd
        public ActionResult Refresh()
        {
            var result = new ResponseData {
                success = true
            };

            if (!AcSession.IsDeveloper())
            {
                result.success = false;
                result.msg     = "对不起,您不是开发人员,不能执行本功能";
            }
            else
            {
                GetRequiredService <IFunctionListImport>().Import(AcDomain, AcSession, AcDomain.Config.SelfAppSystemCode);
            }

            return(this.JsonResult(result));
        }
コード例 #6
0
ファイル: AccountController.cs プロジェクト: zszqwe/anycmd
        public ActionResult GetPlistAccounts(GetPlistAccounts input)
        {
            if (!ModelState.IsValid)
            {
                return(ModelState.ToJsonResult());
            }
            foreach (var filter in input.Filters)
            {
                PropertyState property;
                if (!AcDomain.EntityTypeSet.TryGetProperty(base.EntityType, filter.field, out property))
                {
                    throw new ValidationException("意外的Account实体类型属性" + filter.field);
                }
            }
            input.IncludeDescendants = input.IncludeDescendants ?? false;
            List <DicReader> userAccountTrs = null;

            // 如果组织机构为空则需要检测是否是开发人员,因为只有开发人员才可以看到全部用户。目录为空表示查询全部目录。
            if (string.IsNullOrEmpty(input.CatalogCode))
            {
                if (!AcSession.IsDeveloper())
                {
                    throw new ValidationException("对不起,您没有查看全部账户的权限");
                }
                else
                {
                    userAccountTrs = GetRequiredService <IAccountQuery>().GetPlistAccountTrs(input.Filters, input.CatalogCode
                                                                                             , input.IncludeDescendants.Value, input);
                }
            }
            else
            {
                userAccountTrs = GetRequiredService <IAccountQuery>().GetPlistAccountTrs(input.Filters, input.CatalogCode
                                                                                         , input.IncludeDescendants.Value, input);
            }
            Debug.Assert(input.Total != null, "requestModel.total != null");
            var data = new MiniGrid <Dictionary <string, object> > {
                total = input.Total.Value, data = userAccountTrs
            };

            return(this.JsonResult(data));
        }
コード例 #7
0
        public IAcSession CreateSession(IAcSession subject, Guid sessionId, AccountState account)
        {
            var identity = new AnycmdIdentity(account.LoginName);
            var acSessionEntity = new AcSession
            {
                Id = sessionId,
                AccountId = account.Id,
                AuthenticationType = identity.AuthenticationType,
                Description = null,
                IsAuthenticated = identity.IsAuthenticated,
                IsEnabled = 1,
                LoginName = account.LoginName
            };
            AcSessionState.AcMethod.AddAcSession(_acDomain, acSessionEntity);

            return new AcSessionState(_acDomain, sessionId, account);
        }
コード例 #8
0
        private void DoSignIn(IAcDomain acDomain, Dictionary <string, object> args)
        {
            if (EmptyAcDomain.SingleInstance.Equals(acDomain))
            {
                return;
            }
            var loginName  = args.ContainsKey("loginName") ? (args["loginName"] ?? string.Empty).ToString() : string.Empty;
            var password   = args.ContainsKey("password") ? (args["password"] ?? string.Empty).ToString() : string.Empty;
            var rememberMe = args.ContainsKey("rememberMe") ? (args["rememberMe"] ?? string.Empty).ToString() : string.Empty;
            var passwordEncryptionService = acDomain.GetRequiredService <IPasswordEncryptionService>();

            if (string.IsNullOrEmpty(loginName) || string.IsNullOrEmpty(password))
            {
                throw new ValidationException("用户名和密码不能为空");
            }
            var addVisitingLogCommand = new AddVisitingLogCommand(AcSessionState.Empty)
            {
                IpAddress    = IpHelper.GetClientIp(),
                LoginName    = loginName,
                VisitedOn    = null,
                VisitOn      = DateTime.Now,
                Description  = "登录成功",
                ReasonPhrase = VisitState.LogOnFail.ToName(),
                StateCode    = (int)VisitState.LogOnFail
            };

            password = passwordEncryptionService.Encrypt(password);
            var account = AcSessionState.AcMethod.GetAccountByLoginName(acDomain, loginName);

            if (account == null)
            {
                addVisitingLogCommand.Description = "用户名错误";
                acDomain.MessageDispatcher.DispatchMessage(addVisitingLogCommand);
                throw new ValidationException(addVisitingLogCommand.Description);
            }
            else
            {
                addVisitingLogCommand.AccountId = account.Id;
            }
            if (password != account.Password)
            {
                addVisitingLogCommand.Description = "密码错误";
                acDomain.MessageDispatcher.DispatchMessage(addVisitingLogCommand);
                throw new ValidationException(addVisitingLogCommand.Description);
            }
            if (account.IsEnabled == 0)
            {
                addVisitingLogCommand.Description = "对不起,该账户已被禁用";
                acDomain.MessageDispatcher.DispatchMessage(addVisitingLogCommand);
                throw new ValidationException(addVisitingLogCommand.Description);
            }
            string       auditState = account.AuditState == null ? account.AuditState : account.AuditState.ToLower();
            CatalogState dicItem;

            if (!acDomain.CatalogSet.TryGetCatalog(auditState, out dicItem))
            {
                throw new AnycmdException("意外的字典编码" + auditState);
            }
            if (auditState == null ||
                auditState == "notaudit")
            {
                addVisitingLogCommand.Description = "对不起,该账户尚未审核";
                acDomain.MessageDispatcher.DispatchMessage(addVisitingLogCommand);
                throw new ValidationException(addVisitingLogCommand.Description);
            }
            if (auditState == "auditnotpass")
            {
                addVisitingLogCommand.Description = "对不起,该账户未通过审核";
                acDomain.MessageDispatcher.DispatchMessage(addVisitingLogCommand);
                throw new ValidationException(addVisitingLogCommand.Description);
            }
            if (account.AllowStartTime.HasValue && SystemTime.Now() < account.AllowStartTime.Value)
            {
                addVisitingLogCommand.Description = "对不起,该账户的允许登录开始时间还没到。请在" + account.AllowStartTime + "后登录";
                acDomain.MessageDispatcher.DispatchMessage(addVisitingLogCommand);
                throw new ValidationException(addVisitingLogCommand.Description);
            }
            if (account.AllowEndTime.HasValue && SystemTime.Now() > account.AllowEndTime.Value)
            {
                addVisitingLogCommand.Description = "对不起,该账户的允许登录时间已经过期";
                acDomain.MessageDispatcher.DispatchMessage(addVisitingLogCommand);
                throw new ValidationException(addVisitingLogCommand.Description);
            }
            if (account.LockEndTime.HasValue || account.LockStartTime.HasValue)
            {
                DateTime lockStartTime = account.LockStartTime ?? DateTime.MinValue;
                DateTime lockEndTime   = account.LockEndTime ?? DateTime.MaxValue;
                if (SystemTime.Now() > lockStartTime && SystemTime.Now() < lockEndTime)
                {
                    addVisitingLogCommand.Description = "对不起,该账户暂被锁定";
                    acDomain.MessageDispatcher.DispatchMessage(addVisitingLogCommand);
                    throw new ValidationException(addVisitingLogCommand.Description);
                }
            }

            if (account.PreviousLoginOn.HasValue && account.PreviousLoginOn.Value >= SystemTime.Now().AddMinutes(5))
            {
                addVisitingLogCommand.Description = "检测到您的上次登录时间在未来。这可能是因为本站点服务器的时间落后导致的,请联系管理员。";
                acDomain.MessageDispatcher.DispatchMessage(addVisitingLogCommand);
                throw new ValidationException(addVisitingLogCommand.Description);
            }
            account.PreviousLoginOn = SystemTime.Now();
            if (!account.FirstLoginOn.HasValue)
            {
                account.FirstLoginOn = SystemTime.Now();
            }
            account.LoginCount = (account.LoginCount ?? 0) + 1;
            account.IpAddress  = IpHelper.GetClientIp();

            // 使用账户标识作为会话标识会导致一个账户只有一个会话
            // TODO:支持账户和会话的一对多,为会话级的动态责任分离做准备
            var        sessionEntity = AcSessionState.AcMethod.GetAcSessionEntity(acDomain, account.Id);
            IAcSession acSession;

            if (sessionEntity != null)
            {
                acSession = new AcSessionState(acDomain, sessionEntity.Id, AccountState.Create(account));
                sessionEntity.IsAuthenticated = true;
                AcSessionState.AcMethod.UpdateAcSession(acDomain, sessionEntity);
            }
            else
            {
                var accountState    = AccountState.Create(account);
                var identity        = new AnycmdIdentity(account.LoginName);
                var acSessionEntity = new AcSession
                {
                    Id                 = account.Id,
                    AccountId          = account.Id,
                    AuthenticationType = identity.AuthenticationType,
                    Description        = null,
                    IsAuthenticated    = identity.IsAuthenticated,
                    IsEnabled          = 1,
                    LoginName          = account.LoginName
                };
                AcSessionState.AcMethod.AddAcSession(acDomain, acSessionEntity);
                acSession = new AcSessionState(acDomain, account.Id, accountState);
            }
            if (HttpContext.Current != null)
            {
                HttpContext.Current.User = acSession;
                bool createPersistentCookie = rememberMe.Equals("rememberMe", StringComparison.OrdinalIgnoreCase);
                FormsAuthentication.SetAuthCookie(account.LoginName, createPersistentCookie);
            }
            else
            {
                Thread.CurrentPrincipal = acSession;
            }
            Guid?visitingLogId = Guid.NewGuid();

            acSession.SetData("UserContext_Current_VisitingLogId", visitingLogId);
            acSession.SetData(acDomain.Config.CurrentAcSessionCacheKey, acSession);

            acDomain.EventBus.Publish(new AccountLoginedEvent(acSession, account));
            acDomain.EventBus.Commit();
            addVisitingLogCommand.StateCode    = (int)VisitState.Logged;
            addVisitingLogCommand.ReasonPhrase = VisitState.Logged.ToName();
            addVisitingLogCommand.Description  = "登录成功";
            acDomain.MessageDispatcher.DispatchMessage(addVisitingLogCommand);
        }
コード例 #9
0
 public ActionResult GetNodesByParentId(Guid?parentId)
 {
     if (parentId == Guid.Empty)
     {
         parentId = null;
     }
     if (!parentId.HasValue)
     {
         if (AcSession.IsDeveloper())
         {
             var nodeList = new List <CatalogMiniNode>();
             nodeList.AddRange(AcDomain.CatalogSet.Where(a => a != CatalogState.VirtualRoot && a.ParentCode == null).OrderBy(a => a.SortCode + a.CategoryCode.GetHashCode()).Select(a => new CatalogMiniNode
             {
                 CategoryCode = a.CategoryCode,
                 Code         = a.Code,
                 expanded     = false,
                 Id           = a.Id.ToString(),
                 isLeaf       = !AcDomain.CatalogSet.Any(o => a.Code.Equals(o.ParentCode, StringComparison.OrdinalIgnoreCase)),
                 Name         = a.Name,
                 ParentCode   = a.ParentCode,
                 ParentId     = a.Parent.Id.ToString(),
                 SortCode     = a.SortCode.ToString()
             }));
             return(this.JsonResult(nodeList));
         }
         else
         {
             var orgs = AcSession.AccountPrivilege.Catalogs;
             if (orgs != null && orgs.Count > 0)
             {
                 return(this.JsonResult(orgs.Select(org => new CatalogMiniNode
                 {
                     Code = org.Code ?? string.Empty,
                     Id = org.Id.ToString(),
                     Name = org.Name,
                     isLeaf = AcDomain.CatalogSet.All(o => !org.Code.Equals(o.ParentCode, StringComparison.OrdinalIgnoreCase))
                 })));
             }
             return(this.JsonResult(new List <CatalogMiniNode>()));
         }
     }
     else
     {
         var          pid = parentId.Value;
         CatalogState parentCatalog;
         if (!AcDomain.CatalogSet.TryGetCatalog(pid, out parentCatalog))
         {
             throw new ValidationException("意外的目录标识" + pid);
         }
         var nodeList = new List <CatalogMiniNode>();
         nodeList.AddRange(AcDomain.CatalogSet.Where(a => parentCatalog.Code.Equals(a.ParentCode, StringComparison.OrdinalIgnoreCase)).OrderBy(a => a.SortCode + a.CategoryCode.GetHashCode()).Select(a => new CatalogMiniNode
         {
             CategoryCode = a.CategoryCode,
             Code         = a.Code,
             expanded     = false,
             Id           = a.Id.ToString(),
             isLeaf       = !AcDomain.CatalogSet.Any(o => a.Code.Equals(o.ParentCode, StringComparison.OrdinalIgnoreCase)),
             Name         = a.Name,
             ParentCode   = a.ParentCode,
             ParentId     = a.Parent.Id.ToString(),
             SortCode     = a.SortCode.ToString()
         }));
         nodeList.AddRange(AcDomain.FunctionSet.Where(a => a.ResourceTypeId == pid).OrderBy(a => a.SortCode).Select(a => new CatalogMiniNode
         {
             CategoryCode = "operation",
             Code         = a.Code,
             expanded     = false,
             Id           = a.Id.ToString(),
             isLeaf       = true,
             Name         = string.Format("<span style='color:red;'>{0}</span>", a.Description),
             ParentCode   = parentCatalog.Code,
             ParentId     = pid.ToString(),
             SortCode     = a.SortCode.ToString()
         }));
         return(this.JsonResult(nodeList));
     }
 }
コード例 #10
0
 private IAcSession GetAcSessionByLoginName(IAcDomain acDomain, string loginName)
 {
     if (EmptyAcDomain.SingleInstance.Equals(acDomain))
     {
         return AcSessionState.Empty;
     }
     var storage = acDomain.GetRequiredService<IAcSessionStorage>();
     var acSession = storage.GetData(acDomain.Config.CurrentAcSessionCacheKey) as IAcSession;
     if (acSession != null) return acSession;
     var account = AcSessionState.AcMethod.GetAccountByLoginName(acDomain, loginName);
     if (account == null)
     {
         return AcSessionState.Empty;
     }
     var sessionEntity = AcSessionState.AcMethod.GetAcSessionEntity(acDomain, account.Id);
     if (sessionEntity != null)
     {
         if (!sessionEntity.IsAuthenticated)
         {
             return AcSessionState.Empty;
         }
         acSession = new AcSessionState(acDomain, sessionEntity);
     }
     else
     {
         // 使用账户标识作为会话标识会导致一个账户只有一个会话
         // TODO:支持账户和会话的一对多,为会话级的动态责任分离做准备
         var accountState = AccountState.Create(account);
         var identity = new AnycmdIdentity(account.LoginName);
         var acSessionEntity = new AcSession
         {
             Id = account.Id,
             AccountId = account.Id,
             AuthenticationType = identity.AuthenticationType,
             Description = null,
             IsAuthenticated = identity.IsAuthenticated,
             IsEnabled = 1,
             LoginName = account.LoginName
         };
         AcSessionState.AcMethod.AddAcSession(acDomain, acSessionEntity);
         acSession = new AcSessionState(acDomain, account.Id, accountState);
     }
     storage.SetData(acDomain.Config.CurrentAcSessionCacheKey, acSession);
     return acSession;
 }
コード例 #11
0
        private void DoSignIn(IAcDomain acDomain, Dictionary<string, object> args)
        {
            if (EmptyAcDomain.SingleInstance.Equals(acDomain))
            {
                return;
            }
            var loginName = args.ContainsKey("loginName") ? (args["loginName"] ?? string.Empty).ToString() : string.Empty;
            var password = args.ContainsKey("password") ? (args["password"] ?? string.Empty).ToString() : string.Empty;
            var rememberMe = args.ContainsKey("rememberMe") ? (args["rememberMe"] ?? string.Empty).ToString() : string.Empty;
            var passwordEncryptionService = acDomain.GetRequiredService<IPasswordEncryptionService>();
            if (string.IsNullOrEmpty(loginName) || string.IsNullOrEmpty(password))
            {
                throw new ValidationException("用户名和密码不能为空");
            }
            var addVisitingLogCommand = new AddVisitingLogCommand(AcSessionState.Empty)
            {
                IpAddress = IpHelper.GetClientIp(),
                LoginName = loginName,
                VisitedOn = null,
                VisitOn = DateTime.Now,
                Description = "登录成功",
                ReasonPhrase = VisitState.LogOnFail.ToName(),
                StateCode = (int)VisitState.LogOnFail
            };
            password = passwordEncryptionService.Encrypt(password);
            var account = AcSessionState.AcMethod.GetAccountByLoginName(acDomain, loginName);
            if (account == null)
            {
                addVisitingLogCommand.Description = "用户名错误";
                acDomain.MessageDispatcher.DispatchMessage(addVisitingLogCommand);
                throw new ValidationException(addVisitingLogCommand.Description);
            }
            else
            {
                addVisitingLogCommand.AccountId = account.Id;
            }
            if (password != account.Password)
            {
                addVisitingLogCommand.Description = "密码错误";
                acDomain.MessageDispatcher.DispatchMessage(addVisitingLogCommand);
                throw new ValidationException(addVisitingLogCommand.Description);
            }
            if (account.IsEnabled == 0)
            {
                addVisitingLogCommand.Description = "对不起,该账户已被禁用";
                acDomain.MessageDispatcher.DispatchMessage(addVisitingLogCommand);
                throw new ValidationException(addVisitingLogCommand.Description);
            }
            string auditState = account.AuditState == null ? account.AuditState : account.AuditState.ToLower();
            CatalogState dicItem;
            if (!acDomain.CatalogSet.TryGetCatalog(auditState, out dicItem))
            {
                throw new AnycmdException("意外的字典编码" + auditState);
            }
            if (auditState == null
                || auditState == "notaudit")
            {
                addVisitingLogCommand.Description = "对不起,该账户尚未审核";
                acDomain.MessageDispatcher.DispatchMessage(addVisitingLogCommand);
                throw new ValidationException(addVisitingLogCommand.Description);
            }
            if (auditState == "auditnotpass")
            {
                addVisitingLogCommand.Description = "对不起,该账户未通过审核";
                acDomain.MessageDispatcher.DispatchMessage(addVisitingLogCommand);
                throw new ValidationException(addVisitingLogCommand.Description);
            }
            if (account.AllowStartTime.HasValue && SystemTime.Now() < account.AllowStartTime.Value)
            {
                addVisitingLogCommand.Description = "对不起,该账户的允许登录开始时间还没到。请在" + account.AllowStartTime + "后登录";
                acDomain.MessageDispatcher.DispatchMessage(addVisitingLogCommand);
                throw new ValidationException(addVisitingLogCommand.Description);
            }
            if (account.AllowEndTime.HasValue && SystemTime.Now() > account.AllowEndTime.Value)
            {
                addVisitingLogCommand.Description = "对不起,该账户的允许登录时间已经过期";
                acDomain.MessageDispatcher.DispatchMessage(addVisitingLogCommand);
                throw new ValidationException(addVisitingLogCommand.Description);
            }
            if (account.LockEndTime.HasValue || account.LockStartTime.HasValue)
            {
                DateTime lockStartTime = account.LockStartTime ?? DateTime.MinValue;
                DateTime lockEndTime = account.LockEndTime ?? DateTime.MaxValue;
                if (SystemTime.Now() > lockStartTime && SystemTime.Now() < lockEndTime)
                {
                    addVisitingLogCommand.Description = "对不起,该账户暂被锁定";
                    acDomain.MessageDispatcher.DispatchMessage(addVisitingLogCommand);
                    throw new ValidationException(addVisitingLogCommand.Description);
                }
            }

            if (account.PreviousLoginOn.HasValue && account.PreviousLoginOn.Value >= SystemTime.Now().AddMinutes(5))
            {
                addVisitingLogCommand.Description = "检测到您的上次登录时间在未来。这可能是因为本站点服务器的时间落后导致的,请联系管理员。";
                acDomain.MessageDispatcher.DispatchMessage(addVisitingLogCommand);
                throw new ValidationException(addVisitingLogCommand.Description);
            }
            account.PreviousLoginOn = SystemTime.Now();
            if (!account.FirstLoginOn.HasValue)
            {
                account.FirstLoginOn = SystemTime.Now();
            }
            account.LoginCount = (account.LoginCount ?? 0) + 1;
            account.IpAddress = IpHelper.GetClientIp();

            // 使用账户标识作为会话标识会导致一个账户只有一个会话
            // TODO:支持账户和会话的一对多,为会话级的动态责任分离做准备
            var sessionEntity = AcSessionState.AcMethod.GetAcSessionEntity(acDomain, account.Id);
            IAcSession acSession;
            if (sessionEntity != null)
            {
                acSession = new AcSessionState(acDomain, sessionEntity.Id, AccountState.Create(account));
                sessionEntity.IsAuthenticated = true;
                AcSessionState.AcMethod.UpdateAcSession(acDomain, sessionEntity);
            }
            else
            {
                var accountState = AccountState.Create(account);
                var identity = new AnycmdIdentity(account.LoginName);
                var acSessionEntity = new AcSession
                {
                    Id = account.Id,
                    AccountId = account.Id,
                    AuthenticationType = identity.AuthenticationType,
                    Description = null,
                    IsAuthenticated = identity.IsAuthenticated,
                    IsEnabled = 1,
                    LoginName = account.LoginName
                };
                AcSessionState.AcMethod.AddAcSession(acDomain, acSessionEntity);
                acSession = new AcSessionState(acDomain, account.Id, accountState);
            }
            if (HttpContext.Current != null)
            {
                HttpContext.Current.User = acSession;
                bool createPersistentCookie = rememberMe.Equals("rememberMe", StringComparison.OrdinalIgnoreCase);
                FormsAuthentication.SetAuthCookie(account.LoginName, createPersistentCookie);
            }
            else
            {
                Thread.CurrentPrincipal = acSession;
            }
            Guid? visitingLogId = Guid.NewGuid();

            acSession.SetData("UserContext_Current_VisitingLogId", visitingLogId);
            acSession.SetData(acDomain.Config.CurrentAcSessionCacheKey, acSession);

            acDomain.EventBus.Publish(new AccountLoginedEvent(acSession, account));
            acDomain.EventBus.Commit();
            addVisitingLogCommand.StateCode = (int)VisitState.Logged;
            addVisitingLogCommand.ReasonPhrase = VisitState.Logged.ToName();
            addVisitingLogCommand.Description = "登录成功";
            acDomain.MessageDispatcher.DispatchMessage(addVisitingLogCommand);
        }