From b1135d96f103087917e6b6bb3c399f8a2f7a0e10 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Wed, 18 Sep 2019 19:58:04 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1=E7=99=BB=E9=99=86=E8=AE=A4=E8=AF=81=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Bootstrap.Admin/Controllers/AccountController.cs | 12 ++++++++++++ src/admin/Bootstrap.Admin/Startup.cs | 2 +- src/admin/Bootstrap.Admin/Views/Account/Login.cshtml | 4 ++-- .../Bootstrap.Admin/appsettings.Development.json | 10 ++++++++++ .../Bootstrap.DataAccess/Bootstrap.DataAccess.csproj | 3 ++- 5 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/admin/Bootstrap.Admin/Controllers/AccountController.cs b/src/admin/Bootstrap.Admin/Controllers/AccountController.cs index 197e5fc7..5ef4b84d 100644 --- a/src/admin/Bootstrap.Admin/Controllers/AccountController.cs +++ b/src/admin/Bootstrap.Admin/Controllers/AccountController.cs @@ -3,6 +3,7 @@ using Bootstrap.DataAccess; using Longbow.GiteeAuth; using Longbow.GitHubAuth; using Longbow.Web; +using Longbow.WeChatAuth; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authorization; @@ -199,5 +200,16 @@ namespace Bootstrap.Admin.Controllers var enabled = config.GetValue($"{nameof(GitHubOptions)}:Enabled", false); return Challenge(enabled ? GitHubDefaults.AuthenticationScheme : CookieAuthenticationDefaults.AuthenticationScheme); } + + /// + /// WeChat 认证 + /// + /// + [HttpGet] + public IActionResult WeChat([FromServices]IConfiguration config) + { + var enabled = config.GetValue($"{nameof(GitHubOptions)}:Enabled", false); + return Challenge(enabled ? WeChatDefaults.AuthenticationScheme : CookieAuthenticationDefaults.AuthenticationScheme); + } } } diff --git a/src/admin/Bootstrap.Admin/Startup.cs b/src/admin/Bootstrap.Admin/Startup.cs index ce3f2689..095bfef3 100644 --- a/src/admin/Bootstrap.Admin/Startup.cs +++ b/src/admin/Bootstrap.Admin/Startup.cs @@ -60,7 +60,7 @@ namespace Bootstrap.Admin services.AddSignalR().AddJsonProtocalDefault(); services.AddSignalRExceptionFilterHandler((client, ex) => client.SendMessageBody(ex).ConfigureAwait(false)); services.AddResponseCompression(); - services.AddBootstrapAdminAuthentication().AddGitee(OAuthHelper.Configure).AddGitHub(OAuthHelper.Configure); + services.AddBootstrapAdminAuthentication().AddGitee(OAuthHelper.Configure).AddGitHub(OAuthHelper.Configure).AddWeChat(OAuthHelper.Configure); services.AddSwagger(); services.AddButtonAuthorization(MenuHelper.AuthorizateButtons); services.AddBootstrapAdminBackgroundTask(); diff --git a/src/admin/Bootstrap.Admin/Views/Account/Login.cshtml b/src/admin/Bootstrap.Admin/Views/Account/Login.cshtml index 7f3658ce..225df077 100644 --- a/src/admin/Bootstrap.Admin/Views/Account/Login.cshtml +++ b/src/admin/Bootstrap.Admin/Views/Account/Login.cshtml @@ -122,8 +122,8 @@
diff --git a/src/admin/Bootstrap.Admin/appsettings.Development.json b/src/admin/Bootstrap.Admin/appsettings.Development.json index 268521a3..db12e2cc 100644 --- a/src/admin/Bootstrap.Admin/appsettings.Development.json +++ b/src/admin/Bootstrap.Admin/appsettings.Development.json @@ -82,6 +82,16 @@ "App": "0", "StarredUrl": "https://api.github.com/user/starred/ArgoZhang/BootstrapAdmin" }, + "WeChatOptions": { + "Enabled": true, + "ClientId": "wxe2944ebb9e66551c", + "ClientSecret": "a4e36ddb18af218818e44bb7b8744fe6", + "CallbackPath": "/signin-weixin", + "HomePath": "/Admin/Profiles", + "Scope": [ "snsapi_login" ], + "Roles": [ "Administrators" ], + "App": "0" + }, "SMSOptions": { "CompanyCode": "", "MD5Key": "MD5Key", diff --git a/src/admin/Bootstrap.DataAccess/Bootstrap.DataAccess.csproj b/src/admin/Bootstrap.DataAccess/Bootstrap.DataAccess.csproj index a19f85b2..a5b9b2ad 100644 --- a/src/admin/Bootstrap.DataAccess/Bootstrap.DataAccess.csproj +++ b/src/admin/Bootstrap.DataAccess/Bootstrap.DataAccess.csproj @@ -7,13 +7,14 @@ - + + From 01f070415cea53241684feaf7d8f21b247280e30 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Wed, 18 Sep 2019 21:10:29 +0800 Subject: [PATCH 2/3] =?UTF-8?q?refactor:=20=E4=BC=98=E5=8C=96=E7=AC=AC?= =?UTF-8?q?=E4=B8=89=E6=96=B9=E7=99=BB=E9=99=86=E8=AE=A4=E8=AF=81=E6=B5=81?= =?UTF-8?q?=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Helper/OAuthHelper.cs | 72 +++++++++---------- .../Bootstrap.DataAccess/Helper/UserHelper.cs | 25 +------ 2 files changed, 37 insertions(+), 60 deletions(-) diff --git a/src/admin/Bootstrap.DataAccess/Helper/OAuthHelper.cs b/src/admin/Bootstrap.DataAccess/Helper/OAuthHelper.cs index f6b896c2..ce1e8608 100644 --- a/src/admin/Bootstrap.DataAccess/Helper/OAuthHelper.cs +++ b/src/admin/Bootstrap.DataAccess/Helper/OAuthHelper.cs @@ -1,12 +1,10 @@ -using Bootstrap.Security; -using Longbow.Configuration; -using Longbow.OAuth; +using Longbow.OAuth; using Longbow.Security.Cryptography; +using Microsoft.AspNetCore.Authentication.OAuth; using Microsoft.AspNetCore.WebUtilities; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using System; -using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Net.Http; @@ -19,8 +17,6 @@ namespace Bootstrap.DataAccess /// public static class OAuthHelper { - private static readonly ConcurrentDictionary _pool = new ConcurrentDictionary(); - /// /// 设置 GiteeOptions.Events.OnCreatingTicket 方法 /// @@ -29,13 +25,9 @@ namespace Bootstrap.DataAccess { option.Events.OnCreatingTicket = async context => { - var user = context.User.ToObject(); - user.Schema = context.Scheme.Name; - _pool.AddOrUpdate(user.Login, userName => user, (userName, u) => { u = user; return user; }); - // call webhook var config = context.HttpContext.RequestServices.GetRequiredService(); - var webhookUrl = config.GetValue($"{option.GetType().Name}:StarredUrl", ""); + var webhookUrl = config.GetSection().GetValue("StarredUrl", ""); if (!string.IsNullOrEmpty(webhookUrl)) { var webhookParameters = new Dictionary() @@ -48,8 +40,13 @@ namespace Bootstrap.DataAccess await context.Backchannel.SendAsync(requestMessage, context.HttpContext.RequestAborted); } + // 生成用户 + var user = ParseUser(context); + user.App = option.App; + SaveUser(user, option.Roles); + // 记录登陆日志 - context.HttpContext.Log(user.Name, true); + context.HttpContext.Log(user.UserName, true); }; } @@ -58,33 +55,36 @@ namespace Bootstrap.DataAccess /// /// /// - public static BootstrapUser RetrieveUserByUserName(string userName) where TOptions : LgbOAuthOptions + private static User ParseUser(OAuthCreatingTicketContext context) { - User ret = null; - var user = _pool.TryGetValue(userName, out var giteeUser) ? giteeUser : null; - if (user != null) + var user = context.User.ToObject(); + return new User() { - var option = ConfigurationManager.Get(); - ret = new User() - { - ApprovedBy = "OAuth", - ApprovedTime = DateTime.Now, - DisplayName = user.Name, - UserName = user.Login, - Password = LgbCryptography.GenerateSalt(), - Icon = user.Avatar_Url, - Description = $"{user.Schema}({user.Id})", - App = option.App - }; - DbContextManager.Create().Save(ret); - CacheCleanUtility.ClearCache(cacheKey: UserHelper.RetrieveUsersDataKey); + ApprovedBy = "OAuth", + ApprovedTime = DateTime.Now, + DisplayName = user.Name, + UserName = user.Login, + Password = LgbCryptography.GenerateSalt(), + Icon = user.Avatar_Url, + Description = $"{context.Scheme.Name}({user.Id})" + }; + } - // 根据配置文件设置默认角色 - var usr = UserHelper.Retrieves().First(u => u.UserName == userName); - var roles = RoleHelper.Retrieves().Where(r => option.Roles.Any(rl => rl.Equals(r.RoleName, StringComparison.OrdinalIgnoreCase))).Select(r => r.Id); - RoleHelper.SaveByUserId(usr.Id, roles); - } - return ret; + /// + /// 保存用户到数据库中 + /// + /// + /// + internal static void SaveUser(User newUser, IEnumerable roles) + { + var uid = UserHelper.Retrieves().FirstOrDefault(u => u.UserName == newUser.UserName)?.Id; + if (uid != null) DbContextManager.Create().Delete(new string[] { uid }); + DbContextManager.Create().Save(newUser); + + // 根据配置文件设置默认角色 + var roleIds = DbContextManager.Create().Retrieves().Where(r => roles.Any(rl => rl.Equals(r.RoleName, StringComparison.OrdinalIgnoreCase))).Select(r => r.Id); + DbContextManager.Create().SaveByUserId(newUser.Id, roleIds); + CacheCleanUtility.ClearCache(userIds: new string[0], roleIds: new string[0], cacheKey: $"{UserHelper.RetrieveUsersByNameDataKey}-{newUser.UserName}"); } } } diff --git a/src/admin/Bootstrap.DataAccess/Helper/UserHelper.cs b/src/admin/Bootstrap.DataAccess/Helper/UserHelper.cs index a5360faa..68c5628f 100644 --- a/src/admin/Bootstrap.DataAccess/Helper/UserHelper.cs +++ b/src/admin/Bootstrap.DataAccess/Helper/UserHelper.cs @@ -1,8 +1,6 @@ using Bootstrap.Security; using Bootstrap.Security.DataAccess; using Longbow.Cache; -using Longbow.GiteeAuth; -using Longbow.GitHubAuth; using System; using System.Collections.Generic; using System.Linq; @@ -297,28 +295,7 @@ namespace Bootstrap.DataAccess /// /// /// - public static BootstrapUser RetrieveUserByUserName(IIdentity identity) => CacheManager.GetOrAdd(string.Format("{0}-{1}", RetrieveUsersByNameDataKey, identity.Name), k => - { - var userName = identity.Name; - var proxyList = new List>(); - - // 本地数据库认证 - proxyList.Add(DbContextManager.Create().RetrieveUserByUserName); - - // Gitee 认证 - if (identity.AuthenticationType == GiteeDefaults.AuthenticationScheme) proxyList.Add(OAuthHelper.RetrieveUserByUserName); - - // GitHub 认证 - if (identity.AuthenticationType == GitHubDefaults.AuthenticationScheme) proxyList.Add(OAuthHelper.RetrieveUserByUserName); - - BootstrapUser user = null; - foreach (var p in proxyList) - { - user = p.Invoke(userName); - if (user != null) break; - } - return user; - }, RetrieveUsersByNameDataKey); + public static BootstrapUser RetrieveUserByUserName(IIdentity identity) => CacheManager.GetOrAdd(string.Format("{0}-{1}", RetrieveUsersByNameDataKey, identity.Name), k => DbContextManager.Create().RetrieveUserByUserName(identity.Name), RetrieveUsersByNameDataKey); /// /// 通过登录账号获得用户信息 From 847905adc66fbbb845a21ed118bda0593e4e1c9a Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Wed, 18 Sep 2019 21:28:12 +0800 Subject: [PATCH 3/3] =?UTF-8?q?refactor:=20=E5=A2=9E=E5=8A=A0=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1=E8=AE=A4=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/admin/Bootstrap.Admin/Startup.cs | 2 +- .../Helper/WeChatHelper.cs | 54 +++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 src/admin/Bootstrap.DataAccess/Helper/WeChatHelper.cs diff --git a/src/admin/Bootstrap.Admin/Startup.cs b/src/admin/Bootstrap.Admin/Startup.cs index 095bfef3..f4c94aa5 100644 --- a/src/admin/Bootstrap.Admin/Startup.cs +++ b/src/admin/Bootstrap.Admin/Startup.cs @@ -60,7 +60,7 @@ namespace Bootstrap.Admin services.AddSignalR().AddJsonProtocalDefault(); services.AddSignalRExceptionFilterHandler((client, ex) => client.SendMessageBody(ex).ConfigureAwait(false)); services.AddResponseCompression(); - services.AddBootstrapAdminAuthentication().AddGitee(OAuthHelper.Configure).AddGitHub(OAuthHelper.Configure).AddWeChat(OAuthHelper.Configure); + services.AddBootstrapAdminAuthentication().AddGitee(OAuthHelper.Configure).AddGitHub(OAuthHelper.Configure).AddWeChat(WeChatHelper.Configure); services.AddSwagger(); services.AddButtonAuthorization(MenuHelper.AuthorizateButtons); services.AddBootstrapAdminBackgroundTask(); diff --git a/src/admin/Bootstrap.DataAccess/Helper/WeChatHelper.cs b/src/admin/Bootstrap.DataAccess/Helper/WeChatHelper.cs new file mode 100644 index 00000000..491a4f63 --- /dev/null +++ b/src/admin/Bootstrap.DataAccess/Helper/WeChatHelper.cs @@ -0,0 +1,54 @@ +using Longbow.OAuth; +using Longbow.Security.Cryptography; +using Longbow.WeChatAuth; +using Microsoft.AspNetCore.Authentication.OAuth; +using System; + +namespace Bootstrap.DataAccess +{ + /// + /// 微信登陆帮助类 + /// + public static class WeChatHelper + { + /// + /// 微信登陆配置方法 + /// + /// + /// + public static void Configure(TOptions option) where TOptions : LgbOAuthOptions + { + option.Events.OnCreatingTicket = context => + { + // 生成用户 + var user = ParseUser(context); + user.App = option.App; + OAuthHelper.SaveUser(user, option.Roles); + + // 记录登陆日志 + context.HttpContext.Log(user.DisplayName, true); + return System.Threading.Tasks.Task.CompletedTask; + }; + } + + /// + /// 插入 Gitee 授权用户到数据库中 + /// + /// + /// + private static User ParseUser(OAuthCreatingTicketContext context) + { + var user = context.User.ToObject(); + return new User() + { + ApprovedBy = "OAuth", + ApprovedTime = DateTime.Now, + DisplayName = user.NickName, + UserName = user.UnionId, + Password = LgbCryptography.GenerateSalt(), + Icon = user.HeadImgUrl, + Description = $"{context.Scheme.Name}" + }; + } + } +}