示例#1
0
        public virtual async Task BindAsync(LoginInput input)
        {
            await CheckBindPolicyAsync();

            var miniProgram = await _miniProgramRepository.GetAsync(x => x.AppId == input.AppId);

            var loginResult = await GetLoginResultAsync(miniProgram, input);

            await _identityOptions.SetAsync();

            if (await _identityUserManager.FindByLoginAsync(loginResult.LoginProvider, loginResult.ProviderKey) != null)
            {
                throw new WechatAccountHasBeenBoundException();
            }

            var identityUser = await _identityUserManager.GetByIdAsync(CurrentUser.GetId());

            (await _identityUserManager.AddLoginAsync(identityUser,
                                                      new UserLoginInfo(loginResult.LoginProvider, loginResult.ProviderKey,
                                                                        WeChatManagementCommonConsts.WeChatUserLoginInfoDisplayName))).CheckErrors();

            await UpdateMiniProgramUserAsync(identityUser, miniProgram, loginResult.Code2SessionResponse.UnionId,
                                             loginResult.Code2SessionResponse.OpenId, loginResult.Code2SessionResponse.SessionKey);

            await UpdateUserInfoAsync(identityUser, input.UserInfo);
        }
示例#2
0
        /// <summary>
        /// 通过微信开放能力获取并给当前用户绑定手机号,更新信息:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="BusinessException"></exception>
        /// <exception cref="AbpIdentityResultException"></exception>
        public async Task BindPhoneNumberAsync(BindPhoneNumberInput input)
        {
            await _identityOptions.SetAsync();

            var user = await _identityUserManager.GetByIdAsync(CurrentUser.GetId());

            var miniProgram = await _miniProgramRepository.GetAsync(x => x.AppId == input.AppId);

            var response = await _loginService.Code2SessionAsync(miniProgram.AppId, miniProgram.AppSecret, input.Code);

            if (response.ErrorCode != 0)
            {
                throw new BusinessException(message: $"WeChat error: [{response.ErrorCode}]: {response.ErrorMessage}");
            }

            var decryptedData = _jsonSerializer.Deserialize <Dictionary <string, object> >(AesHelper
                                                                                           .AesDecrypt(input.EncryptedData, input.Iv, response.SessionKey));

            var phoneNumber = decryptedData["phoneNumber"] as string;

            _identityUserManager.RegisterTokenProvider(TokenOptions.DefaultPhoneProvider,
                                                       new StaticPhoneNumberTokenProvider());

            var token = await _identityUserManager.GenerateChangePhoneNumberTokenAsync(user, phoneNumber);

            var identityResult = await _identityUserManager.ChangePhoneNumberAsync(user, phoneNumber, token);

            if (!identityResult.Succeeded)
            {
                throw new AbpIdentityResultException(identityResult);
            }
        }
示例#3
0
        public virtual async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
            await _identityOptions.SetAsync();

            var appId   = context.Request.Raw.Get("appid");
            var openId  = context.Request.Raw.Get("openid");
            var unionId = context.Request.Raw.Get("unionid");

            if (string.IsNullOrWhiteSpace(appId))
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant)
                {
                    ErrorDescription = "请提供有效的 appid"
                };

                return;
            }

            if (string.IsNullOrWhiteSpace(openId))
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant)
                {
                    ErrorDescription = "微信服务器没有提供有效的 openid"
                };

                return;
            }

            var miniProgram = await _miniProgramRepository.GetAsync(x => x.AppId == appId);

            string loginProvider;
            string providerKey;

            if (unionId.IsNullOrWhiteSpace())
            {
                loginProvider = await _miniProgramLoginProviderProvider.GetAppLoginProviderAsync(miniProgram);

                providerKey = openId;
            }
            else
            {
                loginProvider = await _miniProgramLoginProviderProvider.GetOpenLoginProviderAsync(miniProgram);

                providerKey = unionId;
            }

            var identityUser = await _identityUserManager.FindByLoginAsync(loginProvider, providerKey);

            var claims = new List <Claim>
            {
                // 记录 appid
                new Claim("appid", appId)
            };

            claims.AddRange(identityUser.Claims.Select(item => new Claim(item.ClaimType, item.ClaimValue)));

            context.Result = new GrantValidationResult(identityUser.Id.ToString(), GrantType, claims);
        }
