예제 #1
0
        public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
        {
            var cacheManager = IocManager.Instance.Resolve <ICacheManager>();
            var principal    = _tokenHandler.ValidateToken(securityToken, validationParameters, out validatedToken);

            if (!HasAccessTokenType(principal))
            {
                throw new SecurityTokenException("invalid token type");
            }

            AsyncHelper.RunSync(() => ValidateSecurityStampAsync(principal));

            var tokenValidityKeyClaim = principal.Claims.First(c => c.Type == AppConsts.TokenValidityKey);

            if (TokenValidityKeyExistsInCache(tokenValidityKeyClaim, cacheManager))
            {
                return(principal);
            }

            var userIdentifierString = principal.Claims.First(c => c.Type == AppConsts.UserIdentifier);
            var userIdentifier       = UserIdentifier.Parse(userIdentifierString.Value);

            if (!ValidateTokenValidityKey(tokenValidityKeyClaim, userIdentifier))
            {
                throw new SecurityTokenException("invalid");
            }

            var tokenAuthConfiguration = IocManager.Instance.Resolve <TokenAuthConfiguration>();

            cacheManager
            .GetCache(AppConsts.TokenValidityKey)
            .Set(tokenValidityKeyClaim.Value, "", absoluteExpireTime: tokenAuthConfiguration.AccessTokenExpiration);

            return(principal);
        }
예제 #2
0
        public async Task <RefreshTokenResult> RefreshToken(string refreshToken)
        {
            if (string.IsNullOrWhiteSpace(refreshToken))
            {
                throw new ArgumentNullException(nameof(refreshToken));
            }

            if (!IsRefreshTokenValid(refreshToken, out var principal))
            {
                throw new ValidationException("Refresh token is not valid!");
            }

            try
            {
                var user = _userManager.GetUser(UserIdentifier.Parse(principal.Claims.First(x => x.Type == AppConsts.UserIdentifier).Value));
                if (user == null)
                {
                    throw new UserFriendlyException("Unknown user or user identifier");
                }

                principal = await _claimsPrincipalFactory.CreateAsync(user);

                var accessToken = CreateAccessToken(await CreateJwtClaims(principal.Identity as ClaimsIdentity, user));

                return(await Task.FromResult(new RefreshTokenResult(accessToken, GetEncryptedAccessToken(accessToken), (int)_configuration.AccessTokenExpiration.TotalSeconds)));
            }
            catch (UserFriendlyException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new ValidationException("Refresh token is not valid!", e);
            }
        }
        public async Task <bool> Validate(ClaimsPrincipal claimsPrincipal)
        {
            if (claimsPrincipal?.Claims == null || !claimsPrincipal.Claims.Any())
            {
                return(false);
            }

            var securityStampKey = claimsPrincipal.Claims.FirstOrDefault(c => c.Type == AppConsts.SecurityStampKey);

            if (securityStampKey == null)
            {
                return(false);
            }

            var userIdentifierString = claimsPrincipal.Claims.First(c => c.Type == AppConsts.UserIdentifier);
            var userIdentifier       = UserIdentifier.Parse(userIdentifierString.Value);

            var isValid = await ValidateSecurityStampFromCache(userIdentifier, securityStampKey.Value);

            if (!isValid)
            {
                isValid = await ValidateSecurityStampFromDb(userIdentifier, securityStampKey.Value);
            }

            return(isValid);
        }
