diff --git a/Yi.Abp.Net8/Yi.Abp.sln b/Yi.Abp.Net8/Yi.Abp.sln
index d7d36b3d..673840f8 100644
--- a/Yi.Abp.Net8/Yi.Abp.sln
+++ b/Yi.Abp.Net8/Yi.Abp.sln
@@ -72,6 +72,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "audit-logging", "audit-logg
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.AuditLogging.SqlSugarCore", "module\audit-logging\Yi.AuditLogging.SqlSugarCore\Yi.AuditLogging.SqlSugarCore.csproj", "{48806510-8E18-4E1E-9BAF-5B97E88C5FC3}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Framework.AspNetCore.Authentication.OAuth", "framework\Yi.Framework.AspNetCore.Authentication.OAuth\Yi.Framework.AspNetCore.Authentication.OAuth.csproj", "{791AC2FA-50D3-4408-8D68-31DA72F608BE}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -174,6 +176,10 @@ Global
{48806510-8E18-4E1E-9BAF-5B97E88C5FC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{48806510-8E18-4E1E-9BAF-5B97E88C5FC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{48806510-8E18-4E1E-9BAF-5B97E88C5FC3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {791AC2FA-50D3-4408-8D68-31DA72F608BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {791AC2FA-50D3-4408-8D68-31DA72F608BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {791AC2FA-50D3-4408-8D68-31DA72F608BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {791AC2FA-50D3-4408-8D68-31DA72F608BE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -206,6 +212,7 @@ Global
{6C86BA71-9F87-4E2C-B467-2950D77DCDFA} = {E902A945-4F41-4E96-A0DA-9F66CDA22261}
{73CCF2C4-B9FD-44AB-8D4B-0A421805B094} = {2317227D-7796-4E7B-BEDB-7CD1CAE7B853}
{48806510-8E18-4E1E-9BAF-5B97E88C5FC3} = {73CCF2C4-B9FD-44AB-8D4B-0A421805B094}
+ {791AC2FA-50D3-4408-8D68-31DA72F608BE} = {77B949E9-530E-45A5-9657-20F7D5C6875C}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {23D6FBC9-C970-4641-BC1E-2AEA59F51C18}
diff --git a/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/Gitee/GiteeAuthenticationConstants.cs b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/Gitee/GiteeAuthenticationConstants.cs
new file mode 100644
index 00000000..ba665ab5
--- /dev/null
+++ b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/Gitee/GiteeAuthenticationConstants.cs
@@ -0,0 +1,23 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+ * See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers
+ * for more information concerning the license and the contributors participating to this project.
+ */
+
+namespace Yi.Framework.AspNetCore.Authentication.OAuth.Gitee;
+
+///
+/// Contains constants specific to the .
+///
+public static class GiteeAuthenticationConstants
+{
+ public static class Claims
+ {
+ public const string Url = "urn:gitee:url";
+ public const string AvatarUrl = "urn:gitee:avatarUrl";
+
+ public const string OpenId = "urn:openid";
+ public const string AccessToken = "urn:access_token";
+ public const string Name = "urn:name";
+ }
+}
diff --git a/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/Gitee/GiteeAuthenticationDefaults.cs b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/Gitee/GiteeAuthenticationDefaults.cs
new file mode 100644
index 00000000..d972d810
--- /dev/null
+++ b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/Gitee/GiteeAuthenticationDefaults.cs
@@ -0,0 +1,53 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+ * See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers
+ * for more information concerning the license and the contributors participating to this project.
+ */
+
+namespace Yi.Framework.AspNetCore.Authentication.OAuth.Gitee;
+
+///
+/// Default values used by the Gitee authentication middleware.
+///
+public static class GiteeAuthenticationDefaults
+{
+ ///
+ /// Default value for .
+ ///
+ public const string AuthenticationScheme = "Gitee";
+
+ ///
+ /// Default value for .
+ ///
+ public static readonly string DisplayName = "Gitee";
+
+ ///
+ /// Default value for .
+ ///
+ public static readonly string Issuer = "Gitee";
+
+ ///
+ /// Default value for .
+ ///
+ public static readonly string CallbackPath = "/signin-gitee";
+
+ ///
+ /// Default value for .
+ ///
+ public static readonly string AuthorizationEndpoint = "https://gitee.com/oauth/authorize";
+
+ ///
+ /// Default value for .
+ ///
+ public static readonly string TokenEndpoint = "https://gitee.com/oauth/token";
+
+ ///
+ /// Default value for .
+ ///
+ public static readonly string UserInformationEndpoint = "https://gitee.com/api/v5/user";
+
+ ///
+ /// Default value for .
+ ///
+ public static readonly string UserEmailsEndpoint = "https://gitee.com/api/v5/emails";
+}
diff --git a/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/Gitee/GiteeAuthenticationExtensions.cs b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/Gitee/GiteeAuthenticationExtensions.cs
new file mode 100644
index 00000000..a28f4882
--- /dev/null
+++ b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/Gitee/GiteeAuthenticationExtensions.cs
@@ -0,0 +1,75 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+ * See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers
+ * for more information concerning the license and the contributors participating to this project.
+ */
+
+using JetBrains.Annotations;
+using Microsoft.AspNetCore.Authentication;
+
+namespace Yi.Framework.AspNetCore.Authentication.OAuth.Gitee;
+
+///
+/// Extension methods to add Gitee authentication capabilities to an HTTP application pipeline.
+///
+public static class GiteeAuthenticationExtensions
+{
+ ///
+ /// Adds to the specified
+ /// , which enables Gitee authentication capabilities.
+ ///
+ /// The authentication builder.
+ /// The .
+ public static AuthenticationBuilder AddGitee([NotNull] this AuthenticationBuilder builder)
+ {
+ return builder.AddGitee(GiteeAuthenticationDefaults.AuthenticationScheme, options => { });
+ }
+
+ ///
+ /// Adds to the specified
+ /// , which enables Gitee authentication capabilities.
+ ///
+ /// The authentication builder.
+ /// The delegate used to configure the OpenID 2.0 options.
+ /// The .
+ public static AuthenticationBuilder AddGitee(
+ [NotNull] this AuthenticationBuilder builder,
+ [NotNull] Action configuration)
+ {
+ return builder.AddGitee(GiteeAuthenticationDefaults.AuthenticationScheme, configuration);
+ }
+
+ ///
+ /// Adds to the specified
+ /// , which enables Gitee authentication capabilities.
+ ///
+ /// The authentication builder.
+ /// The authentication scheme associated with this instance.
+ /// The delegate used to configure the Gitee options.
+ /// The .
+ public static AuthenticationBuilder AddGitee(
+ [NotNull] this AuthenticationBuilder builder,
+ [NotNull] string scheme,
+ [NotNull] Action configuration)
+ {
+ return builder.AddGitee(scheme, GiteeAuthenticationDefaults.DisplayName, configuration);
+ }
+
+ ///
+ /// Adds to the specified
+ /// , which enables Gitee authentication capabilities.
+ ///
+ /// The authentication builder.
+ /// The authentication scheme associated with this instance.
+ /// The optional display name associated with this instance.
+ /// The delegate used to configure the Gitee options.
+ /// The .
+ public static AuthenticationBuilder AddGitee(
+ [NotNull] this AuthenticationBuilder builder,
+ [NotNull] string scheme,
+ [CanBeNull] string caption,
+ [NotNull] Action configuration)
+ {
+ return builder.AddScheme(scheme, caption, configuration);
+ }
+}
diff --git a/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/Gitee/GiteeAuthenticationHandler.cs b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/Gitee/GiteeAuthenticationHandler.cs
new file mode 100644
index 00000000..f88e6d3e
--- /dev/null
+++ b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/Gitee/GiteeAuthenticationHandler.cs
@@ -0,0 +1,55 @@
+using System.Security.Claims;
+using System.Text.Encodings.Web;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using Yi.Framework.AspNetCore.Authentication.OAuth.QQ;
+using static Yi.Framework.AspNetCore.Authentication.OAuth.Gitee.GiteeAuthenticationConstants;
+
+namespace Yi.Framework.AspNetCore.Authentication.OAuth.Gitee
+{
+ public class GiteeAuthenticationHandler : OauthAuthenticationHandler
+ {
+ public GiteeAuthenticationHandler(IOptionsMonitor options, ILoggerFactory logger, UrlEncoder encoder, IHttpClientFactory httpClientFactory) : base(options, logger, encoder, httpClientFactory)
+ {
+ }
+
+ public override string AuthenticationSchemeNmae => GiteeAuthenticationDefaults.AuthenticationScheme;
+
+ protected override async Task> GetAuthTicketAsync(string code)
+ {
+ //获取 accessToken
+ var tokenQueryKv = new List>()
+ {
+ new KeyValuePair("grant_type","authorization_code"),
+ new KeyValuePair("client_id",Options.ClientId),
+ new KeyValuePair("client_secret",Options.ClientSecret),
+ new KeyValuePair("redirect_uri",Options.RedirectUri),
+ new KeyValuePair("code",code)
+ };
+ var tokenModel = await SendHttpRequestAsync(GiteeAuthenticationDefaults.TokenEndpoint, tokenQueryKv,HttpMethod.Post);
+
+ //获取 userInfo
+ var userInfoQueryKv = new List>()
+ {
+ new KeyValuePair("access_token",tokenModel.access_token),
+ };
+ var userInfoMdoel = await SendHttpRequestAsync(GiteeAuthenticationDefaults.UserInformationEndpoint, userInfoQueryKv);
+
+ List claims = new List()
+ {
+ new Claim(Claims.AvatarUrl, userInfoMdoel.avatar_url),
+ new Claim(Claims.Url, userInfoMdoel.url),
+
+ new Claim(Claims.OpenId,userInfoMdoel.id.ToString()),
+ new Claim(Claims.Name, userInfoMdoel.name),
+ new Claim(Claims.AccessToken, tokenModel.access_token)
+ };
+ return claims;
+ }
+
+ protected override void VerifyErrResponse(string content)
+ {
+ GiteeAuthticationErrCodeModel.VerifyErrResponse(content);
+ }
+ }
+}
diff --git a/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/Gitee/GiteeAuthenticationOptions.cs b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/Gitee/GiteeAuthenticationOptions.cs
new file mode 100644
index 00000000..0139fe38
--- /dev/null
+++ b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/Gitee/GiteeAuthenticationOptions.cs
@@ -0,0 +1,47 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+ * See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers
+ * for more information concerning the license and the contributors participating to this project.
+ */
+
+using System.Security.Claims;
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Authentication.OAuth;
+using static Yi.Framework.AspNetCore.Authentication.OAuth.Gitee.GiteeAuthenticationConstants;
+
+namespace Yi.Framework.AspNetCore.Authentication.OAuth.Gitee;
+
+///
+/// Defines a set of options used by .
+///
+public class GiteeAuthenticationOptions : OAuthOptions
+{
+ public GiteeAuthenticationOptions()
+ {
+ ClaimsIssuer = GiteeAuthenticationDefaults.Issuer;
+
+ CallbackPath = GiteeAuthenticationDefaults.CallbackPath;
+
+ AuthorizationEndpoint = GiteeAuthenticationDefaults.AuthorizationEndpoint;
+ TokenEndpoint = GiteeAuthenticationDefaults.TokenEndpoint;
+ UserInformationEndpoint = GiteeAuthenticationDefaults.UserInformationEndpoint;
+ UserEmailsEndpoint = GiteeAuthenticationDefaults.UserEmailsEndpoint;
+
+ Scope.Add("user_info");
+ Scope.Add("emails");
+
+ ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "id");
+ ClaimActions.MapJsonKey(ClaimTypes.Name, "login");
+ ClaimActions.MapJsonKey(ClaimTypes.Email, "email");
+ ClaimActions.MapJsonKey(Claims.Name, "name");
+ ClaimActions.MapJsonKey(Claims.Url, "url");
+ }
+
+ ///
+ /// Gets or sets the address of the endpoint exposing
+ /// the email addresses associated with the logged in user.
+ ///
+ public string UserEmailsEndpoint { get; set; }
+
+ public string RedirectUri { get; set; }
+}
diff --git a/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/Gitee/GiteeAuthticationErrCodeModel.cs b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/Gitee/GiteeAuthticationErrCodeModel.cs
new file mode 100644
index 00000000..a1cba0f5
--- /dev/null
+++ b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/Gitee/GiteeAuthticationErrCodeModel.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json;
+using System.Threading.Tasks;
+
+
+namespace Yi.Framework.AspNetCore.Authentication.OAuth.Gitee
+{
+ public class GiteeAuthticationErrCodeModel
+ {
+ public string error { get; set; }
+
+ public string error_description { get; set; }
+
+ public static void VerifyErrResponse(string content)
+ {
+
+ var model =Newtonsoft.Json.JsonConvert.DeserializeObject (content);
+ if (model.error != null)
+ {
+
+ throw new Exception($"第三方授权返回错误,错误码:【{model.error}】,错误详情:【{model.error_description}】");
+ }
+ }
+
+ }
+
+}
diff --git a/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/Gitee/GiteeAuthticationcationHttpModel.cs b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/Gitee/GiteeAuthticationcationHttpModel.cs
new file mode 100644
index 00000000..15ffd178
--- /dev/null
+++ b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/Gitee/GiteeAuthticationcationHttpModel.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.AspNetCore.Authentication.OAuth.Gitee
+{
+ public class GiteeAuthticationcationTokenResponse
+ {
+ public string access_token { get; set; }
+ public string token_type { get; set; }
+ public int expires_in { get; set; }
+ public string refresh_token { get; set; }
+ public string scope { get; set; }
+ public long created_at { get; set; }
+ }
+
+
+ public class GiteeAuthticationcationOpenIdResponse
+ {
+ public string client_id { get; set; }
+
+ public string openid { get; set; }
+
+ }
+
+ public class GiteeAuthticationcationUserInfoResponse
+ {
+ ///
+ /// 也可以等于openId
+ ///
+ public int id { get; set; }
+ public string login { get; set; }
+ public string name { get; set; }
+ public string avatar_url { get; set; }
+ public string url { get; set; }
+ public string html_url { get; set; }
+ public string remark { get; set; }
+ public string followers_url { get; set; }
+ public string following_url { get; set; }
+ public string gists_url { get; set; }
+ public string starred_url { get; set; }
+ public string subscriptions_url { get; set; }
+ public string organizations_url { get; set; }
+ public string repos_url { get; set; }
+ public string events_url { get; set; }
+ public string received_events_url { get; set; }
+ public string type { get; set; }
+ public string blog { get; set; }
+ public string weibo { get; set; }
+ public string bio { get; set; }
+ public int public_repos { get; set; }
+ public int public_gists { get; set; }
+ public int followers { get; set; }
+ public int following { get; set; }
+ public int stared { get; set; }
+ public int watched { get; set; }
+ public DateTime created_at { get; set; }
+ public DateTime updated_at { get; set; }
+ public string email { get; set; }
+ }
+}
diff --git a/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/OAuthAuthenticationHandler.cs b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/OAuthAuthenticationHandler.cs
new file mode 100644
index 00000000..4fedae7c
--- /dev/null
+++ b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/OAuthAuthenticationHandler.cs
@@ -0,0 +1,96 @@
+using System.Security.Claims;
+using System.Text.Encodings.Web;
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.WebUtilities;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+
+namespace Yi.Framework.AspNetCore.Authentication.OAuth
+{
+ public abstract class OauthAuthenticationHandler : AuthenticationHandler where TOptions : AuthenticationSchemeOptions, new()
+ {
+ public abstract string AuthenticationSchemeNmae { get; }
+ private AuthenticationScheme _scheme;
+
+ public OauthAuthenticationHandler(IOptionsMonitor options, ILoggerFactory logger, UrlEncoder encoder, IHttpClientFactory httpClientFactory) : base(options, logger, encoder)
+ {
+ HttpClientFactory = httpClientFactory;
+ HttpClient = HttpClientFactory.CreateClient();
+ }
+
+
+ protected IHttpClientFactory HttpClientFactory { get; }
+
+ protected HttpClient HttpClient { get; }
+
+
+
+ ///
+ /// 生成认证票据
+ ///
+ ///
+ private AuthenticationTicket TicketConver(List claims)
+ {
+ var claimsIdentity = new ClaimsIdentity(claims.ToArray(), AuthenticationSchemeNmae);
+ var principal = new ClaimsPrincipal(claimsIdentity);
+ return new AuthenticationTicket(principal, AuthenticationSchemeNmae);
+ }
+
+ protected async Task SendHttpRequestAsync(string url, IEnumerable> query, HttpMethod? httpMethod = null)
+ {
+ httpMethod = httpMethod ?? HttpMethod.Get;
+
+ var queryUrl = QueryHelpers.AddQueryString(url, query);
+ HttpResponseMessage response = null;
+ if (httpMethod == HttpMethod.Get)
+ {
+ response = await HttpClient.GetAsync(queryUrl);
+ }
+ else if (httpMethod == HttpMethod.Post)
+ {
+ response = await HttpClient.PostAsync(queryUrl, null);
+ }
+
+ var content = await response.Content.ReadAsStringAsync();
+ if (!response.IsSuccessStatusCode)
+ {
+ throw new Exception($"授权服务器请求错误,请求地址:{queryUrl},错误信息:{content}");
+ }
+ VerifyErrResponse(content);
+ var model = Newtonsoft.Json.JsonConvert.DeserializeObject(content);
+ return model!;
+ }
+
+ protected virtual void VerifyErrResponse(string content)
+ {
+ return;
+ }
+
+ protected abstract Task> GetAuthTicketAsync(string code);
+
+
+ protected override async Task HandleAuthenticateAsync()
+ {
+ if (!Context.Request.Query.ContainsKey("code"))
+ {
+ return AuthenticateResult.Fail("回调未包含code参数");
+ }
+ var code = Context.Request.Query["code"].ToString();
+
+ List authTicket = null;
+ try
+ {
+ authTicket = await GetAuthTicketAsync(code);
+ }
+ catch (Exception ex)
+ {
+ return AuthenticateResult.Fail(ex.Message ?? "未知错误");
+ }
+ //成功
+ var result = AuthenticateResult.Success(TicketConver(authTicket));
+ return result;
+ }
+ }
+}
+
+
diff --git a/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/QQ/QQAuthenticationConstants.cs b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/QQ/QQAuthenticationConstants.cs
new file mode 100644
index 00000000..bac733fa
--- /dev/null
+++ b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/QQ/QQAuthenticationConstants.cs
@@ -0,0 +1,27 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+ * See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers
+ * for more information concerning the license and the contributors participating to this project.
+ */
+
+namespace Yi.Framework.AspNetCore.Authentication.OAuth.QQ;
+
+///
+/// Contains constants specific to the .
+///
+public static class QQAuthenticationConstants
+{
+ public static class Claims
+ {
+ public const string AvatarFullUrl = "urn:qq:avatar_full";
+ public const string AvatarUrl = "urn:qq:avatar";
+ public const string PictureFullUrl = "urn:qq:picture_full";
+ public const string PictureMediumUrl = "urn:qq:picture_medium";
+ public const string PictureUrl = "urn:qq:picture";
+ public const string UnionId = "urn:qq:unionid";
+
+ public const string OpenId = "urn:openid";
+ public const string AccessToken = "urn:access_token";
+ public const string Name = "urn:name";
+ }
+}
diff --git a/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/QQ/QQAuthenticationDefaults.cs b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/QQ/QQAuthenticationDefaults.cs
new file mode 100644
index 00000000..61106b07
--- /dev/null
+++ b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/QQ/QQAuthenticationDefaults.cs
@@ -0,0 +1,53 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+ * See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers
+ * for more information concerning the license and the contributors participating to this project.
+ */
+
+namespace Yi.Framework.AspNetCore.Authentication.OAuth.QQ;
+
+///
+/// Default values for QQ authentication.
+///
+public static class QQAuthenticationDefaults
+{
+ ///
+ /// Default value for .
+ ///
+ public const string AuthenticationScheme = "QQ";
+
+ ///
+ /// Default value for .
+ ///
+ public static readonly string DisplayName = "QQ";
+
+ ///
+ /// Default value for .
+ ///
+ public static readonly string Issuer = "QQ";
+
+ ///
+ /// Default value for .
+ ///
+ public static readonly string CallbackPath = "/signin-qq";
+
+ ///
+ /// Default value for .
+ ///
+ public static readonly string AuthorizationEndpoint = "https://graph.qq.com/oauth2.0/authorize";
+
+ ///
+ /// Default value for .
+ ///
+ public static readonly string TokenEndpoint = "https://graph.qq.com/oauth2.0/token";
+
+ ///
+ /// Default value for .
+ ///
+ public static readonly string UserIdentificationEndpoint = "https://graph.qq.com/oauth2.0/me";
+
+ ///
+ /// Default value for .
+ ///
+ public static readonly string UserInformationEndpoint = "https://graph.qq.com/user/get_user_info";
+}
diff --git a/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/QQ/QQAuthenticationExtensions.cs b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/QQ/QQAuthenticationExtensions.cs
new file mode 100644
index 00000000..4ffac491
--- /dev/null
+++ b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/QQ/QQAuthenticationExtensions.cs
@@ -0,0 +1,77 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+ * See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers
+ * for more information concerning the license and the contributors participating to this project.
+ */
+
+using JetBrains.Annotations;
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Yi.Framework.AspNetCore.Authentication.OAuth.QQ;
+
+///
+/// Extension methods to add QQ authentication capabilities to an HTTP application pipeline.
+///
+public static class QQAuthenticationExtensions
+{
+ ///
+ /// Adds to the specified
+ /// , which enables QQ authentication capabilities.
+ ///
+ /// The authentication builder.
+ /// The .
+ public static AuthenticationBuilder AddQQ([NotNull] this AuthenticationBuilder builder)
+ {
+ return builder.AddQQ(QQAuthenticationDefaults.AuthenticationScheme, options => { });
+ }
+
+ ///
+ /// Adds to the specified
+ /// , which enables QQ authentication capabilities.
+ ///
+ /// The authentication builder.
+ /// The delegate used to configure the OpenID 2.0 options.
+ /// The .
+ public static AuthenticationBuilder AddQQ(
+ [NotNull] this AuthenticationBuilder builder,
+ [NotNull] Action configuration)
+ {
+ return builder.AddQQ(QQAuthenticationDefaults.AuthenticationScheme, configuration);
+ }
+
+ ///
+ /// Adds to the specified
+ /// , which enables QQ authentication capabilities.
+ ///
+ /// The authentication builder.
+ /// The authentication scheme associated with this instance.
+ /// The delegate used to configure the QQ options.
+ /// The .
+ public static AuthenticationBuilder AddQQ(
+ [NotNull] this AuthenticationBuilder builder,
+ [NotNull] string scheme,
+ [NotNull] Action configuration)
+ {
+ return builder.AddQQ(scheme, QQAuthenticationDefaults.DisplayName, configuration);
+ }
+
+ ///
+ /// Adds to the specified
+ /// , which enables QQ authentication capabilities.
+ ///
+ /// The authentication builder.
+ /// The authentication scheme associated with this instance.
+ /// The optional display name associated with this instance.
+ /// The delegate used to configure the QQ options.
+ /// The .
+ public static AuthenticationBuilder AddQQ(
+ [NotNull] this AuthenticationBuilder builder,
+ [NotNull] string scheme,
+ [CanBeNull] string caption,
+ [NotNull] Action configuration)
+ {
+ return builder.AddScheme(scheme, caption, configuration);
+
+ }
+}
diff --git a/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/QQ/QQAuthenticationHandler.cs b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/QQ/QQAuthenticationHandler.cs
new file mode 100644
index 00000000..3f342496
--- /dev/null
+++ b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/QQ/QQAuthenticationHandler.cs
@@ -0,0 +1,70 @@
+using System.Security.Claims;
+using System.Text.Encodings.Web;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using static Yi.Framework.AspNetCore.Authentication.OAuth.QQ.QQAuthenticationConstants;
+
+namespace Yi.Framework.AspNetCore.Authentication.OAuth.QQ
+{
+ public class QQAuthenticationHandler : OauthAuthenticationHandler
+ {
+ public QQAuthenticationHandler(IOptionsMonitor options, ILoggerFactory logger, UrlEncoder encoder, IHttpClientFactory httpClientFactory) : base(options, logger, encoder, httpClientFactory)
+ {
+ }
+
+ public override string AuthenticationSchemeNmae => QQAuthenticationDefaults.AuthenticationScheme;
+
+ protected override void VerifyErrResponse(string content)
+ {
+ QQAuthticationErrCodeModel.VerifyErrResponse(content);
+ }
+
+ protected override async Task> GetAuthTicketAsync(string code)
+ {
+
+ //获取 accessToken
+ var tokenQueryKv = new List>()
+ {
+ new KeyValuePair("grant_type","authorization_code"),
+ new KeyValuePair("client_id",Options.ClientId),
+ new KeyValuePair("client_secret",Options.ClientSecret),
+ new KeyValuePair("redirect_uri",Options.RedirectUri),
+ new KeyValuePair("fmt","json"),
+ new KeyValuePair("need_openid","1"),
+ new KeyValuePair("code",code),
+ new KeyValuePair("state","true"),
+ };
+ var tokenModel = await SendHttpRequestAsync(QQAuthenticationDefaults.TokenEndpoint, tokenQueryKv);
+
+
+
+ //获取 userInfo
+ var userInfoQueryKv = new List>()
+ {
+ new KeyValuePair("access_token",tokenModel.access_token),
+ new KeyValuePair("oauth_consumer_key",Options.ClientId),
+ new KeyValuePair("openid",tokenModel.openid),
+ };
+
+ var userInfoMdoel = await SendHttpRequestAsync(QQAuthenticationDefaults.UserInformationEndpoint, userInfoQueryKv);
+
+
+ List claims = new List()
+ {
+
+ new Claim(Claims.AvatarFullUrl, userInfoMdoel.figureurl_qq_2),
+ new Claim(Claims.AvatarUrl, userInfoMdoel.figureurl_qq_1),
+ new Claim(Claims.PictureFullUrl, userInfoMdoel.figureurl_2),
+ new Claim(Claims.PictureMediumUrl, userInfoMdoel.figureurl_qq_1),
+ new Claim(Claims.PictureUrl, userInfoMdoel.figureurl),
+
+ new Claim(Claims.OpenId, tokenModel.openid),
+ new Claim(Claims.Name, userInfoMdoel.nickname),
+ new Claim(Claims.AccessToken, tokenModel.access_token),
+
+ };
+ return claims;
+
+ }
+ }
+}
diff --git a/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/QQ/QQAuthenticationOptions.cs b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/QQ/QQAuthenticationOptions.cs
new file mode 100644
index 00000000..c82c44d2
--- /dev/null
+++ b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/QQ/QQAuthenticationOptions.cs
@@ -0,0 +1,51 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+ * See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers
+ * for more information concerning the license and the contributors participating to this project.
+ */
+
+using System.Security.Claims;
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Authentication.OAuth;
+using static Yi.Framework.AspNetCore.Authentication.OAuth.QQ.QQAuthenticationConstants;
+
+namespace Yi.Framework.AspNetCore.Authentication.OAuth.QQ;
+
+///
+/// Defines a set of options used by .
+///
+public class QQAuthenticationOptions : OAuthOptions
+{
+ public QQAuthenticationOptions()
+ {
+ ClaimsIssuer = QQAuthenticationDefaults.Issuer;
+ CallbackPath = QQAuthenticationDefaults.CallbackPath;
+
+ AuthorizationEndpoint = QQAuthenticationDefaults.AuthorizationEndpoint;
+ TokenEndpoint = QQAuthenticationDefaults.TokenEndpoint;
+ UserIdentificationEndpoint = QQAuthenticationDefaults.UserIdentificationEndpoint;
+ UserInformationEndpoint = QQAuthenticationDefaults.UserInformationEndpoint;
+
+ Scope.Add("get_user_info");
+
+ ClaimActions.MapJsonKey(ClaimTypes.Name, "nickname");
+ ClaimActions.MapJsonKey(ClaimTypes.Gender, "gender");
+ ClaimActions.MapJsonKey(Claims.PictureUrl, "figureurl");
+ ClaimActions.MapJsonKey(Claims.PictureMediumUrl, "figureurl_1");
+ ClaimActions.MapJsonKey(Claims.PictureFullUrl, "figureurl_2");
+ ClaimActions.MapJsonKey(Claims.AvatarUrl, "figureurl_qq_1");
+ ClaimActions.MapJsonKey(Claims.AvatarFullUrl, "figureurl_qq_2");
+ }
+
+ ///
+ /// Gets or sets if the union Id (the primary key of an owner for different apps of the QQ platform) should be put into the user claims.
+ ///
+ public bool ApplyForUnionId { get; set; }
+
+ ///
+ /// Gets or sets the URL of the user identification endpoint (a.k.a. the "OpenID endpoint").
+ ///
+ public string UserIdentificationEndpoint { get; set; }
+
+ public string RedirectUri { get; set; }
+}
diff --git a/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/QQ/QQAuthticationErrCodeModel.cs b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/QQ/QQAuthticationErrCodeModel.cs
new file mode 100644
index 00000000..b84824bf
--- /dev/null
+++ b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/QQ/QQAuthticationErrCodeModel.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json;
+using System.Threading.Tasks;
+
+
+namespace Yi.Framework.AspNetCore.Authentication.OAuth.QQ
+{
+ public class QQAuthticationErrCodeModel
+ {
+ public string error { get; set; }
+
+ public string error_description { get; set; }
+
+ public static void VerifyErrResponse(string content)
+ {
+
+ var model =Newtonsoft.Json.JsonConvert.DeserializeObject (content);
+ if (model.error != null)
+ {
+
+ throw new Exception($"第三方授权返回错误,错误码:【{model.error}】,错误详情:【{model.error_description}】");
+ }
+ }
+
+ }
+
+}
diff --git a/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/QQ/QQAuthticationcationHttpModel.cs b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/QQ/QQAuthticationcationHttpModel.cs
new file mode 100644
index 00000000..f9639f31
--- /dev/null
+++ b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/QQ/QQAuthticationcationHttpModel.cs
@@ -0,0 +1,89 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.AspNetCore.Authentication.OAuth.QQ
+{
+ public class QQAuthticationcationTokenResponse
+ {
+ public string access_token { get; set; }
+
+ public string expires_in { get; set; }
+
+ public string refresh_token { get; set; }
+
+ public string openid { get; set; }
+ }
+
+
+ public class QQAuthticationcationOpenIdResponse
+ {
+ public string client_id { get; set; }
+
+ public string openid { get; set; }
+
+ }
+
+ public class QQAuthticationcationUserInfoResponse
+ {
+ // 返回码
+ public int ret { get; set; }
+
+ // 如果ret<0,会有相应的错误信息提示
+ // 返回数据全部用UTF-8编码
+ public string msg { get; set; }
+
+ // 判断是否有数据丢失
+ // 0或者不返回:没有数据丢失,可以缓存
+ // 1:有部分数据丢失或错误,不要缓存
+ public int is_lost { get; set; }
+
+ // 用户在QQ空间的昵称
+ public string nickname { get; set; }
+
+ // 大小为30x30像素的QQ空间头像URL
+ public string figureurl { get; set; }
+
+ // 大小为50x50像素的QQ空间头像URL
+ public string figureurl_1 { get; set; }
+
+ // 大小为100x100像素的QQ空间头像URL
+ public string figureurl_2 { get; set; }
+
+ // 大小为40x40像素的QQ头像URL
+ public string figureurl_qq_1 { get; set; }
+
+ // 大小为100x100像素的QQ头像URL
+ // 需要注意,不是所有的用户都拥有QQ的100x100的头像,但40x40像素则是一定会有
+ public string figureurl_qq_2 { get; set; }
+
+ // 性别。如果获取不到则默认返回"男"
+ public string gender { get; set; }
+
+ // 性别类型。默认返回2
+ public int gender_type { get; set; }
+
+ // 省
+ public string province { get; set; }
+
+ // 市
+ public string city { get; set; }
+
+ // 年
+ public int year { get; set; }
+
+ // 星座
+ public string constellation { get; set; }
+
+ // 标识用户是否为黄钻用户
+ public int is_yellow_vip { get; set; }
+
+ // 黄钻等级
+ public int yellow_vip_level { get; set; }
+
+ // 是否为年费黄钻用户
+ public int is_yellow_year_vip { get; set; }
+ }
+}
diff --git a/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/Yi.Framework.AspNetCore.Authentication.OAuth.csproj b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/Yi.Framework.AspNetCore.Authentication.OAuth.csproj
new file mode 100644
index 00000000..d3f7f9b9
--- /dev/null
+++ b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/Yi.Framework.AspNetCore.Authentication.OAuth.csproj
@@ -0,0 +1,12 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
diff --git a/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/YiFrameworkAspNetCoreAuthenticationOAuthModule.cs b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/YiFrameworkAspNetCoreAuthenticationOAuthModule.cs
new file mode 100644
index 00000000..f5783555
--- /dev/null
+++ b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore.Authentication.OAuth/YiFrameworkAspNetCoreAuthenticationOAuthModule.cs
@@ -0,0 +1,20 @@
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.Modularity;
+using Yi.Framework.Core;
+
+
+namespace Yi.Framework.AspNetCore.Authentication.OAuth
+{
+ ///
+ /// 本模块轮子来自 AspNet.Security.OAuth.QQ;
+ ///
+ [DependsOn(typeof(YiFrameworkAspNetCoreModule))]
+ public class YiFrameworkAspNetCoreAuthenticationOAuthModule:AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ var service = context.Services;
+ service.AddHttpClient();
+ }
+ }
+}
diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Services/Authentication/QQAuthService.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Services/Authentication/QQAuthService.cs
deleted file mode 100644
index 29695fdc..00000000
--- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Services/Authentication/QQAuthService.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Authentication;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.Extensions.Logging;
-using Quartz.Logging;
-using Volo.Abp;
-using Volo.Abp.DependencyInjection;
-
-namespace Yi.Framework.Bbs.Application.Services.Authentication
-{
- public class QQAuthService : IRemoteService, ITransientDependency
- {
- private HttpContext HttpContext { get; set; }
- private ILogger _logger;
- public QQAuthService(IHttpContextAccessor httpContextAccessor, ILogger logger)
- {
- _logger = logger;
- HttpContext = httpContextAccessor.HttpContext ?? throw new ApplicationException("未注册Http");
- }
- [HttpGet("/auth/qq")]
- public async Task AuthQQAsync()
- {
- var data = await HttpContext.AuthenticateAsync("QQ");
- _logger.LogError($"QQ回调信息:{Newtonsoft.Json.JsonConvert.SerializeObject(data)}");
- _logger.LogError($"QQ回调身份:{Newtonsoft.Json.JsonConvert.SerializeObject(data.Principal)}");
- }
- }
-}
diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.SqlSugarCore/DataSeeds/BbsDictionaryDataSeed.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.SqlSugarCore/DataSeeds/BbsDictionaryDataSeed.cs
index a3d59a8b..3c7c6dbf 100644
--- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.SqlSugarCore/DataSeeds/BbsDictionaryDataSeed.cs
+++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.SqlSugarCore/DataSeeds/BbsDictionaryDataSeed.cs
@@ -15,8 +15,8 @@ namespace Yi.Framework.Bbs.SqlSugarCore.DataSeeds
public class BbsDictionaryDataSeed : IDataSeedContributor, ITransientDependency
{
private ISqlSugarRepository _repository;
- private ISqlSugarRepository _typeRepository;
- public BbsDictionaryDataSeed(ISqlSugarRepository repository, ISqlSugarRepository typeRepository) {
+ private ISqlSugarRepository _typeRepository;
+ public BbsDictionaryDataSeed(ISqlSugarRepository repository, ISqlSugarRepository typeRepository) {
_repository=repository;
_typeRepository=typeRepository;
@@ -194,10 +194,10 @@ namespace Yi.Framework.Bbs.SqlSugarCore.DataSeeds
return entities;
}
- public List GetSeedDictionaryTypeData()
+ public List GetSeedDictionaryTypeData()
{
- List entities = new List();
- DictionaryTypeEntity dict1 = new DictionaryTypeEntity()
+ List entities = new List();
+ DictionaryTypeAggregateRoot dict1 = new DictionaryTypeAggregateRoot()
{
DictName = "BBS类型标签",
diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application.Contracts/Dtos/Account/AuthGetListInput.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application.Contracts/Dtos/Account/AuthGetListInput.cs
new file mode 100644
index 00000000..8149a728
--- /dev/null
+++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application.Contracts/Dtos/Account/AuthGetListInput.cs
@@ -0,0 +1,13 @@
+using Yi.Framework.Ddd.Application.Contracts;
+
+namespace Yi.Framework.Rbac.Application.Contracts.Dtos.Account
+{
+ public class AuthGetListInput:PagedAllResultRequestDto
+ {
+ public Guid? UserId { get; set; }
+
+ public string? OpenId { get; set; }
+
+ public string? AuthType { get; set; }
+ }
+}
diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application.Contracts/Dtos/Account/AuthOutputDto.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application.Contracts/Dtos/Account/AuthOutputDto.cs
new file mode 100644
index 00000000..f111b547
--- /dev/null
+++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application.Contracts/Dtos/Account/AuthOutputDto.cs
@@ -0,0 +1,17 @@
+using Volo.Abp.Application.Dtos;
+
+namespace Yi.Framework.Rbac.Application.Contracts.Dtos.Account
+{
+ public class AuthOutputDto:EntityDto
+ {
+ public Guid UserId { get; set; }
+
+ public string OpenId { get; set; }
+
+ public string Name { get; set; }
+
+ public string AuthType { get; set; }
+
+ public DateTime CreationTime { get; set; }
+ }
+}
diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/EventHandlers/StudentEventHandler.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/EventHandlers/StudentEventHandler.cs
index 4ded4f5d..776eea4a 100644
--- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/EventHandlers/StudentEventHandler.cs
+++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/EventHandlers/StudentEventHandler.cs
@@ -3,7 +3,7 @@ using Volo.Abp.Domain.Entities.Events;
using Volo.Abp.EventBus;
using Yi.Framework.Rbac.Domain.Entities;
-namespace Yi.Framework.Rbac.Domain.EventHandlers
+namespace Yi.Framework.Rbac.Application.EventHandlers
{
public class StudentEventHandler : ILocalEventHandler>, ITransientDependency
{
diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/AccountService.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/AccountService.cs
index f6c9462c..cb90fb1f 100644
--- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/AccountService.cs
+++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/AccountService.cs
@@ -1,15 +1,10 @@
-using System.IdentityModel.Tokens.Jwt;
-using System.Security.Claims;
-using System.Text;
-using System.Text.RegularExpressions;
+using System.Text.RegularExpressions;
using Lazy.Captcha.Core;
-using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Options;
-using Microsoft.IdentityModel.Tokens;
using SqlSugar;
using Volo.Abp;
using Volo.Abp.Application.Services;
@@ -27,7 +22,6 @@ using Yi.Framework.Rbac.Domain.Repositories;
using Yi.Framework.Rbac.Domain.Shared.Caches;
using Yi.Framework.Rbac.Domain.Shared.Consts;
using Yi.Framework.Rbac.Domain.Shared.Dtos;
-using Yi.Framework.Rbac.Domain.Shared.Etos;
using Yi.Framework.Rbac.Domain.Shared.Options;
using Yi.Framework.SqlSugarCore.Abstractions;
@@ -36,8 +30,6 @@ namespace Yi.Framework.Rbac.Application.Services
public class AccountService : ApplicationService, IAccountService
{
- private readonly ILocalEventBus _localEventBus;
- private readonly JwtOptions _jwtOptions;
private IDistributedCache _phoneCache;
private readonly ICaptcha _captcha;
private readonly IGuidGenerator _guidGenerator;
@@ -45,45 +37,30 @@ namespace Yi.Framework.Rbac.Application.Services
private readonly IAliyunManger _aliyunManger;
public AccountService(IUserRepository userRepository,
ICurrentUser currentUser,
- AccountManager accountManager,
+ IAccountManager accountManager,
ISqlSugarRepository menuRepository,
- IHttpContextAccessor httpContextAccessor,
- ILocalEventBus localEventBus,
- IOptions jwtOptions,
IDistributedCache phoneCache,
ICaptcha captcha,
IGuidGenerator guidGenerator,
IOptions options,
- IAliyunManger aliyunManger,
- ISqlSugarRepository roleRepository,
- UserManager userManager)
+ IAliyunManger aliyunManger)
{
_userRepository = userRepository;
_currentUser = currentUser;
_accountManager = accountManager;
_menuRepository = menuRepository;
- _httpContextAccessor = httpContextAccessor;
- _localEventBus = localEventBus;
- _jwtOptions = jwtOptions.Value;
_phoneCache = phoneCache;
_captcha = captcha;
_guidGenerator = guidGenerator;
_rbacOptions = options.Value;
_aliyunManger = aliyunManger;
- _roleRepository = roleRepository;
- _userManager = userManager;
}
private IUserRepository _userRepository;
private ICurrentUser _currentUser;
- private AccountManager _accountManager;
+ private IAccountManager _accountManager;
private ISqlSugarRepository _menuRepository;
- private IUserService _userService;
- private UserManager _userManager;
- private ISqlSugarRepository _roleRepository;
- private IHttpContextAccessor _httpContextAccessor;
-
///
/// 效验图片登录验证码,无需和账号绑定
///
@@ -117,59 +94,16 @@ namespace Yi.Framework.Rbac.Application.Services
ValidationImageCaptcha(input);
UserEntity user = new();
- //登录成功
+ //效验
await _accountManager.LoginValidationAsync(input.UserName, input.Password, x => user = x);
- //获取用户信息
- var userInfo = await _userRepository.GetUserAllInfoAsync(user.Id);
-
- //判断用户状态
- if (userInfo.User.State == false)
- {
- throw new UserFriendlyException(UserConst.State_Is_State);
- }
-
- if (userInfo.RoleCodes.Count == 0)
- {
- throw new UserFriendlyException(UserConst.No_Role);
- }
- //这里抛出一个登录的事件
- var loginEntity = new LoginLogEntity().GetInfoByHttpContext(_httpContextAccessor.HttpContext);
- var loginEto = loginEntity.Adapt();
- loginEto.UserName = input.UserName;
- loginEto.UserId = userInfo.User.Id;
- await _localEventBus.PublishAsync(loginEto);
- //将用户信息添加到缓存中,需要考虑的是更改了用户、角色、菜单等整个体系都需要将缓存进行刷新,看具体业务进行选择
+ //获取token
+ var accessToken = await _accountManager.GetTokenByUserIdAsync(user.Id);
-
- //创建token
- var accessToken = CreateToken(_accountManager.UserInfoToClaim(userInfo));
return new { Token = accessToken };
}
- ///
- /// 创建令牌
- ///
- ///
- ///
- private string CreateToken(List> kvs)
- {
- var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtOptions.SecurityKey));
- var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
- var claims = kvs.Select(x => new Claim(x.Key, x.Value.ToString())).ToList();
- var token = new JwtSecurityToken(
- issuer: _jwtOptions.Issuer,
- audience: _jwtOptions.Audience,
- claims: claims,
- expires: DateTime.Now.AddSeconds(_jwtOptions.ExpiresMinuteTime),
- notBefore: DateTime.Now,
- signingCredentials: creds);
- string returnToken = new JwtSecurityTokenHandler().WriteToken(token);
-
- return returnToken;
- }
-
///
/// 生成验证码
@@ -267,7 +201,7 @@ namespace Yi.Framework.Rbac.Application.Services
///
[AllowAnonymous]
[UnitOfWork]
- public async Task