From ba4c8cb15629aa88b5dcfa986bc0cf8f05b49b05 Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Thu, 6 Oct 2022 11:39:36 +0800 Subject: [PATCH] remove useless modules --- .../FodyWeavers.xml | 3 - .../FodyWeavers.xsd | 30 -- .../LINGYUN.Abp.IdentityServer.QQ.csproj | 19 - .../QQ/AbpIdentityServerQQConsts.cs | 8 - .../QQ/AbpIdentityServerQQModule.cs | 19 - .../Abp/IdentityServer/QQ/AbpQQClaimTypes.cs | 31 -- .../QQ/QQConnectOAuthHandler.cs | 175 --------- .../QQ/QQConnectOAuthOptions.cs | 47 --- .../QQAuthenticationExtensions.cs | 63 ---- .../System/BytesExtensions.cs | 16 - .../System/StringExtensions.cs | 17 - .../System/Text/Json/JsonElementExtensions.cs | 63 ---- .../FodyWeavers.xml | 3 - .../FodyWeavers.xsd | 30 -- .../LINGYUN.Abp.IdentityServer.WeChat.csproj | 26 -- .../WeChat/AbpIdentityServerWeChatModule.cs | 56 --- .../WeChat/IWeChatResourceDataSeeder.cs | 9 - .../WeChat/Localization/en.json | 12 - .../WeChat/Localization/zh-Hans.json | 12 - .../WeChatMiniProgramGrantValidator.cs | 75 ---- .../WeChatMiniProgramProfileService.cs | 67 ---- .../Official/WeChatOfficialGrantValidator.cs | 75 ---- .../Official/WeChatOfficialOAuthConsts.cs | 71 ---- .../WeChatOfficialSignatureMiddleware.cs | 77 ---- .../WeChat/WeChatGrantValidator.cs | 242 ------------- .../WeChat/WeChatResourceDataSeeder.cs | 86 ----- .../Official/WeChatOfficialOAuthHandler.cs | 336 ------------------ .../Official/WeChatOfficialOAuthOptions.cs | 47 --- .../Official/WeChatOfficialStateCacheItem.cs | 18 - .../WeChatAuthenticationExtensions.cs | 65 ---- ...ntityServerApplicationBuilderExtensions.cs | 22 -- .../System/BytesExtensions.cs | 16 - .../System/StringExtensions.cs | 17 - .../System/Text/Json/JsonElementExtensions.cs | 63 ---- 34 files changed, 1916 deletions(-) delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/FodyWeavers.xml delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/FodyWeavers.xsd delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/LINGYUN.Abp.IdentityServer.QQ.csproj delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/LINGYUN/Abp/IdentityServer/QQ/AbpIdentityServerQQConsts.cs delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/LINGYUN/Abp/IdentityServer/QQ/AbpIdentityServerQQModule.cs delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/LINGYUN/Abp/IdentityServer/QQ/AbpQQClaimTypes.cs delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/Microsoft/AspNetCore/Authentication/QQ/QQConnectOAuthHandler.cs delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/Microsoft/AspNetCore/Authentication/QQ/QQConnectOAuthOptions.cs delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/Microsoft/AspNetCore/Authentication/QQAuthenticationExtensions.cs delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/System/BytesExtensions.cs delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/System/StringExtensions.cs delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/System/Text/Json/JsonElementExtensions.cs delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/FodyWeavers.xml delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/FodyWeavers.xsd delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN.Abp.IdentityServer.WeChat.csproj delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/AbpIdentityServerWeChatModule.cs delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/IWeChatResourceDataSeeder.cs delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Localization/en.json delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Localization/zh-Hans.json delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/MiniProgram/WeChatMiniProgramGrantValidator.cs delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/MiniProgram/WeChatMiniProgramProfileService.cs delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Official/WeChatOfficialGrantValidator.cs delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Official/WeChatOfficialOAuthConsts.cs delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Official/WeChatOfficialSignatureMiddleware.cs delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/WeChatGrantValidator.cs delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/WeChatResourceDataSeeder.cs delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialOAuthHandler.cs delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialOAuthOptions.cs delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialStateCacheItem.cs delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/Microsoft/AspNetCore/Authentication/WeChatAuthenticationExtensions.cs delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/Microsoft/AspNetCore/Builder/IdentityServerApplicationBuilderExtensions.cs delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/System/BytesExtensions.cs delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/System/StringExtensions.cs delete mode 100644 aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/System/Text/Json/JsonElementExtensions.cs diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/FodyWeavers.xml b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/FodyWeavers.xml deleted file mode 100644 index 1715698cc..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/FodyWeavers.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/FodyWeavers.xsd b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/FodyWeavers.xsd deleted file mode 100644 index 11da52550..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/FodyWeavers.xsd +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. - - - - - A comma-separated list of error codes that can be safely ignored in assembly verification. - - - - - 'false' to turn off automatic generation of the XML Schema file. - - - - - \ No newline at end of file diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/LINGYUN.Abp.IdentityServer.QQ.csproj b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/LINGYUN.Abp.IdentityServer.QQ.csproj deleted file mode 100644 index e60fad65e..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/LINGYUN.Abp.IdentityServer.QQ.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - net6.0 - - - - - - - - - - - - diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/LINGYUN/Abp/IdentityServer/QQ/AbpIdentityServerQQConsts.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/LINGYUN/Abp/IdentityServer/QQ/AbpIdentityServerQQConsts.cs deleted file mode 100644 index 5ce20e964..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/LINGYUN/Abp/IdentityServer/QQ/AbpIdentityServerQQConsts.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace LINGYUN.Abp.IdentityServer.QQ; - -public static class AbpIdentityServerQQConsts -{ - public static string AuthenticationScheme { get; set; } = "QQ Connect"; - public static string DisplayName { get; set; } = "QQ Connect"; - public static string CallbackPath { get; set; } = "/signin-qq"; -} diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/LINGYUN/Abp/IdentityServer/QQ/AbpIdentityServerQQModule.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/LINGYUN/Abp/IdentityServer/QQ/AbpIdentityServerQQModule.cs deleted file mode 100644 index e57f4672a..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/LINGYUN/Abp/IdentityServer/QQ/AbpIdentityServerQQModule.cs +++ /dev/null @@ -1,19 +0,0 @@ -using LINGYUN.Abp.Tencent.QQ; -using Microsoft.AspNetCore.Authentication; -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.IdentityServer; -using Volo.Abp.Modularity; - -namespace LINGYUN.Abp.IdentityServer.QQ; - -[DependsOn(typeof(AbpTencentQQModule))] -[DependsOn(typeof(AbpIdentityServerDomainModule))] -public class AbpIdentityServerQQModule : AbpModule -{ - public override void ConfigureServices(ServiceConfigurationContext context) - { - context.Services - .AddAuthentication() - .AddQQConnect(); - } -} \ No newline at end of file diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/LINGYUN/Abp/IdentityServer/QQ/AbpQQClaimTypes.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/LINGYUN/Abp/IdentityServer/QQ/AbpQQClaimTypes.cs deleted file mode 100644 index 9b293b931..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/LINGYUN/Abp/IdentityServer/QQ/AbpQQClaimTypes.cs +++ /dev/null @@ -1,31 +0,0 @@ -namespace LINGYUN.Abp.WeChat.Security.Claims -{ - /// - /// QQ互联身份类型,可以像 自行配置 - ///
- /// See: - ///
- public class AbpQQClaimTypes - { - /// - /// 用户的唯一标识 - /// - public static string OpenId { get; set; } = "qq-openid"; // 可变更 - /// - /// 用户昵称 - /// - public static string NickName { get; set; } = "nickname"; - /// - /// 性别。 如果获取不到则默认返回"男" - /// - public static string Gender { get; set; } = "gender"; - /// - /// 用户头像, 取自字段: figureurl_qq_1 - /// - /// - /// 根据QQ互联文档, 40x40的头像是一定会存在的, 只取40x40的头像 - /// see: https://wiki.connect.qq.com/get_user_info - /// - public static string AvatarUrl { get; set; } = "avatar"; - } -} diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/Microsoft/AspNetCore/Authentication/QQ/QQConnectOAuthHandler.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/Microsoft/AspNetCore/Authentication/QQ/QQConnectOAuthHandler.cs deleted file mode 100644 index 2876decbb..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/Microsoft/AspNetCore/Authentication/QQ/QQConnectOAuthHandler.cs +++ /dev/null @@ -1,175 +0,0 @@ -using LINGYUN.Abp.Tencent.QQ; -using LINGYUN.Abp.WeChat.Security.Claims; -using Microsoft.AspNetCore.Authentication.OAuth; -using Microsoft.AspNetCore.WebUtilities; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Security.Claims; -using System.Text.Encodings.Web; -using System.Text.Json; -using System.Threading.Tasks; - -namespace Microsoft.AspNetCore.Authentication.QQ -{ - /// - /// QQ互联实现 - /// - public class QQConnectOAuthHandler : OAuthHandler - { - protected AbpTencentQQOptionsFactory TencentQQOptionsFactory { get; } - public QQConnectOAuthHandler( - IOptionsMonitor options, - AbpTencentQQOptionsFactory tencentQQOptionsFactory, - ILoggerFactory logger, - UrlEncoder encoder, - ISystemClock clock) - : base(options, logger, encoder, clock) - { - TencentQQOptionsFactory = tencentQQOptionsFactory; - } - - protected override async Task InitializeHandlerAsync() - { - var options = await TencentQQOptionsFactory.CreateAsync(); - - // 用配置项重写 - Options.ClientId = options.AppId; - Options.ClientSecret = options.AppKey; - Options.IsMobile = options.IsMobile; - - await base.InitializeHandlerAsync(); - } - - /// - /// 构建用户授权地址 - /// - protected override string BuildChallengeUrl(AuthenticationProperties properties, string redirectUri) - { - var challengeUrl = base.BuildChallengeUrl(properties, redirectUri); - if (Options.IsMobile) - { - challengeUrl += "&display=mobile"; - } - return challengeUrl; - } - - /// - /// code换取access_token - /// - protected override async Task ExchangeCodeAsync(OAuthCodeExchangeContext context) - { - var address = QueryHelpers.AddQueryString(Options.TokenEndpoint, new Dictionary() - { - { "client_id", Options.ClientId }, - { "redirect_uri", context.RedirectUri }, - { "client_secret", Options.ClientSecret}, - { "code", context.Code}, - { "grant_type","authorization_code"} - }); - - var response = await Backchannel.GetAsync(address); - if (!response.IsSuccessStatusCode) - { - Logger.LogError("An error occurred while retrieving an access token: the remote server " + - "returned a {Status} response with the following payload: {Headers} {Body}.", - /* Status: */ response.StatusCode, - /* Headers: */ response.Headers.ToString(), - /* Body: */ await response.Content.ReadAsStringAsync()); - - return OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token.")); - } - - var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync()); - if (!string.IsNullOrEmpty(payload.GetRootString("errcode"))) - { - Logger.LogError("An error occurred while retrieving an access token: the remote server " + - "returned a {Status} response with the following payload: {Headers} {Body}.", - /* Status: */ response.StatusCode, - /* Headers: */ response.Headers.ToString(), - /* Body: */ await response.Content.ReadAsStringAsync()); - - return OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token.")); - } - return OAuthTokenResponse.Success(payload); - } - - protected override async Task CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) - { - var openIdEndpoint = Options.OpenIdEndpoint + "?access_token=" + tokens.AccessToken + "&fmt=json"; - var openIdResponse = await Backchannel.GetAsync(openIdEndpoint, Context.RequestAborted); - openIdResponse.EnsureSuccessStatusCode(); - - var openIdPayload = JsonDocument.Parse(await openIdResponse.Content.ReadAsStringAsync()); - var openId = openIdPayload.GetRootString("openid"); - - identity.AddClaim(new Claim(AbpQQClaimTypes.OpenId, openId, ClaimValueTypes.String, Options.ClaimsIssuer)); - - var address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, new Dictionary - { - {"oauth_consumer_key", Options.ClientId}, - {"access_token", tokens.AccessToken}, - {"openid", openId} - }); - - var response = await Backchannel.GetAsync(address); - if (!response.IsSuccessStatusCode) - { - Logger.LogError("An error occurred while retrieving the user profile: the remote server " + - "returned a {Status} response with the following payload: {Headers} {Body}.", - /* Status: */ response.StatusCode, - /* Headers: */ response.Headers.ToString(), - /* Body: */ await response.Content.ReadAsStringAsync()); - - throw new HttpRequestException("An error occurred while retrieving user information."); - } - - var userInfoPayload = JsonDocument.Parse(await response.Content.ReadAsStringAsync()); - var errorCode = userInfoPayload.GetRootString("ret"); - if (!"0".Equals(errorCode)) - { - // See: https://wiki.connect.qq.com/%e5%85%ac%e5%85%b1%e8%bf%94%e5%9b%9e%e7%a0%81%e8%af%b4%e6%98%8e - Logger.LogError("An error occurred while retrieving the user profile: the remote server " + - "returned code {Code} response with message: {Message}.", - errorCode, - userInfoPayload.GetRootString("msg")); - - throw new HttpRequestException("An error occurred while retrieving user information."); - } - - var nickName = userInfoPayload.GetRootString("nickname"); - if (!nickName.IsNullOrWhiteSpace()) - { - identity.AddClaim(new Claim(AbpQQClaimTypes.NickName, nickName, ClaimValueTypes.String, Options.ClaimsIssuer)); - } - var gender = userInfoPayload.GetRootString("gender"); - if (!gender.IsNullOrWhiteSpace()) - { - identity.AddClaim(new Claim(AbpQQClaimTypes.Gender, gender, ClaimValueTypes.String, Options.ClaimsIssuer)); - } - var avatarUrl = userInfoPayload.GetRootString("figureurl_qq_1"); - if (!avatarUrl.IsNullOrWhiteSpace()) - { - identity.AddClaim(new Claim(AbpQQClaimTypes.AvatarUrl, avatarUrl, ClaimValueTypes.String, Options.ClaimsIssuer)); - } - - var context = new OAuthCreatingTicketContext( - new ClaimsPrincipal(identity), - properties, - Context, - Scheme, - Options, - Backchannel, - tokens, - userInfoPayload.RootElement); - - context.RunClaimActions(); - - await Events.CreatingTicket(context); - - return new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name); - } - } -} \ No newline at end of file diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/Microsoft/AspNetCore/Authentication/QQ/QQConnectOAuthOptions.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/Microsoft/AspNetCore/Authentication/QQ/QQConnectOAuthOptions.cs deleted file mode 100644 index b650bc517..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/Microsoft/AspNetCore/Authentication/QQ/QQConnectOAuthOptions.cs +++ /dev/null @@ -1,47 +0,0 @@ -using LINGYUN.Abp.IdentityServer.QQ; -using LINGYUN.Abp.WeChat.Security.Claims; -using Microsoft.AspNetCore.Authentication.OAuth; -using Microsoft.AspNetCore.Http; -using System.Security.Claims; - -namespace Microsoft.AspNetCore.Authentication.QQ -{ - public class QQConnectOAuthOptions : OAuthOptions - { - /// - /// 是否移动端样式 - /// - public bool IsMobile { get; set; } - /// - /// 获取用户OpenID_OAuth2.0 - /// - public string OpenIdEndpoint { get; set; } - - public QQConnectOAuthOptions() - { - // 用于防止初始化错误,会在OAuthHandler.InitializeHandlerAsync中进行重写 - ClientId = "QQConnect"; - ClientSecret = "QQConnect"; - - ClaimsIssuer = "connect.qq.com"; - CallbackPath = new PathString(AbpIdentityServerQQConsts.CallbackPath); - - AuthorizationEndpoint = "https://graph.qq.com/oauth2.0/authorize"; - TokenEndpoint = "https://graph.qq.com/oauth2.0/token"; - OpenIdEndpoint = "https://graph.qq.com/oauth2.0/me"; - UserInformationEndpoint = "https://graph.qq.com/user/get_user_info"; - - Scope.Add("get_user_info"); - - // 这个原始的属性一定要写进去,框架关联判断是否绑定QQ - ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "openid"); - ClaimActions.MapJsonKey(ClaimTypes.Name, "nickname"); - - // 把自定义的身份标识写进令牌 - ClaimActions.MapJsonKey(AbpQQClaimTypes.OpenId, "openid"); - ClaimActions.MapJsonKey(AbpQQClaimTypes.NickName, "nickname"); - ClaimActions.MapJsonKey(AbpQQClaimTypes.Gender, "gender"); - ClaimActions.MapJsonKey(AbpQQClaimTypes.AvatarUrl, "figureurl_qq_1"); - } - } -} diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/Microsoft/AspNetCore/Authentication/QQAuthenticationExtensions.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/Microsoft/AspNetCore/Authentication/QQAuthenticationExtensions.cs deleted file mode 100644 index a748fa99c..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/Microsoft/AspNetCore/Authentication/QQAuthenticationExtensions.cs +++ /dev/null @@ -1,63 +0,0 @@ -using LINGYUN.Abp.IdentityServer.QQ; -using Microsoft.AspNetCore.Authentication.QQ; -using Microsoft.Extensions.DependencyInjection; -using System; - -namespace Microsoft.AspNetCore.Authentication -{ - public static class QQAuthenticationExtensions - { - /// - /// - public static AuthenticationBuilder AddQQConnect( - this AuthenticationBuilder builder) - { - return builder - .AddQQConnect( - AbpIdentityServerQQConsts.AuthenticationScheme, - AbpIdentityServerQQConsts.DisplayName, - options => { }); - } - - /// - /// - public static AuthenticationBuilder AddQQConnect( - this AuthenticationBuilder builder, - Action configureOptions) - { - return builder - .AddQQConnect( - AbpIdentityServerQQConsts.AuthenticationScheme, - configureOptions); - } - - /// - /// - public static AuthenticationBuilder AddQQConnect( - this AuthenticationBuilder builder, - string authenticationScheme, - Action configureOptions) - { - return builder - .AddQQConnect( - authenticationScheme, - AbpIdentityServerQQConsts.DisplayName, - configureOptions); - } - - /// - /// - public static AuthenticationBuilder AddQQConnect( - this AuthenticationBuilder builder, - string authenticationScheme, - string displayName, - Action configureOptions) - { - return builder - .AddOAuth( - authenticationScheme, - displayName, - configureOptions); - } - } -} diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/System/BytesExtensions.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/System/BytesExtensions.cs deleted file mode 100644 index d1bad7915..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/System/BytesExtensions.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Security.Cryptography; - -namespace System -{ - internal static class BytesExtensions - { - public static byte[] Sha1(this byte[] data) - { - using (var sha = SHA1.Create()) - { - var hashBytes = sha.ComputeHash(data); - return hashBytes; - } - } - } -} diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/System/StringExtensions.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/System/StringExtensions.cs deleted file mode 100644 index a8eb40c27..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/System/StringExtensions.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Security.Cryptography; -using System.Text; - -namespace System -{ - internal static class StringExtensions - { - public static byte[] Sha1(this string str) - { - using (var sha = SHA1.Create()) - { - var hashBytes = sha.ComputeHash(Encoding.ASCII.GetBytes(str)); - return hashBytes; - } - } - } -} diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/System/Text/Json/JsonElementExtensions.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/System/Text/Json/JsonElementExtensions.cs deleted file mode 100644 index 653a868ac..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.QQ/System/Text/Json/JsonElementExtensions.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System.Collections.Generic; - -namespace System.Text.Json -{ - internal static class JsonElementExtensions - { - public static IEnumerable GetRootStrings(this JsonDocument json, string key) - { - return json.RootElement.GetStrings(key); - } - - public static IEnumerable GetStrings(this JsonElement json, string key) - { - var result = new List(); - - if (json.TryGetProperty(key, out JsonElement property) && property.ValueKind == JsonValueKind.Array) - { - foreach (var jsonProp in property.EnumerateArray()) - { - result.Add(jsonProp.GetString()); - } - } - - return result; - } - - public static string GetRootString(this JsonDocument json, string key, string defaultValue = "") - { - if (json.RootElement.TryGetProperty(key, out JsonElement property)) - { - return property.GetString(); - } - return defaultValue; - } - - public static string GetString(this JsonElement json, string key, string defaultValue = "") - { - if (json.TryGetProperty(key, out JsonElement property)) - { - return property.GetString(); - } - return defaultValue; - } - - public static int GetRootInt32(this JsonDocument json, string key, int defaultValue = 0) - { - if (json.RootElement.TryGetProperty(key, out JsonElement property) && property.TryGetInt32(out int value)) - { - return value; - } - return defaultValue; - } - - public static int GetInt32(this JsonElement json, string key, int defaultValue = 0) - { - if (json.TryGetProperty(key, out JsonElement property) && property.TryGetInt32(out int value)) - { - return value; - } - return defaultValue; - } - } -} diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/FodyWeavers.xml b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/FodyWeavers.xml deleted file mode 100644 index 1715698cc..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/FodyWeavers.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/FodyWeavers.xsd b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/FodyWeavers.xsd deleted file mode 100644 index 11da52550..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/FodyWeavers.xsd +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. - - - - - A comma-separated list of error codes that can be safely ignored in assembly verification. - - - - - 'false' to turn off automatic generation of the XML Schema file. - - - - - \ No newline at end of file diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN.Abp.IdentityServer.WeChat.csproj b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN.Abp.IdentityServer.WeChat.csproj deleted file mode 100644 index 2276e916a..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN.Abp.IdentityServer.WeChat.csproj +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - net6.0 - - - - - - - - - - - - - - - - - - - diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/AbpIdentityServerWeChatModule.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/AbpIdentityServerWeChatModule.cs deleted file mode 100644 index cb4621c31..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/AbpIdentityServerWeChatModule.cs +++ /dev/null @@ -1,56 +0,0 @@ -using LINGYUN.Abp.Identity.WeChat; -using LINGYUN.Abp.IdentityServer.WeChat.MiniProgram; -using LINGYUN.Abp.IdentityServer.WeChat.Official; -using LINGYUN.Abp.WeChat.MiniProgram; -using LINGYUN.Abp.WeChat.Official; -using Microsoft.AspNetCore.Authentication; -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.IdentityServer; -using Volo.Abp.IdentityServer.Localization; -using Volo.Abp.Localization; -using Volo.Abp.Modularity; -using Volo.Abp.VirtualFileSystem; - -namespace LINGYUN.Abp.IdentityServer.WeChat -{ - [DependsOn( - typeof(AbpWeChatOfficialModule), - typeof(AbpWeChatMiniProgramModule), - typeof(AbpIdentityWeChatModule), - typeof(AbpIdentityServerDomainModule))] - public class AbpIdentityServerWeChatModule : AbpModule - { - public override void PreConfigureServices(ServiceConfigurationContext context) - { - var configuration = context.Services.GetConfiguration(); - - PreConfigure(builder => - { - builder.AddProfileService(); - - // TODO: 两个类型不通用配置项,不然只需要一个 - builder.AddExtensionGrantValidator(); - builder.AddExtensionGrantValidator(); - }); - } - - public override void ConfigureServices(ServiceConfigurationContext context) - { - Configure(options => - { - options.FileSets.AddEmbedded(); - }); - - Configure(options => - { - options.Resources - .Get() - .AddVirtualJson("/LINGYUN/Abp/IdentityServer/WeChat/Localization"); - }); - - context.Services - .AddAuthentication() - .AddWeChat(); - } - } -} diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/IWeChatResourceDataSeeder.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/IWeChatResourceDataSeeder.cs deleted file mode 100644 index 38d591d26..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/IWeChatResourceDataSeeder.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Threading.Tasks; - -namespace LINGYUN.Abp.IdentityServer -{ - public interface IWeChatResourceDataSeeder - { - Task CreateStandardResourcesAsync(); - } -} diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Localization/en.json b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Localization/en.json deleted file mode 100644 index 2f8fdd3b4..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Localization/en.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "culture": "en", - "texts": { - "MiniProgramAuthorizationDisabledMessage": "Applet authorization is not enabled for the application", - "OfficialAuthorizationDisabledMessage": "Official authorization is not enabled for the application", - "SelfRegistrationDisabledMessage": "Self-registration is disabled for this application. Please contact the application administrator to register a new user.", - "InvalidGrant:GrantTypeInvalid": "The type of authorization that is not allowed!", - "InvalidGrant:WeChatTokenInvalid": "WeChat authentication failed!", - "InvalidGrant:WeChatCodeNotFound": "The code obtained when WeChat is logged in is empty or does not exist!", - "InvalidGrant:WeChatNotRegister": "User WeChat account not registed!" - } -} \ No newline at end of file diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Localization/zh-Hans.json b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Localization/zh-Hans.json deleted file mode 100644 index b07fdf6f7..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Localization/zh-Hans.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "culture": "zh-Hans", - "texts": { - "MiniProgramAuthorizationDisabledMessage": "应用程序未开放小程序授权", - "OfficialAuthorizationDisabledMessage": "应用程序未开放公众平台授权", - "SelfRegistrationDisabledMessage": "应用程序未开放注册,请联系管理员添加新用户.", - "InvalidGrant:GrantTypeInvalid": "不被允许的授权类型!", - "InvalidGrant:WeChatTokenInvalid": "微信认证失败!", - "InvalidGrant:WeChatCodeNotFound": "微信登录时获取的 code 为空或不存在!", - "InvalidGrant:WeChatNotRegister": "用户微信账号未绑定!" - } -} \ No newline at end of file diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/MiniProgram/WeChatMiniProgramGrantValidator.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/MiniProgram/WeChatMiniProgramGrantValidator.cs deleted file mode 100644 index f94c6ec66..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/MiniProgram/WeChatMiniProgramGrantValidator.cs +++ /dev/null @@ -1,75 +0,0 @@ -using IdentityServer4.Models; -using IdentityServer4.Services; -using IdentityServer4.Validation; -using LINGYUN.Abp.WeChat.Localization; -using LINGYUN.Abp.WeChat.MiniProgram; -using LINGYUN.Abp.WeChat.MiniProgram.Features; -using LINGYUN.Abp.WeChat.OpenId; -using Microsoft.AspNetCore.Identity; -using Microsoft.Extensions.Localization; -using System.Threading.Tasks; -using Volo.Abp.Features; -using Volo.Abp.Identity; -using Volo.Abp.IdentityServer.Localization; -using IdentityUser = Volo.Abp.Identity.IdentityUser; - -namespace LINGYUN.Abp.IdentityServer.WeChat.MiniProgram -{ - /// - /// 对于小程序绑定用户的扩展授权验证器 - /// - public class WeChatMiniProgramGrantValidator : WeChatGrantValidator - { - public override string GrantType => AbpWeChatMiniProgramConsts.GrantType; - - public override string LoginProvider => AbpWeChatMiniProgramConsts.ProviderName; - - public override string AuthenticationMethod => AbpWeChatMiniProgramConsts.AuthenticationMethod; - - protected AbpWeChatMiniProgramOptionsFactory MiniProgramOptionsFactory { get; } - - protected IFeatureChecker FeatureChecker => ServiceProvider.LazyGetRequiredService(); - - public WeChatMiniProgramGrantValidator( - IEventService eventService, - IWeChatOpenIdFinder weChatOpenIdFinder, - UserManager userManager, - IIdentityUserRepository userRepository, - IdentitySecurityLogManager identitySecurityLogManager, - IStringLocalizer identityLocalizer, - IStringLocalizer identityServerLocalizer, - IStringLocalizer wechatLocalizer, - AbpWeChatMiniProgramOptionsFactory miniProgramOptionsFactory) - : base( - eventService, - weChatOpenIdFinder, - userManager, - userRepository, - identitySecurityLogManager, - wechatLocalizer, - identityLocalizer, - identityServerLocalizer) - { - MiniProgramOptionsFactory = miniProgramOptionsFactory; - } - - protected override async Task CheckFeatureAsync(ExtensionGrantValidationContext context) - { - if (!await FeatureChecker.IsEnabledAsync(WeChatMiniProgramFeatures.EnableAuthorization)) - { - context.Result = new GrantValidationResult( - TokenRequestErrors.InvalidGrant, - WeChatLocalizer["MiniProgramAuthorizationDisabledMessage"]); - return false; - } - return true; - } - - protected override async Task FindOpenIdAsync(string code) - { - var options = await MiniProgramOptionsFactory.CreateAsync(); - - return await WeChatOpenIdFinder.FindAsync(code, options.AppId, options.AppSecret); - } - } -} diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/MiniProgram/WeChatMiniProgramProfileService.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/MiniProgram/WeChatMiniProgramProfileService.cs deleted file mode 100644 index baedda606..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/MiniProgram/WeChatMiniProgramProfileService.cs +++ /dev/null @@ -1,67 +0,0 @@ -using IdentityServer4.AspNetIdentity; -using IdentityServer4.Models; -using LINGYUN.Abp.WeChat.Security.Claims; -using Microsoft.AspNetCore.Identity; -using System.Linq; -using System.Security.Principal; -using System.Threading.Tasks; -using Volo.Abp.Identity; -using Volo.Abp.MultiTenancy; -using Volo.Abp.Uow; -using IdentityUser = Volo.Abp.Identity.IdentityUser; - -namespace LINGYUN.Abp.IdentityServer.WeChat.MiniProgram -{ - public class WeChatMiniProgramProfileService : ProfileService - { - protected ICurrentTenant CurrentTenant { get; } - public WeChatMiniProgramProfileService( - IdentityUserManager userManager, - IUserClaimsPrincipalFactory claimsFactory, - ICurrentTenant currentTenant) - : base(userManager, claimsFactory) - { - CurrentTenant = currentTenant; - } - - [UnitOfWork] - public override async Task GetProfileDataAsync(ProfileDataRequestContext context) - { - using (CurrentTenant.Change(context.Subject.FindTenantId())) - { - await base.GetProfileDataAsync(context); - - // TODO: 可以从令牌获取openid, 安全性呢? - TryAddWeChatClaim(context, AbpWeChatClaimTypes.OpenId); - TryAddWeChatClaim(context, AbpWeChatClaimTypes.UnionId); - } - } - - [UnitOfWork] - public override async Task IsActiveAsync(IsActiveContext context) - { - using (CurrentTenant.Change(context.Subject.FindTenantId())) - { - await base.IsActiveAsync(context); - } - } - - [UnitOfWork] - public override Task IsUserActiveAsync(IdentityUser user) - { - return Task.FromResult(user.IsActive); - } - - protected virtual void TryAddWeChatClaim(ProfileDataRequestContext context, string weChatClaimType) - { - if (context.RequestedClaimTypes.Any(rc => rc.Contains(weChatClaimType))) - { - var weChatClaim = context.Subject.FindFirst(weChatClaimType); - if (weChatClaim != null) - { - context.IssuedClaims.Add(weChatClaim); - } - } - } - } -} diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Official/WeChatOfficialGrantValidator.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Official/WeChatOfficialGrantValidator.cs deleted file mode 100644 index fb6117f24..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Official/WeChatOfficialGrantValidator.cs +++ /dev/null @@ -1,75 +0,0 @@ -using IdentityServer4.Models; -using IdentityServer4.Services; -using IdentityServer4.Validation; -using LINGYUN.Abp.WeChat.Localization; -using LINGYUN.Abp.WeChat.Official; -using LINGYUN.Abp.WeChat.Official.Features; -using LINGYUN.Abp.WeChat.OpenId; -using Microsoft.AspNetCore.Identity; -using Microsoft.Extensions.Localization; -using System.Threading.Tasks; -using Volo.Abp.Features; -using Volo.Abp.Identity; -using Volo.Abp.IdentityServer.Localization; -using IdentityUser = Volo.Abp.Identity.IdentityUser; - -namespace LINGYUN.Abp.IdentityServer.WeChat.Official -{ - /// - /// 对于公众平台绑定用户的扩展授权验证器 - /// - public class WeChatOfficialGrantValidator : WeChatGrantValidator - { - public override string GrantType => AbpWeChatOfficialConsts.GrantType; - - public override string LoginProvider => AbpWeChatOfficialConsts.ProviderName; - - public override string AuthenticationMethod => AbpWeChatOfficialConsts.AuthenticationMethod; - - protected AbpWeChatOfficialOptionsFactory WeChatOfficialOptionsFactory { get; } - - protected IFeatureChecker FeatureChecker => ServiceProvider.LazyGetRequiredService(); - - public WeChatOfficialGrantValidator( - IEventService eventService, - IWeChatOpenIdFinder weChatOpenIdFinder, - UserManager userManager, - IIdentityUserRepository userRepository, - IdentitySecurityLogManager identitySecurityLogManager, - IStringLocalizer identityLocalizer, - IStringLocalizer identityServerLocalizer, - IStringLocalizer wechatLocalizer, - AbpWeChatOfficialOptionsFactory weChatOfficialOptionsFactory) - : base( - eventService, - weChatOpenIdFinder, - userManager, - userRepository, - identitySecurityLogManager, - wechatLocalizer, - identityLocalizer, - identityServerLocalizer) - { - WeChatOfficialOptionsFactory = weChatOfficialOptionsFactory; - } - - protected override async Task CheckFeatureAsync(ExtensionGrantValidationContext context) - { - if (!await FeatureChecker.IsEnabledAsync(WeChatOfficialFeatures.EnableAuthorization)) - { - context.Result = new GrantValidationResult( - TokenRequestErrors.InvalidGrant, - WeChatLocalizer["OfficialAuthorizationDisabledMessage"]); - return false; - } - return true; - } - - protected override async Task FindOpenIdAsync(string code) - { - var options = await WeChatOfficialOptionsFactory.CreateAsync(); - - return await WeChatOpenIdFinder.FindAsync(code, options.AppId, options.AppSecret); - } - } -} diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Official/WeChatOfficialOAuthConsts.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Official/WeChatOfficialOAuthConsts.cs deleted file mode 100644 index d4c3bb108..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Official/WeChatOfficialOAuthConsts.cs +++ /dev/null @@ -1,71 +0,0 @@ -using LINGYUN.Abp.WeChat; -using LINGYUN.Abp.WeChat.Official; - -namespace LINGYUN.Abp.IdentityServer.WeChat.Official -{ - /// - /// 与微信公众号认证相关的静态(可变)常量 - /// - public static class WeChatOfficialOAuthConsts - { - /// - /// 微信个人信息标识 - /// - public static string ProfileKey { get; set; } = "wechat.profile"; - /// - /// 微信提供者标识 - /// - public static string ProviderKey => AbpWeChatOfficialConsts.ProviderName; - /// - /// 微信提供者显示名称 - /// - public static string DisplayName => AbpWeChatGlobalConsts.DisplayName; - /// - /// 回调地址 - /// - public static string CallbackPath { get; set; } = "/signin-wechat"; - - /// - /// 微信客户端外的网页登录 - /// - public const string QrConnectEndpoint = "https://open.weixin.qq.com/connect/qrconnect"; - - /// - /// 微信客户端内的网页登录 - /// - public const string AuthorizationEndpoint = "https://open.weixin.qq.com/connect/oauth2/authorize"; - - /// - /// 用户允许授权后通过返回的code换取access_token地址 - /// - public const string TokenEndpoint = "https://api.weixin.qq.com/sns/oauth2/access_token"; - - /// - /// 使用access_token获取用户个人信息地址 - /// - public const string UserInformationEndpoint = "https://api.weixin.qq.com/sns/userinfo"; - /// - /// 弹出授权页面,可通过openid拿到昵称、性别、所在地。 - /// 并且, 即使在未关注的情况下,只要用户授权,也能获取其信息 - ///
- ///
- /// 详询: - ///
- /// - /// 以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。 - /// 但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息 - /// - public const string UserInfoScope = "snsapi_userinfo"; - /// - /// 不弹出授权页面,直接跳转,只能获取用户openid - ///
- ///
- /// 详询: - ///
- /// - /// 以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。 - /// 用户感知的就是直接进入了回调页(往往是业务页面) - /// - public const string LoginScope = "snsapi_login"; - } -} diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Official/WeChatOfficialSignatureMiddleware.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Official/WeChatOfficialSignatureMiddleware.cs deleted file mode 100644 index b326504ca..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Official/WeChatOfficialSignatureMiddleware.cs +++ /dev/null @@ -1,77 +0,0 @@ -using LINGYUN.Abp.WeChat.Official; -using Microsoft.AspNetCore.Http; -using System; -using System.Collections; -using System.Threading.Tasks; -using Volo.Abp; -using Volo.Abp.DependencyInjection; - -namespace LINGYUN.Abp.IdentityServer.WeChat.Official -{ - public class WeChatOfficialSignatureMiddleware : IMiddleware, ITransientDependency - { - protected AbpWeChatOfficialOptionsFactory WeChatOfficialOptionsFactory { get; } - public WeChatOfficialSignatureMiddleware( - AbpWeChatOfficialOptionsFactory weChatOfficialOptionsFactory) - { - WeChatOfficialOptionsFactory = weChatOfficialOptionsFactory; - } - - public async Task InvokeAsync(HttpContext context, RequestDelegate next) - { - if (context.Request.Path.HasValue) - { - var options = await WeChatOfficialOptionsFactory.CreateAsync(); - - var requestPath = context.Request.Path.Value; - // 访问地址是否与定义的地址匹配 - if (requestPath.Equals(options.Url)) - { - var timestamp = context.Request.Query["timestamp"]; - var nonce = context.Request.Query["nonce"]; - var signature = context.Request.Query["signature"]; - var echostr = context.Request.Query["echostr"]; - // 验证消息合法性 - var check = CheckWeChatSignature(options.Token, timestamp, nonce, signature); - if (check) - { - // 验证通过需要把微信服务器传递的字符原封不动传回 - await context.Response.WriteAsync(echostr); - return; - } - // 微信消息验证不通过 - throw new AbpException("Invalid wechat signature"); - } - } - // 不属于微信的消息进入下一个中间件 - await next(context); - } - - protected bool CheckWeChatSignature(string token, string timestamp, string nonce, string signature) - { - var al = new ArrayList - { - token, - timestamp, - nonce - }; - // step1 排序 - al.Sort(); - string signatureStr = string.Empty; - // step2 拼接 - for (int i = 0; i < al.Count; i++) - { - signatureStr += al[i]; - } - // step3 SHA1加密 - byte[] bytes_out = signatureStr.Sha1(); - string result = BitConverter.ToString(bytes_out).Replace("-", ""); - // step4 比对 - if (result.Equals(signature, StringComparison.CurrentCultureIgnoreCase)) - { - return true; - } - return false; - } - } -} diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/WeChatGrantValidator.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/WeChatGrantValidator.cs deleted file mode 100644 index e596164bf..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/WeChatGrantValidator.cs +++ /dev/null @@ -1,242 +0,0 @@ -using IdentityModel; -using IdentityServer4.Events; -using IdentityServer4.Models; -using IdentityServer4.Services; -using IdentityServer4.Validation; -using LINGYUN.Abp.WeChat; -using LINGYUN.Abp.WeChat.Localization; -using LINGYUN.Abp.WeChat.OpenId; -using LINGYUN.Abp.WeChat.Security.Claims; -using LINGYUN.Abp.WeChat.Settings; -using Microsoft.AspNetCore.Identity; -using Microsoft.Extensions.Localization; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Logging.Abstractions; -using System; -using System.Collections.Generic; -using System.Security.Claims; -using System.Threading.Tasks; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Guids; -using Volo.Abp.Identity; -using Volo.Abp.IdentityServer; -using Volo.Abp.IdentityServer.Localization; -using Volo.Abp.MultiTenancy; -using Volo.Abp.Security.Claims; -using Volo.Abp.Settings; -using Volo.Abp.Uow; - -using IdentityResource = Volo.Abp.Identity.Localization.IdentityResource; -using IdentityUser = Volo.Abp.Identity.IdentityUser; - -namespace LINGYUN.Abp.IdentityServer.WeChat -{ - public abstract class WeChatGrantValidator : IExtensionGrantValidator - { - public abstract string GrantType { get; } - public abstract string LoginProvider { get; } - public abstract string AuthenticationMethod { get; } - - public ILogger Logger { protected get; set; } - public IAbpLazyServiceProvider ServiceProvider { protected get; set; } - - protected IEventService EventService { get; } - protected IWeChatOpenIdFinder WeChatOpenIdFinder { get; } - protected IIdentityUserRepository UserRepository { get; } - protected IdentitySecurityLogManager IdentitySecurityLogManager { get; } - protected UserManager UserManager { get; } - protected IStringLocalizer WeChatLocalizer { get; } - protected IStringLocalizer IdentityLocalizer { get; } - protected IStringLocalizer IdentityServerLocalizer { get; } - - public WeChatGrantValidator( - IEventService eventService, - IWeChatOpenIdFinder weChatOpenIdFinder, - UserManager userManager, - IIdentityUserRepository userRepository, - IdentitySecurityLogManager identitySecurityLogManager, - IStringLocalizer wechatLocalizer, - IStringLocalizer identityLocalizer, - IStringLocalizer identityServerLocalizer) - { - EventService = eventService; - UserManager = userManager; - UserRepository = userRepository; - IdentitySecurityLogManager = identitySecurityLogManager; - WeChatOpenIdFinder = weChatOpenIdFinder; - WeChatLocalizer = wechatLocalizer; - IdentityLocalizer = identityLocalizer; - IdentityServerLocalizer = identityServerLocalizer; - - Logger = NullLogger.Instance; - } - - protected abstract Task FindOpenIdAsync(string code); - - [UnitOfWork] - public async Task ValidateAsync(ExtensionGrantValidationContext context) - { - if (!await CheckFeatureAsync(context)) - { - return; - } - - var raw = context.Request.Raw; - var credential = raw.Get(OidcConstants.TokenRequest.GrantType); - if (credential == null || !credential.Equals(GrantType)) - { - Logger.LogWarning("Invalid grant type: not allowed"); - context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, IdentityServerLocalizer["InvalidGrant:GrantTypeInvalid"]); - return; - } - - var wechatCode = raw.Get(AbpWeChatGlobalConsts.TokenName); - if (wechatCode.IsNullOrWhiteSpace() || wechatCode.IsNullOrWhiteSpace()) - { - Logger.LogWarning("Invalid grant type: wechat code not found"); - context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, IdentityServerLocalizer["InvalidGrant:WeChatCodeNotFound"]); - return; - } - - WeChatOpenId wechatOpenId; - try - { - wechatOpenId = await FindOpenIdAsync(wechatCode); - } - catch(AbpWeChatException e) - { - context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, e.Message); - return; - } - var currentUser = await UserManager.FindByLoginAsync(LoginProvider, wechatOpenId.OpenId); - if (currentUser == null) - { - // 检查是否允许自注册 - var settingProvider = ServiceProvider.LazyGetRequiredService(); - // TODO 检查启用用户注册是否有必要引用账户模块 - if (!await settingProvider.IsTrueAsync("Abp.Account.IsSelfRegistrationEnabled") || - !await settingProvider.IsTrueAsync(WeChatSettingNames.EnabledQuickLogin)) - { - Logger.LogWarning("Invalid grant type: wechat openid not register", wechatOpenId.OpenId); - context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, IdentityServerLocalizer["InvalidGrant:WeChatNotRegister"]); - return; - } - var guiGenerator = ServiceProvider.LazyGetRequiredService(); - var currentTenant = ServiceProvider.LazyGetRequiredService(); - var userName = "wxid-" + wechatOpenId.OpenId.ToMd5().ToLower(); - var userEmail = $"{userName}@{currentTenant.Name ?? "default"}.io"; - currentUser = new IdentityUser(guiGenerator.Create(), userName, userEmail, currentTenant.Id); - (await UserManager.CreateAsync(currentUser)).CheckErrors(); - (await UserManager.AddLoginAsync( - currentUser, - new UserLoginInfo( - LoginProvider, - wechatOpenId.OpenId, - AbpWeChatGlobalConsts.DisplayName))).CheckErrors(); - } - - // 检查是否已锁定 - if (await UserManager.IsLockedOutAsync(currentUser)) - { - Logger.LogInformation("Authentication failed for username: {username}, reason: locked out", currentUser.UserName); - context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, IdentityLocalizer["Volo.Abp.Identity:UserLockedOut"]); - - await SaveSecurityLogAsync(context, currentUser, wechatOpenId, IdentityServerSecurityLogActionConsts.LoginLockedout); - - return; - } - - await EventService.RaiseAsync(new UserLoginSuccessEvent(currentUser.UserName, wechatOpenId.OpenId, null)); - - // 登录之后需要更新安全令牌 - (await UserManager.UpdateSecurityStampAsync(currentUser)).CheckErrors(); - - await SetSuccessResultAsync(context, currentUser, wechatOpenId); - } - - protected virtual Task CheckFeatureAsync(ExtensionGrantValidationContext context) - { - return Task.FromResult(true); - } - - protected async virtual Task SetSuccessResultAsync(ExtensionGrantValidationContext context, IdentityUser user, WeChatOpenId wechatOpenId) - { - var sub = await UserManager.GetUserIdAsync(user); - - Logger.LogInformation("Credentials validated for username: {username}", user.UserName); - - var additionalClaims = new List(); - - await AddCustomClaimsAsync(additionalClaims, user, wechatOpenId, context); - - context.Result = new GrantValidationResult( - sub, - AuthenticationMethod, - additionalClaims.ToArray() - ); - - await SaveSecurityLogAsync( - context, - user, - wechatOpenId, - IdentityServerSecurityLogActionConsts.LoginSucceeded); - } - - protected async virtual Task SaveSecurityLogAsync( - ExtensionGrantValidationContext context, - IdentityUser user, - WeChatOpenId wechatOpenId, - string action) - { - var logContext = new IdentitySecurityLogContext - { - Identity = IdentityServerSecurityLogIdentityConsts.IdentityServer, - Action = action, - UserName = user.UserName, - ClientId = await FindClientIdAsync(context) - }; - logContext.WithProperty("GrantType", GrantType); - logContext.WithProperty("Provider", LoginProvider); - logContext.WithProperty("Method", AuthenticationMethod); - - await IdentitySecurityLogManager.SaveAsync(logContext); - } - - protected virtual Task FindClientIdAsync(ExtensionGrantValidationContext context) - { - return Task.FromResult(context.Request?.Client?.ClientId); - } - - protected virtual Task AddCustomClaimsAsync( - List customClaims, - IdentityUser user, - WeChatOpenId wechatOpenId, - ExtensionGrantValidationContext context) - { - if (user.TenantId.HasValue) - { - customClaims.Add( - new Claim( - AbpClaimTypes.TenantId, - user.TenantId?.ToString() - ) - ); - } - - customClaims.Add( - new Claim( - AbpWeChatClaimTypes.OpenId, - wechatOpenId.OpenId)); - - if (!wechatOpenId.UnionId.IsNullOrWhiteSpace()) - { - customClaims.Add( - new Claim( - AbpWeChatClaimTypes.UnionId, - wechatOpenId.UnionId)); - } - - return Task.CompletedTask; - } - } -} diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/WeChatResourceDataSeeder.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/WeChatResourceDataSeeder.cs deleted file mode 100644 index 7088941ad..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/WeChatResourceDataSeeder.cs +++ /dev/null @@ -1,86 +0,0 @@ -using LINGYUN.Abp.IdentityServer.WeChat.Official; -using LINGYUN.Abp.WeChat.Security.Claims; -using System.Threading.Tasks; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Guids; -using Volo.Abp.Identity; -using Volo.Abp.IdentityServer.IdentityResources; - -namespace LINGYUN.Abp.IdentityServer -{ - public class WeChatResourceDataSeeder : IWeChatResourceDataSeeder, ITransientDependency - { - protected IIdentityClaimTypeRepository ClaimTypeRepository { get; } - protected IIdentityResourceRepository IdentityResourceRepository { get; } - protected IGuidGenerator GuidGenerator { get; } - - public WeChatResourceDataSeeder( - IIdentityResourceRepository identityResourceRepository, - IGuidGenerator guidGenerator, - IIdentityClaimTypeRepository claimTypeRepository) - { - IdentityResourceRepository = identityResourceRepository; - GuidGenerator = guidGenerator; - ClaimTypeRepository = claimTypeRepository; - } - - public async virtual Task CreateStandardResourcesAsync() - { - var wechatClaimTypes = new string[] - { - AbpWeChatClaimTypes.AvatarUrl, - AbpWeChatClaimTypes.City, - AbpWeChatClaimTypes.Country, - AbpWeChatClaimTypes.NickName, - AbpWeChatClaimTypes.OpenId, - AbpWeChatClaimTypes.Privilege, - AbpWeChatClaimTypes.Province, - AbpWeChatClaimTypes.Sex, - AbpWeChatClaimTypes.UnionId - }; - - var wechatResource = new IdentityServer4.Models.IdentityResource( - WeChatOfficialOAuthConsts.ProfileKey, - WeChatOfficialOAuthConsts.DisplayName, - wechatClaimTypes); - - foreach (var claimType in wechatClaimTypes) - { - await AddClaimTypeIfNotExistsAsync(claimType); - } - - await AddIdentityResourceIfNotExistsAsync(wechatResource); - } - - protected async virtual Task AddIdentityResourceIfNotExistsAsync(IdentityServer4.Models.IdentityResource resource) - { - if (await IdentityResourceRepository.CheckNameExistAsync(resource.Name)) - { - return; - } - - await IdentityResourceRepository.InsertAsync( - new IdentityResource( - GuidGenerator.Create(), - resource - ) - ); - } - - protected async virtual Task AddClaimTypeIfNotExistsAsync(string claimType) - { - if (await ClaimTypeRepository.AnyAsync(claimType)) - { - return; - } - - await ClaimTypeRepository.InsertAsync( - new IdentityClaimType( - GuidGenerator.Create(), - claimType, - isStatic: true - ) - ); - } - } -} diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialOAuthHandler.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialOAuthHandler.cs deleted file mode 100644 index 607ffcc8a..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialOAuthHandler.cs +++ /dev/null @@ -1,336 +0,0 @@ -using LINGYUN.Abp.IdentityServer.WeChat.Official; -using LINGYUN.Abp.WeChat.Official; -using Microsoft.AspNetCore.Authentication.OAuth; -using Microsoft.AspNetCore.WebUtilities; -using Microsoft.Extensions.Caching.Distributed; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using Microsoft.Extensions.Primitives; -using Microsoft.Net.Http.Headers; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Net.Http; -using System.Security.Claims; -using System.Text; -using System.Text.Encodings.Web; -using System.Text.Json; -using System.Threading.Tasks; -using Volo.Abp.Caching; - -namespace Microsoft.AspNetCore.Authentication.WeChat.Official -{ - /// - /// 网页授权只有公众平台的实现 - /// - public class WeChatOfficialOAuthHandler : OAuthHandler - { - protected IDistributedCache Cache { get; } - protected AbpWeChatOfficialOptionsFactory WeChatOfficialOptionsFactory { get; } - public WeChatOfficialOAuthHandler( - IDistributedCache cache, - IOptionsMonitor options, - AbpWeChatOfficialOptionsFactory weChatOfficialOptionsFactory, - ILoggerFactory logger, - UrlEncoder encoder, - ISystemClock clock) - : base(options, logger, encoder, clock) - { - Cache = cache; - WeChatOfficialOptionsFactory = weChatOfficialOptionsFactory; - } - - protected override async Task InitializeHandlerAsync() - { - var weChatOfficialOptions = await WeChatOfficialOptionsFactory.CreateAsync(); - - // 用配置项重写 - Options.ClientId = weChatOfficialOptions.AppId; - Options.ClientSecret = weChatOfficialOptions.AppSecret; - - await base.InitializeHandlerAsync(); - } - - protected override async Task CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) - { - var address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, new Dictionary - { - ["access_token"] = tokens.AccessToken, - ["openid"] = tokens.Response.GetRootString("openid") - }); - - var response = await Backchannel.GetAsync(address); - if (!response.IsSuccessStatusCode) - { - Logger.LogError("An error occurred while retrieving the user profile: the remote server " + - "returned a {Status} response with the following payload: {Headers} {Body}.", - /* Status: */ response.StatusCode, - /* Headers: */ response.Headers.ToString(), - /* Body: */ await response.Content.ReadAsStringAsync()); - - throw new HttpRequestException("An error occurred while retrieving user information."); - } - - var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync()); - if (!string.IsNullOrEmpty(payload.GetRootString("errcode"))) - { - Logger.LogError("An error occurred while retrieving the user profile: the remote server " + - "returned a {Status} response with the following payload: {Headers} {Body}.", - /* Status: */ response.StatusCode, - /* Headers: */ response.Headers.ToString(), - /* Body: */ await response.Content.ReadAsStringAsync()); - - throw new HttpRequestException("An error occurred while retrieving user information."); - } - - var context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Scheme, Options, Backchannel, tokens, payload.RootElement); - context.RunClaimActions(); - - await Events.CreatingTicket(context); - - // TODO: 此处通过唯一的 CorrelationId, 将 properties生成的State缓存删除 - var state = Request.Query["state"]; - - var stateCacheKey = WeChatOfficialStateCacheItem.CalculateCacheKey(state.ToString().ToMd5(), null); - await Cache.RemoveAsync(stateCacheKey, token: Context.RequestAborted); - - return new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name); - } - - /// - /// code换取access_token - /// - protected override async Task ExchangeCodeAsync(OAuthCodeExchangeContext context) - { - var address = QueryHelpers.AddQueryString(Options.TokenEndpoint, new Dictionary() - { - ["appid"] = Options.ClientId, - ["secret"] = Options.ClientSecret, - ["code"] = context.Code, - ["grant_type"] = "authorization_code" - }); - - var response = await Backchannel.GetAsync(address); - if (!response.IsSuccessStatusCode) - { - Logger.LogError("An error occurred while retrieving an access token: the remote server " + - "returned a {Status} response with the following payload: {Headers} {Body}.", - /* Status: */ response.StatusCode, - /* Headers: */ response.Headers.ToString(), - /* Body: */ await response.Content.ReadAsStringAsync()); - - return OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token.")); - } - - var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync()); - if (!string.IsNullOrEmpty(payload.GetRootString("errcode"))) - { - Logger.LogError("An error occurred while retrieving an access token: the remote server " + - "returned a {Status} response with the following payload: {Headers} {Body}.", - /* Status: */ response.StatusCode, - /* Headers: */ response.Headers.ToString(), - /* Body: */ await response.Content.ReadAsStringAsync()); - - return OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token.")); - } - return OAuthTokenResponse.Success(payload); - } - - protected override async Task HandleChallengeAsync(AuthenticationProperties properties) - { - await base.HandleChallengeAsync(properties); - - // TODO: 此处已经生成唯一的 CorrelationId, 可以借此将 properties生成State之后再进行缓存 - // 注: 默认的State对于微信来说太长(微信只支持128位长度的State),因此巧妙的利用CorrelationId的MD5值来替代State - // MD5转换防止直接通过CorrelationId干些别的事情... - var state = properties.Items[".xsrf"]; - - var stateToken = Options.StateDataFormat.Protect(properties); - var stateCacheKey = WeChatOfficialStateCacheItem.CalculateCacheKey(state.ToMd5(), null); - - await Cache - .SetAsync( - stateCacheKey, - new WeChatOfficialStateCacheItem(stateToken), - new DistributedCacheEntryOptions - { - AbsoluteExpiration = Clock.UtcNow.AddMinutes(2) // TODO: 设定2分钟过期? - }, - token: Context.RequestAborted); - } - /// - /// 构建用户授权地址 - /// - protected override string BuildChallengeUrl(AuthenticationProperties properties, string redirectUri) - { - var state = properties.Items[".xsrf"]; - - var isWeChatBrewserRequest = IsWeChatBrowser(); - - var scope = isWeChatBrewserRequest - ? WeChatOfficialOAuthConsts.UserInfoScope - : FormatScope(); - - var endPoint = isWeChatBrewserRequest - ? Options.AuthorizationEndpoint - : WeChatOfficialOAuthConsts.QrConnectEndpoint; - - var challengeUrl = QueryHelpers.AddQueryString(endPoint, new Dictionary - { - ["appid"] = Options.ClientId, - ["redirect_uri"] = redirectUri, - ["response_type"] = "code" - }); - - challengeUrl += $"&scope={scope}&state={state.ToMd5()}"; - - return challengeUrl; - } - - protected override async Task HandleRemoteAuthenticateAsync() - { - var query = Request.Query; - - // TODO: 此处借用唯一的 CorrelationId, 将 properties生成的State缓存取出,进行解密 - var state = query["state"]; - - var stateCacheKey = WeChatOfficialStateCacheItem.CalculateCacheKey(state.ToString().ToMd5(), null); - var stateCacheItem = await Cache.GetAsync(stateCacheKey, token: Context.RequestAborted); - - var properties = Options.StateDataFormat.Unprotect(stateCacheItem.State); - - if (properties == null) - { - return HandleRequestResult.Fail("The oauth state was missing or invalid."); - } - - // OAuth2 10.12 CSRF - if (!ValidateCorrelationId(properties)) - { - return HandleRequestResult.Fail("Correlation failed.", properties); - } - - var error = query["error"]; - if (!StringValues.IsNullOrEmpty(error)) - { - // Note: access_denied errors are special protocol errors indicating the user didn't - // approve the authorization demand requested by the remote authorization server. - // Since it's a frequent scenario (that is not caused by incorrect configuration), - // denied errors are handled differently using HandleAccessDeniedErrorAsync(). - // Visit https://tools.ietf.org/html/rfc6749#section-4.1.2.1 for more information. - var errorDescription = query["error_description"]; - var errorUri = query["error_uri"]; - if (StringValues.Equals(error, "access_denied")) - { - var result = await HandleAccessDeniedErrorAsync(properties); - if (!result.None) - { - return result; - } - var deniedEx = new Exception("Access was denied by the resource owner or by the remote server."); - deniedEx.Data["error"] = error.ToString(); - deniedEx.Data["error_description"] = errorDescription.ToString(); - deniedEx.Data["error_uri"] = errorUri.ToString(); - - return HandleRequestResult.Fail(deniedEx, properties); - } - - var failureMessage = new StringBuilder(); - failureMessage.Append(error); - if (!StringValues.IsNullOrEmpty(errorDescription)) - { - failureMessage.Append(";Description=").Append(errorDescription); - } - if (!StringValues.IsNullOrEmpty(errorUri)) - { - failureMessage.Append(";Uri=").Append(errorUri); - } - - var ex = new Exception(failureMessage.ToString()); - ex.Data["error"] = error.ToString(); - ex.Data["error_description"] = errorDescription.ToString(); - ex.Data["error_uri"] = errorUri.ToString(); - - return HandleRequestResult.Fail(ex, properties); - } - - var code = query["code"]; - - if (StringValues.IsNullOrEmpty(code)) - { - return HandleRequestResult.Fail("Code was not found.", properties); - } - - var codeExchangeContext = new OAuthCodeExchangeContext(properties, code, BuildRedirectUri(Options.CallbackPath)); - using var tokens = await ExchangeCodeAsync(codeExchangeContext); - - if (tokens.Error != null) - { - return HandleRequestResult.Fail(tokens.Error, properties); - } - - if (string.IsNullOrEmpty(tokens.AccessToken)) - { - return HandleRequestResult.Fail("Failed to retrieve access token.", properties); - } - - var identity = new ClaimsIdentity(ClaimsIssuer); - - if (Options.SaveTokens) - { - var authTokens = new List(); - - authTokens.Add(new AuthenticationToken { Name = "access_token", Value = tokens.AccessToken }); - if (!string.IsNullOrEmpty(tokens.RefreshToken)) - { - authTokens.Add(new AuthenticationToken { Name = "refresh_token", Value = tokens.RefreshToken }); - } - - if (!string.IsNullOrEmpty(tokens.TokenType)) - { - authTokens.Add(new AuthenticationToken { Name = "token_type", Value = tokens.TokenType }); - } - - if (!string.IsNullOrEmpty(tokens.ExpiresIn)) - { - int value; - if (int.TryParse(tokens.ExpiresIn, NumberStyles.Integer, CultureInfo.InvariantCulture, out value)) - { - // https://www.w3.org/TR/xmlschema-2/#dateTime - // https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx - var expiresAt = Clock.UtcNow + TimeSpan.FromSeconds(value); - authTokens.Add(new AuthenticationToken - { - Name = "expires_at", - Value = expiresAt.ToString("o", CultureInfo.InvariantCulture) - }); - } - } - - properties.StoreTokens(authTokens); - } - - var ticket = await CreateTicketAsync(identity, properties, tokens); - if (ticket != null) - { - return HandleRequestResult.Success(ticket); - } - else - { - return HandleRequestResult.Fail("Failed to retrieve user information from remote server.", properties); - } - } - - protected override string FormatScope() - { - return string.Join(",", Options.Scope); - } - - protected virtual bool IsWeChatBrowser() - { - var userAgent = Request.Headers[HeaderNames.UserAgent].ToString(); - - return userAgent.Contains("micromessenger", StringComparison.InvariantCultureIgnoreCase); - } - } -} \ No newline at end of file diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialOAuthOptions.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialOAuthOptions.cs deleted file mode 100644 index 8ff9f9e11..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialOAuthOptions.cs +++ /dev/null @@ -1,47 +0,0 @@ -using LINGYUN.Abp.IdentityServer.WeChat.Official; -using LINGYUN.Abp.WeChat.Security.Claims; -using Microsoft.AspNetCore.Authentication.OAuth; -using Microsoft.AspNetCore.Http; -using System.Security.Claims; -using System.Text.Json; - -namespace Microsoft.AspNetCore.Authentication.WeChat.Official -{ - public class WeChatOfficialOAuthOptions : OAuthOptions - { - public WeChatOfficialOAuthOptions() - { - // 用于防止初始化错误,会在OAuthHandler.InitializeHandlerAsync中进行重写 - ClientId = "WeChatOfficial"; - ClientSecret = "WeChatOfficial"; - - ClaimsIssuer = WeChatOfficialOAuthConsts.ProviderKey; - CallbackPath = new PathString(WeChatOfficialOAuthConsts.CallbackPath); - - AuthorizationEndpoint = WeChatOfficialOAuthConsts.AuthorizationEndpoint; - TokenEndpoint = WeChatOfficialOAuthConsts.TokenEndpoint; - UserInformationEndpoint = WeChatOfficialOAuthConsts.UserInformationEndpoint; - - Scope.Add(WeChatOfficialOAuthConsts.LoginScope); - Scope.Add(WeChatOfficialOAuthConsts.UserInfoScope); - - // 这个原始的属性一定要写进去,框架与UserLogin.ProviderKey进行关联判断是否绑定微信 - ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "openid"); - ClaimActions.MapJsonKey(ClaimTypes.Name, "nickname"); - - // 把自定义的身份标识写进令牌 - ClaimActions.MapJsonKey(AbpWeChatClaimTypes.OpenId, "openid"); - ClaimActions.MapJsonKey(AbpWeChatClaimTypes.UnionId, "unionid");// 公众号如果与小程序关联,这个可以用上 - ClaimActions.MapJsonKey(AbpWeChatClaimTypes.NickName, "nickname"); - ClaimActions.MapJsonKey(AbpWeChatClaimTypes.Sex, "sex", ClaimValueTypes.Integer); - ClaimActions.MapJsonKey(AbpWeChatClaimTypes.Country, "country"); - ClaimActions.MapJsonKey(AbpWeChatClaimTypes.Province, "province"); - ClaimActions.MapJsonKey(AbpWeChatClaimTypes.City, "city"); - ClaimActions.MapJsonKey(AbpWeChatClaimTypes.AvatarUrl, "headimgurl"); - ClaimActions.MapCustomJson(AbpWeChatClaimTypes.Privilege, user => - { - return string.Join(",", user.GetStrings("privilege")); - }); - } - } -} diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialStateCacheItem.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialStateCacheItem.cs deleted file mode 100644 index e8c5eb5e8..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialStateCacheItem.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Microsoft.AspNetCore.Authentication.WeChat.Official -{ - public class WeChatOfficialStateCacheItem - { - public string State { get; set; } - - public WeChatOfficialStateCacheItem() { } - public WeChatOfficialStateCacheItem(string state) - { - State = state; - } - - public static string CalculateCacheKey(string correlationId, string purpose) - { - return $"ci:{correlationId};p:{purpose ?? "null"}"; - } - } -} diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/Microsoft/AspNetCore/Authentication/WeChatAuthenticationExtensions.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/Microsoft/AspNetCore/Authentication/WeChatAuthenticationExtensions.cs deleted file mode 100644 index 3a5812611..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/Microsoft/AspNetCore/Authentication/WeChatAuthenticationExtensions.cs +++ /dev/null @@ -1,65 +0,0 @@ -using LINGYUN.Abp.IdentityServer.WeChat.Official; -using LINGYUN.Abp.WeChat; -using Microsoft.AspNetCore.Authentication.WeChat.Official; -using Microsoft.Extensions.DependencyInjection; -using System; - -namespace Microsoft.AspNetCore.Authentication -{ - public static class WeChatAuthenticationExtensions - { - /// - /// - public static AuthenticationBuilder AddWeChat( - this AuthenticationBuilder builder) - { - return builder - .AddWeChat( - AbpWeChatGlobalConsts.AuthenticationScheme, - AbpWeChatGlobalConsts.DisplayName, - options => { }); - } - - /// - /// - public static AuthenticationBuilder AddWeChat( - this AuthenticationBuilder builder, - Action configureOptions) - { - return builder - .AddWeChat( - AbpWeChatGlobalConsts.AuthenticationScheme, - AbpWeChatGlobalConsts.DisplayName, - configureOptions); - } - - /// - /// - public static AuthenticationBuilder AddWeChat( - this AuthenticationBuilder builder, - string authenticationScheme, - Action configureOptions) - { - return builder - .AddWeChat( - authenticationScheme, - WeChatOfficialOAuthConsts.DisplayName, - configureOptions); - } - - /// - /// - public static AuthenticationBuilder AddWeChat( - this AuthenticationBuilder builder, - string authenticationScheme, - string displayName, - Action configureOptions) - { - return builder - .AddOAuth( - authenticationScheme, - displayName, - configureOptions); - } - } -} diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/Microsoft/AspNetCore/Builder/IdentityServerApplicationBuilderExtensions.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/Microsoft/AspNetCore/Builder/IdentityServerApplicationBuilderExtensions.cs deleted file mode 100644 index d152749d8..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/Microsoft/AspNetCore/Builder/IdentityServerApplicationBuilderExtensions.cs +++ /dev/null @@ -1,22 +0,0 @@ -using LINGYUN.Abp.IdentityServer.WeChat.Official; - -namespace Microsoft.AspNetCore.Builder -{ - public static class IdentityServerApplicationBuilderExtensions - { - /// - /// 启用中间件可以处理微信服务器消息 - /// 用于验证消息是否来自于微信服务器 - /// - /// - /// - /// 也可以用Controller的形式来实现 - /// - /// - public static IApplicationBuilder UseWeChatSignature(this IApplicationBuilder builder) - { - builder.UseMiddleware(); - return builder; - } - } -} diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/System/BytesExtensions.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/System/BytesExtensions.cs deleted file mode 100644 index d1bad7915..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/System/BytesExtensions.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Security.Cryptography; - -namespace System -{ - internal static class BytesExtensions - { - public static byte[] Sha1(this byte[] data) - { - using (var sha = SHA1.Create()) - { - var hashBytes = sha.ComputeHash(data); - return hashBytes; - } - } - } -} diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/System/StringExtensions.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/System/StringExtensions.cs deleted file mode 100644 index a8eb40c27..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/System/StringExtensions.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Security.Cryptography; -using System.Text; - -namespace System -{ - internal static class StringExtensions - { - public static byte[] Sha1(this string str) - { - using (var sha = SHA1.Create()) - { - var hashBytes = sha.ComputeHash(Encoding.ASCII.GetBytes(str)); - return hashBytes; - } - } - } -} diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/System/Text/Json/JsonElementExtensions.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/System/Text/Json/JsonElementExtensions.cs deleted file mode 100644 index 653a868ac..000000000 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/System/Text/Json/JsonElementExtensions.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System.Collections.Generic; - -namespace System.Text.Json -{ - internal static class JsonElementExtensions - { - public static IEnumerable GetRootStrings(this JsonDocument json, string key) - { - return json.RootElement.GetStrings(key); - } - - public static IEnumerable GetStrings(this JsonElement json, string key) - { - var result = new List(); - - if (json.TryGetProperty(key, out JsonElement property) && property.ValueKind == JsonValueKind.Array) - { - foreach (var jsonProp in property.EnumerateArray()) - { - result.Add(jsonProp.GetString()); - } - } - - return result; - } - - public static string GetRootString(this JsonDocument json, string key, string defaultValue = "") - { - if (json.RootElement.TryGetProperty(key, out JsonElement property)) - { - return property.GetString(); - } - return defaultValue; - } - - public static string GetString(this JsonElement json, string key, string defaultValue = "") - { - if (json.TryGetProperty(key, out JsonElement property)) - { - return property.GetString(); - } - return defaultValue; - } - - public static int GetRootInt32(this JsonDocument json, string key, int defaultValue = 0) - { - if (json.RootElement.TryGetProperty(key, out JsonElement property) && property.TryGetInt32(out int value)) - { - return value; - } - return defaultValue; - } - - public static int GetInt32(this JsonElement json, string key, int defaultValue = 0) - { - if (json.TryGetProperty(key, out JsonElement property) && property.TryGetInt32(out int value)) - { - return value; - } - return defaultValue; - } - } -}