예제 #4
0
        public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
        {
            var cacheManager = IocManager.Instance.Resolve <ICacheManager>();

            // 解析验证当前请求的token
            var principal = _tokenHandler.ValidateToken(securityToken, validationParameters, out validatedToken);

            // 从解析的token中获取用户id和token校验值
            var userIdentifierString     = principal.Claims.First(c => c.Type == AbpProConsts.UserIdentifier);
            var tokenValidityKeyInClaims = principal.Claims.First(c => c.Type == AbpProConsts.TokenValidityKey);

            // 从缓存中获取是否存在以token校验值作为键的缓存
            var tokenValidityKeyInCache = cacheManager
                                          .GetCache(AbpProConsts.TokenValidityKey)
                                          .GetOrDefault(tokenValidityKeyInClaims.Value);

            // 缓存不为空则表示验证通过
            if (tokenValidityKeyInCache != null)
            {
                return(principal);
            }

            // 缓存为空则从用户关联的 UserToken 表中查询出
            // LoginProvider 值为 TokenValidityKeyProvider 并且 Name 值为 tokenValidityKeyInClaims.Value
            // 的token,判断是否符合校验条件
            using (var unitOfWorkManager = IocManager.Instance.ResolveAsDisposable <IUnitOfWorkManager>())
            {
                using (var uow = unitOfWorkManager.Object.Begin())
                {
                    var userIdentifier = UserIdentifier.Parse(userIdentifierString.Value);

                    using (unitOfWorkManager.Object.Current.SetTenantId(userIdentifier.TenantId))
                    {
                        using (var userManager = IocManager.Instance.ResolveAsDisposable <UserManager>())
                        {
                            var userManagerObject = userManager.Object;
                            var user = userManagerObject.GetUser(userIdentifier);
                            var isValidityKetValid = AsyncHelper.RunSync(() =>
                                                                         userManagerObject.IsTokenValidityKeyValidAsync(user, tokenValidityKeyInClaims.Value)
                                                                         );
                            uow.Complete();

                            // 符合校验条件加入缓存,下次访问走缓存速度更快
                            if (isValidityKetValid)
                            {
                                cacheManager
                                .GetCache(AbpProConsts.TokenValidityKey)
                                .Set(tokenValidityKeyInClaims.Value, "");

                                return(principal);
                            }
                        }
                    }

                    // 校验失败,抛出校验token失败异常
                    throw new SecurityTokenException("invalid");
                }
            }
        }
        public void GetHashCode_Test()
        {
            UserIdentifier.Parse("5@4").GetHashCode().ShouldBe(UserIdentifier.Parse("5@4").GetHashCode());

            UserIdentifier.Parse("1@1").GetHashCode().ShouldNotBe(UserIdentifier.Parse("2@2").GetHashCode());

            UserIdentifier.Parse("1@0").GetHashCode().ShouldNotBe(UserIdentifier.Parse("0@1").GetHashCode());

            UserIdentifier.Parse("1@2").GetHashCode().ShouldNotBe(UserIdentifier.Parse("2@1").GetHashCode());
        }
        public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
        {
            var cacheManager = IocManager.Instance.Resolve <ICacheManager>();

            var principal = _tokenHandler.ValidateToken(securityToken, validationParameters, out validatedToken);

            var userIdentifierString     = principal.Claims.First(c => c.Type == AppConsts.UserIdentifier);
            var tokenValidityKeyInClaims = principal.Claims.First(c => c.Type == AppConsts.TokenValidityKey);

            var tokenValidityKeyInCache = cacheManager
                                          .GetCache(AppConsts.TokenValidityKey)
                                          .GetOrDefault(tokenValidityKeyInClaims.Value);

            if (tokenValidityKeyInCache != null)
            {
                return(principal);
            }

            using (var unitOfWorkManager = IocManager.Instance.ResolveAsDisposable <IUnitOfWorkManager>())
            {
                using (var uow = unitOfWorkManager.Object.Begin())
                {
                    var userIdentifier = UserIdentifier.Parse(userIdentifierString.Value);

                    using (unitOfWorkManager.Object.Current.SetTenantId(userIdentifier.TenantId))
                    {
                        using (var userManager = IocManager.Instance.ResolveAsDisposable <UserManager>())
                        {
                            var userManagerObject = userManager.Object;
                            var user = userManagerObject.GetUser(userIdentifier);
                            var isValidityKetValid = AsyncHelper.RunSync(() =>
                                                                         userManagerObject.IsTokenValidityKeyValidAsync(user, tokenValidityKeyInClaims.Value)
                                                                         );
                            uow.Complete();

                            if (isValidityKetValid)
                            {
                                cacheManager
                                .GetCache(AppConsts.TokenValidityKey)
                                .Set(tokenValidityKeyInClaims.Value, "");

                                return(principal);
                            }
                        }
                    }

                    throw new SecurityTokenException("invalid");
                }
            }
        }