示例#4
0
        protected virtual async Task <LoginResultInfoModel> GetLoginResultAsync(LoginInput input)
        {
            var tenantId      = CurrentTenant.Id;
            var tenantChanged = false;

            MiniProgram miniProgram;

            if (input.LookupUseRecentlyTenant)
            {
                using (_dataFilter.Disable <IMultiTenant>())
                {
                    miniProgram = await _miniProgramRepository.FirstOrDefaultAsync(x => x.AppId == input.AppId);
                }
            }
            else
            {
                miniProgram = await _miniProgramRepository.GetAsync(x => x.AppId == input.AppId);
            }

            var code2SessionResponse =
                await _loginService.Code2SessionAsync(miniProgram.AppId, miniProgram.AppSecret, input.Code);

            _signatureChecker.Check(input.RawData, code2SessionResponse.SessionKey, input.Signature);

            var openId  = code2SessionResponse.OpenId;
            var unionId = code2SessionResponse.UnionId;

            if (input.LookupUseRecentlyTenant)
            {
                using (_dataFilter.Disable <IMultiTenant>())
                {
                    tenantId = await _miniProgramUserRepository.FindRecentlyTenantIdAsync(input.AppId, openId, true);
                }

                if (tenantId != CurrentTenant.Id)
                {
                    tenantChanged = true;
                }
            }

            using var tenantChange = CurrentTenant.Change(tenantId);

            if (tenantChanged)
            {
                miniProgram = await _miniProgramRepository.GetAsync(x => x.AppId == input.AppId);
            }

            // 如果 auth.code2Session 没有返回用户的 UnionId
            if (unionId.IsNullOrWhiteSpace())
            {
                if (!input.EncryptedData.IsNullOrWhiteSpace() && !input.Iv.IsNullOrWhiteSpace())
                {
                    // 方法1:通过 EncryptedData 和 Iv 解密获得用户的 UnionId
                    var decryptedData =
                        _jsonSerializer.Deserialize <Dictionary <string, object> >(
                            AesHelper.AesDecrypt(input.EncryptedData, input.Iv, code2SessionResponse.SessionKey));

                    unionId = decryptedData.GetOrDefault("unionId") as string;
                }
                else
                {
                    // 方法2:尝试通过 OpenId 在 MiniProgramUser 实体中查找用户的 UnionId
                    // Todo: should use IMiniProgramUserStore
                    unionId = await _miniProgramUserRepository.FindUnionIdByOpenIdAsync(miniProgram.Id, openId);
                }
            }

            string loginProvider;
            string providerKey;

            if (unionId.IsNullOrWhiteSpace())
            {
                loginProvider = await _miniProgramLoginProviderProvider.GetAppLoginProviderAsync(miniProgram);

                providerKey = openId;
            }
            else
            {
                loginProvider = await _miniProgramLoginProviderProvider.GetOpenLoginProviderAsync(miniProgram);

                providerKey = unionId;
            }
            return(new LoginResultInfoModel
            {
                MiniProgram = miniProgram,
                LoginProvider = loginProvider,
                ProviderKey = providerKey,
                UnionId = unionId,
                Code2SessionResponse = code2SessionResponse
            });
        }
        protected virtual async Task <LoginResultInfoModel> GetLoginResultAsync(LoginInput input)
        {
            var tenantId      = CurrentTenant.Id;
            var tenantChanged = false;

            MiniProgram miniProgram;

            if (input.LookupUseRecentlyTenant)
            {
                using (_dataFilter.Disable <IMultiTenant>())
                {
                    miniProgram = await _miniProgramRepository.FirstOrDefaultAsync(x => x.AppId == input.AppId);
                }
            }
            else
            {
                miniProgram = await _miniProgramRepository.GetAsync(x => x.AppId == input.AppId);
            }

            var code2SessionResponse =
                await _loginService.Code2SessionAsync(miniProgram.AppId, miniProgram.AppSecret, input.Code);

            var openId  = code2SessionResponse.OpenId;
            var unionId = code2SessionResponse.UnionId;

            if (input.LookupUseRecentlyTenant)
            {
                using (_dataFilter.Disable <IMultiTenant>())
                {
                    tenantId = await _miniProgramUserRepository.FindRecentlyTenantIdAsync(input.AppId, openId, true);
                }

                if (tenantId != CurrentTenant.Id)
                {
                    tenantChanged = true;
                }
            }

            using var tenantChange = CurrentTenant.Change(tenantId);

            if (tenantChanged)
            {
                miniProgram = await _miniProgramRepository.GetAsync(x => x.AppId == input.AppId);
            }

            string loginProvider;
            string providerKey;

            if (!unionId.IsNullOrWhiteSpace())
            {
                loginProvider = await _miniProgramLoginProviderProvider.GetOpenLoginProviderAsync(miniProgram);

                providerKey = unionId;
            }
            else
            {
                loginProvider = await _miniProgramLoginProviderProvider.GetAppLoginProviderAsync(miniProgram);

                providerKey = openId;
            }
            return(new LoginResultInfoModel
            {
                MiniProgram = miniProgram,
                LoginProvider = loginProvider,
                ProviderKey = providerKey,
                UnionId = unionId,
                Code2SessionResponse = code2SessionResponse
            });
        }
        public virtual async Task <string> LoginAsync(LoginInput input)
        {
            var miniProgram = await _miniProgramRepository.GetAsync(x => x.AppId == input.AppId);

            var code2SessionResponse =
                await _loginService.Code2SessionAsync(miniProgram.AppId, miniProgram.AppSecret, input.Code);

            _signatureChecker.Check(input.RawData, code2SessionResponse.SessionKey, input.Signature);

            var openId  = code2SessionResponse.OpenId;
            var unionId = code2SessionResponse.UnionId;

            if (input.LookupUseRecentlyTenant)
            {
                Guid?tenantId;

                using (_dataFilter.Disable <IMultiTenant>())
                {
                    tenantId = await _miniProgramUserRepository.FindRecentlyTenantIdAsync(miniProgram.Id, openId);
                }

                using var tenantChange = CurrentTenant.Change(tenantId);
            }

            string loginProvider;
            string providerKey;

            // 如果 auth.code2Session 没有返回用户的 UnionId
            if (unionId.IsNullOrWhiteSpace())
            {
                if (!input.EncryptedData.IsNullOrWhiteSpace() && !input.Iv.IsNullOrWhiteSpace())
                {
                    // 方法1:通过 EncryptedData 和 Iv 解密获得用户的 UnionId
                    var decryptedData =
                        _jsonSerializer.Deserialize <Dictionary <string, object> >(
                            AesHelper.AesDecrypt(input.EncryptedData, input.Iv, code2SessionResponse.SessionKey));

                    unionId = decryptedData.GetOrDefault("unionId") as string;
                }
                else
                {
                    // 方法2:尝试通过 OpenId 在 MiniProgramUser 实体中查找用户的 UnionId
                    // Todo: should use IMiniProgramUserStore
                    unionId = await _miniProgramUserRepository.FindUnionIdByOpenIdAsync(miniProgram.Id, openId);
                }
            }

            if (unionId.IsNullOrWhiteSpace())
            {
                loginProvider = await _miniProgramLoginProviderProvider.GetAppLoginProviderAsync(miniProgram);

                providerKey = openId;
            }
            else
            {
                loginProvider = await _miniProgramLoginProviderProvider.GetOpenLoginProviderAsync(miniProgram);

                providerKey = unionId;
            }

            var identityUser = await _identityUserManager.FindByLoginAsync(loginProvider, providerKey) ??
                               await _miniProgramLoginNewUserCreator.CreateAsync(input.UserInfo, loginProvider, providerKey);

            await UpdateMiniProgramUserAsync(identityUser, miniProgram, unionId, openId, code2SessionResponse.SessionKey);
            await UpdateUserInfoAsync(identityUser, input.UserInfo);

            return((await RequestIds4LoginAsync(input.AppId, unionId, openId))?.Raw);
        }