예제 #7
0
        /// <summary>
        /// 余额支付
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        protected async Task BalancePay(PayInput input)
        {
            var data = JsonConvert.DeserializeObject <JObject>(input.CustomData);
            var uid  = data["uid"]?.ToString();
            var log  = await CreateToPayTransactionInfo(input);

            if (data["key"]?.ToString() == "系统充值")
            {
                throw new UserFriendlyException("余额支付不支持此业务!");
            }

            var userIdentifer = UserIdentifier.Parse(uid);
            await UserManager.UpdateRechargeInfo(userIdentifer, (int)(-input.TotalAmount * 100));

            await _paymentCallbackManager.ExecuteCallback(data["key"]?.ToString(), log.OutTradeNo, log.TransactionId, (int)(input.TotalAmount * 100), data);
        }
예제 #8
0
        /// <summary>
        /// 执行回调逻辑
        /// </summary>
        /// <param name="key">支付业务关键字</param>
        /// <param name="outTradeNo">商户系统的订单号</param>
        /// <param name="totalFee">金额(单位:分)</param>
        /// <param name="transactionId">微信支付订单号</param>
        /// <param name="data">自定义数据</param>
        /// <returns></returns>
        public async Task ExecuteCallback(string key, string outTradeNo, string transactionId, int totalFee, JObject data)
        {
            Logger.Info("正在执行【" + key + "】回调逻辑。data:" + data?.ToJsonString());
            var userIdentifer = UserIdentifier.Parse(data?["uid"]?.ToString());

            using (AbpSession.Use(userIdentifer.TenantId, userIdentifer.UserId))
            {
                //更新交易日志
                await _transactionLogHelper.UpdateAsync(outTradeNo, transactionId, async (unitOfWork, loginfo) =>
                {
                    //TODO:金额比较
                    //if (loginfo.Currency.CurrencyValue == totalFee)
                    //{

                    //}
                    switch (key)
                    {
                    case "订单支付":
                        {
                            var orderCode = data?["code"]?.ToString();
                            //await _orderManager.UpdateOrderPayStatus(orderCode, totalFee);
                            break;
                        }

                    case "系统充值":
                        {
                            await UserManager.UpdateRechargeInfo(userIdentifer, totalFee);
                        }
                        break;

                    default:

                        break;
                    }
                });
            }
        }
예제 #9
0
        protected virtual async Task <UserIdentifier[]> GetUsers(NotificationInfo notificationInfo)
        {
            List <UserIdentifier> userIds;

            if (!notificationInfo.UserIds.IsNullOrEmpty())
            {
                //Directly get from UserIds
                userIds = notificationInfo
                          .UserIds
                          .Split(",")
                          .Select(uidAsStr => UserIdentifier.Parse(uidAsStr))
                          .Where(uid => SettingManager.GetSettingValueForUser <bool>(NotificationSettingNames.ReceiveNotifications, uid.TenantId, uid.UserId))
                          .ToList();
            }
            else
            {
                //Get subscribed users

                var tenantIds = GetTenantIds(notificationInfo);

                List <NotificationSubscriptionInfo> subscriptions;

                if (tenantIds.IsNullOrEmpty() ||
                    (tenantIds.Length == 1 && tenantIds[0] == NotificationInfo.AllTenantIds.To <int>()))
                {
                    //Get all subscribed users of all tenants
                    subscriptions = await _notificationStore.GetSubscriptionsAsync(
                        notificationInfo.NotificationName,
                        notificationInfo.EntityTypeName,
                        notificationInfo.EntityId
                        );
                }
                else
                {
                    //Get all subscribed users of specified tenant(s)
                    subscriptions = await _notificationStore.GetSubscriptionsAsync(
                        tenantIds,
                        notificationInfo.NotificationName,
                        notificationInfo.EntityTypeName,
                        notificationInfo.EntityId
                        );
                }

                //Remove invalid subscriptions
                var invalidSubscriptions = new Dictionary <Guid, NotificationSubscriptionInfo>();

                //TODO: Group subscriptions per tenant for potential performance improvement
                foreach (var subscription in subscriptions)
                {
                    using (CurrentUnitOfWork.SetTenantId(subscription.TenantId))
                    {
                        if (!await _notificationDefinitionManager.IsAvailableAsync(notificationInfo.NotificationName, new UserIdentifier(subscription.TenantId, subscription.UserId)) ||
                            !SettingManager.GetSettingValueForUser <bool>(NotificationSettingNames.ReceiveNotifications, subscription.TenantId, subscription.UserId))
                        {
                            invalidSubscriptions[subscription.Id] = subscription;
                        }
                    }
                }

                subscriptions.RemoveAll(s => invalidSubscriptions.ContainsKey(s.Id));

                //Get user ids
                userIds = subscriptions
                          .Select(s => new UserIdentifier(s.TenantId, s.UserId))
                          .ToList();
            }

            if (!notificationInfo.ExcludedUserIds.IsNullOrEmpty())
            {
                //Exclude specified users.
                var excludedUserIds = notificationInfo
                                      .ExcludedUserIds
                                      .Split(",")
                                      .Select(uidAsStr => UserIdentifier.Parse(uidAsStr))
                                      .ToList();

                userIds.RemoveAll(uid => excludedUserIds.Any(euid => euid.Equals(uid)));
            }

            return(userIds.ToArray());
        }
예제 #10
0
        public virtual async Task <bool> GetGranteddesignatedPermissionsAsync(long userId, string permissionName)
        {
            PermissionChecker.IsGranted(UserIdentifier.Parse(AbpClaimTypes.UserId), PermissionNames.Pages_Tenants);

            return(await _userManager.IsGrantedAsync(userId, permissionName));
        }
예제 #11
0
        public async Task<JsonResult> Authenticate([FromBody] AuthenticateModel model)
        { 
            //AuthenticateResultModel 返回的字典类型
            SortedDictionary<string, object> DgDict = new SortedDictionary<string, object>();
            //返回登录结果
            var loginResult = await GetLoginResultAsync(
                model.UserNameOrEmailAddress,
                model.Password,
                GetTenancyNameOrNull()
            );
            AbpClaimTypes.UserId = loginResult.User.Id.ToString();
            #region 角色列表版本  暂时没用
            DgDict.Add("permissionsToRolesVersion", 1001);
            #endregion
           
            #region 获取所有权限列表
            var Permissions = PermissionManager.GetAllPermissions();
            Treelist = new List<TreeClass>();
            TreeClass treeClass1 = new TreeClass();
            treeClass1.id = 1;
            treeClass1.parentId = 0;
            treeClass1.label = Mapper.Map<PermissionDto>(Permissions.Where(x => x.Name == PermissionNames.Pages_Staff).FirstOrDefault()).DisplayName;
            treeClass1.Permission = Mapper.Map<PermissionDto>(Permissions.Where(x => x.Name == PermissionNames.Pages_Staff).FirstOrDefault());           
            Treelist = Recursion(Permissions.Where(x => x.Name == PermissionNames.Pages_Staff).FirstOrDefault(), 1);
            Treelist.Add(treeClass1);
            DgDict.Add("allPermissions", new ListResultDto<PermissionDto>(
                ObjectMapper.Map<List<PermissionDto>>(Permissions)
            ));
            try
            { 
                DgDict.Add("allPermissionsForTree", Treelist);
            }
            catch (Exception ex)
            {

            }
            num = 1;
            //权限列表
            List<Permission> allPermissions = new List<Permission>();
            foreach (var item in Permissions)
            {
                allPermissions.Add(item);
            }
            #endregion
           
            #region 角色列表
            //var allRoles = await _roleRepository.GetAllListAsync();
            var allRoleIReadOnlyList = await _roleRepository.GetAllListAsync();
            List<Role> allRoles = new List<Role>();
            foreach (var item in allRoleIReadOnlyList.Where(x=>x.IsDeleted==false).ToList())
            {
                allRoles.Add(item);
            }
            DgDict.Add("allRoles", Mapper.Map<List<RoleListDto>>(allRoles));
            //DgDict.Add("allRoles", new ListResultDto<RoleListDto>(ObjectMapper.Map<List<RoleListDto>>(allRoles)));

            //new ListResultDto<RoleListDto>(ObjectMapper.Map<List<RoleListDto>>(allRoles));

            #endregion
            //获取登录用户的所拥有的所有权限
            var grantedPermissionNames = new List<string>();
            if (loginResult.User.Id>0)
            {
                foreach (var permissionName in allPermissions)
                {
                   Abp.UserIdentifier Identifier=UserIdentifier.Parse(loginResult.User.Id.ToString());
                    if (await PermissionChecker.IsGrantedAsync(Identifier, permissionName.Name))
                    {
                        grantedPermissionNames.Add(permissionName.Name);  // 获取当前用户的权限
                    }
                }
            }
          
            #region  是否有审核权 canAssignInspectionToOther
            bool canAssignInspectionToOther = await PermissionChecker.IsGrantedAsync(UserIdentifier.Parse(loginResult.User.Id.ToString()), PermissionNames.Pages_Inspection);
            if (!canAssignInspectionToOther)
            {
                DgDict.Add("canAssignInspectionToOther", "没有Pages_Inspection");
                DgDict.Add("canAssignInspectionToOtherValue", false);
            }
            else
            {
                DgDict.Add("canAssignInspectionToOther", "拥有Pages_Inspection");
                DgDict.Add("canAssignInspectionToOtherValue", true);
            }
            #endregion

            bool canAssignRolesFromAdmin = await PermissionChecker.IsGrantedAsync(UserIdentifier.Parse(loginResult.User.Id.ToString()), PermissionNames.Pages_Tenants);
            bool canAssignRolesFromRQAdmin = await PermissionChecker.IsGrantedAsync(UserIdentifier.Parse(loginResult.User.Id.ToString()), PermissionNames.Pages_Admin);
            bool canAssignRolesFromRQAssitant = await PermissionChecker.IsGrantedAsync(UserIdentifier.Parse(loginResult.User.Id.ToString()), PermissionNames.Pages_RQAssitant);
 
            #region 可分配角色列表--针对员工管理

            List<Role> RolescanAssigned = allRoles;
            List<string> RolescanAssignedString = new List<string>();//角色名数组初始化
            foreach (var item in allRoleIReadOnlyList.Where(x => x.IsDeleted == false).ToList())
            {
                RolescanAssignedString.Add(item.Name);
            }
            //如果任务已经分配且未分配给自己,且不具有分配任务权限,则抛出异常
            if (canAssignRolesFromAdmin) 
            {
                List<Role> allmyRoles = new List<Role>();//当前用户可分配的角色 初始化
                string[] outAdmin = { "Admin"};
                foreach (var item in outAdmin)
                {
                    if (RolescanAssignedString.Contains(item))
                    {
                        RolescanAssignedString.Remove(item);
                    }  //item.SetNormalizedName in
                }
                foreach (var itemStr in RolescanAssignedString)
                {
                    foreach (var item in allRoles)
                    {
                        if (item.Name == itemStr)
                        {
                            allmyRoles.Add(item);
                        }
                    }
                }
                DgDict.Add("RolescanAssigned", Mapper.Map<List<RoleDto>>(allmyRoles));
            }
            else if (canAssignRolesFromRQAdmin)
            {
                List<Role> allmyRoles = new List<Role>();//当前用户可分配的角色 初始化
                string[] outAdmin = { "Admin","RQAdmin","RQAdminPermissions"};
                foreach (var item in outAdmin)
                {
                    if (RolescanAssignedString.Contains(item))
                    {
                        RolescanAssignedString.Remove(item);
                    }  //item.SetNormalizedName in
                }
                foreach (var itemStr in RolescanAssignedString)
                {
                    foreach (var item in allRoles)
                    {
                        if (item.Name == itemStr)
                        {
                            allmyRoles.Add(item);
                        }
                    }
                }
                DgDict.Add("RolescanAssigned", Mapper.Map<List<RoleDto>>(allmyRoles));

            }
            else if (canAssignRolesFromRQAssitant)
            {
                string[] outAdmin = { "Admin", "RQAssitantPermissions",
                    "RQAdmin" , "RQAssitant" ,"RQAdminPermissions"};
                List<Role> allmyRoles = new List<Role>();//当前用户可分配的角色 初始化
                foreach (var item in outAdmin)
                {
                    if (RolescanAssignedString.Contains(item))
                    {
                        RolescanAssignedString.Remove(item);
                    }  //item.SetNormalizedName in
                }
                foreach (var itemStr in RolescanAssignedString)
                {
                    foreach (var item in allRoles)
                    {
                        if (item.Name == itemStr)
                        {
                            allmyRoles.Add(item);
                        }
                    }
                }
                DgDict.Add("RolescanAssigned", Mapper.Map<List<RoleDto>>(allmyRoles));

            }
            else
            { 
                DgDict.Add("RolescanAssigned", null);
            }
            #endregion
            
            #region 可分配权限列表【角色管理-分配权限】
            var PermissionscanAssigned = allPermissions;
            List<string> PermissionscanAssignedString = new List<string>();
            foreach (var item in PermissionscanAssigned)
            {
                PermissionscanAssignedString.Add(item.Name);
            }

            if (canAssignRolesFromAdmin) 
            {
                DgDict.Add("PermissionscanAssigned", Mapper.Map<List<PermissionDto>>(PermissionscanAssigned));
            }
            else if (canAssignRolesFromRQAdmin)
            {
                List<Permission> allMyPermission = new List<Permission>();//当前用户可分配的权限 初始化
                string[] outAdmin = {"Pages","Pages.Tenants",
                    "Pages.Users", "Pages.Roles", "Pages.Admin",
                    "Pages.Admin.Users","Pages.Admin.Roles"
                };
                foreach (var item in outAdmin)
                {
                    if (PermissionscanAssignedString.Contains(item))
                    {
                        PermissionscanAssignedString.Remove(item);
                    }  
                }
                foreach (var itemStr in PermissionscanAssignedString)
                {
                    foreach (var item in PermissionscanAssigned)
                    {
                        if (item.Name == itemStr)
                        {
                            allMyPermission.Add(item);
                        }
                    }
                }
                DgDict.Add("PermissionscanAssigned", Mapper.Map<List<PermissionDto>>(allMyPermission));

            }
            else if (canAssignRolesFromRQAssitant)
            {
                List<Permission> allMyPermission = new List<Permission>();//当前用户可分配的权限 初始化
                string[] outAdmin = {"Pages","Pages.Tenants",
                    "Pages.Users", "Pages.Roles", "Pages.Admin",
                    "Pages.Admin.Users","Pages.Admin.Roles",
                    "Pages.RQAssitant.Roles", "Pages.RQAssitant.Users",
                    "Pages.RQAssitant"
                };
                foreach (var item in outAdmin)
                {
                    if (PermissionscanAssignedString.Contains(item))
                    {
                        PermissionscanAssignedString.Remove(item);
                    }
                }
                foreach (var itemStr in PermissionscanAssignedString)
                {
                    foreach (var item in PermissionscanAssigned)
                    {
                        if (item.Name == itemStr)
                        {
                            allMyPermission.Add(item);
                        }
                    }
                }
                DgDict.Add("PermissionscanAssigned", Mapper.Map<List<PermissionDto>>(allMyPermission));

            }
            else
            {
                DgDict.Add("PermissionscanAssigned", null);
            }

            #endregion
            
            #region 登录返回UserId-accessToken--EncryptedAccessToken-ExpireInSeconds
            var accessToken = CreateAccessToken(CreateJwtClaims(loginResult.Identity));
            DgDict.Add("AuthenticateResultModel",
                   new AuthenticateResultModel
                   {
                       AccessToken = accessToken,
                       EncryptedAccessToken = GetEncrpyedAccessToken(accessToken),
                       ExpireInSeconds = (int)_configuration.Expiration.TotalSeconds,
                       UserId = loginResult.User.Id
                   }
                );
            #endregion

            return Json(DgDict);
        }
예제 #12
0
        protected virtual async Task <UserIdentifier[]> GetUsers(PushRequest request)
        {
            var userIds = new List <UserIdentifier>();

            if (request.UserIds.IsNullOrEmpty())
            {
                //Get subscribed users

                List <PushRequestSubscription> subscriptions;

                if (request.TenantIds.IsNullOrWhiteSpace() ||
                    request.TenantIds.Trim() == PushRequest.AllTenantIdsString)
                {
                    //Get all subscribed users of all tenants
                    subscriptions = await RequestStore.GetSubscriptionsAsync(
                        request.Name,
                        request.EntityTypeName,
                        request.EntityId
                        );
                }
                else
                {
                    var tenantIds = PushRequest.GetTenantIds(request.TenantIds);

                    //Get all subscribed users of specified tenant(s)
                    subscriptions = await RequestStore.GetSubscriptionsAsync(
                        tenantIds,
                        request.Name,
                        request.EntityTypeName,
                        request.EntityId
                        );
                }

                //Remove invalid subscriptions
                var invalidSubscriptions = new Dictionary <Guid, PushRequestSubscription>();

                var subscriptionGroups = subscriptions.GroupBy(s => s.TenantId);
                foreach (var subscriptionGroup in subscriptionGroups)
                {
                    using (CurrentUnitOfWork.SetTenantId(subscriptionGroup.Key))
                    {
                        foreach (var subscription in subscriptionGroup)
                        {
                            if (!await DefinitionManager.IsAvailableAsync(request.Name, new UserIdentifier(subscription.TenantId, subscription.UserId)) ||
                                // TODO: exclude system push request from checking user setting
                                !SettingManager.GetSettingValueForUser <bool>(AbpPushSettingNames.Receive, subscription.TenantId, subscription.UserId))
                            {
                                invalidSubscriptions[subscription.Id] = subscription;
                            }
                        }
                    }
                }

                subscriptions.RemoveAll(s => invalidSubscriptions.ContainsKey(s.Id));

                //Get user ids
                userIds = subscriptions
                          .Select(s => new UserIdentifier(s.TenantId, s.UserId))
                          .ToList();
            }
            else
            {
                //Directly get from UserIds
                userIds = request
                          .UserIds
                          .Split(",")
                          .Select(uidAsStr => UserIdentifier.Parse(uidAsStr))
                          // TODO: exclude system push request from checking user setting
                          .Where(uid => SettingManager.GetSettingValueForUser <bool>(AbpPushSettingNames.Receive, uid.TenantId, uid.UserId))
                          .ToList();
            }

            if (!request.ExcludedUserIds.IsNullOrEmpty())
            {
                //Exclude specified users.
                var excludedUserIds = request
                                      .ExcludedUserIds
                                      .Split(",")
                                      .Select(uidAsStr => UserIdentifier.Parse(uidAsStr))
                                      .ToList();

                userIds.RemoveAll(uid => excludedUserIds.Any(euid => euid.Equals(uid)));
            }

            return(userIds.ToArray());
        }