refactor: 优化第三方登陆认证流程

This commit is contained in:
Argo Zhang 2019-09-18 21:10:29 +08:00 committed by Argo Zhang
parent 9c0324002a
commit d0ac2373ae
No known key found for this signature in database
GPG Key ID: 152E398953DDF19F
2 changed files with 37 additions and 60 deletions

View File

@ -1,12 +1,10 @@
using Bootstrap.Security; using Longbow.OAuth;
using Longbow.Configuration;
using Longbow.OAuth;
using Longbow.Security.Cryptography; using Longbow.Security.Cryptography;
using Microsoft.AspNetCore.Authentication.OAuth;
using Microsoft.AspNetCore.WebUtilities; using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net.Http; using System.Net.Http;
@ -19,8 +17,6 @@ namespace Bootstrap.DataAccess
/// </summary> /// </summary>
public static class OAuthHelper public static class OAuthHelper
{ {
private static readonly ConcurrentDictionary<string, OAuthUser> _pool = new ConcurrentDictionary<string, OAuthUser>();
/// <summary> /// <summary>
/// 设置 GiteeOptions.Events.OnCreatingTicket 方法 /// 设置 GiteeOptions.Events.OnCreatingTicket 方法
/// </summary> /// </summary>
@ -29,13 +25,9 @@ namespace Bootstrap.DataAccess
{ {
option.Events.OnCreatingTicket = async context => option.Events.OnCreatingTicket = async context =>
{ {
var user = context.User.ToObject<OAuthUser>();
user.Schema = context.Scheme.Name;
_pool.AddOrUpdate(user.Login, userName => user, (userName, u) => { u = user; return user; });
// call webhook // call webhook
var config = context.HttpContext.RequestServices.GetRequiredService<IConfiguration>(); var config = context.HttpContext.RequestServices.GetRequiredService<IConfiguration>();
var webhookUrl = config.GetValue($"{option.GetType().Name}:StarredUrl", ""); var webhookUrl = config.GetSection<TOptions>().GetValue("StarredUrl", "");
if (!string.IsNullOrEmpty(webhookUrl)) if (!string.IsNullOrEmpty(webhookUrl))
{ {
var webhookParameters = new Dictionary<string, string>() var webhookParameters = new Dictionary<string, string>()
@ -48,8 +40,13 @@ namespace Bootstrap.DataAccess
await context.Backchannel.SendAsync(requestMessage, context.HttpContext.RequestAborted); 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
/// </summary> /// </summary>
/// <param name="userName"></param> /// <param name="userName"></param>
/// <returns></returns> /// <returns></returns>
public static BootstrapUser RetrieveUserByUserName<TOptions>(string userName) where TOptions : LgbOAuthOptions private static User ParseUser(OAuthCreatingTicketContext context)
{ {
User ret = null; var user = context.User.ToObject<OAuthUser>();
var user = _pool.TryGetValue(userName, out var giteeUser) ? giteeUser : null; return new User()
if (user != null)
{ {
var option = ConfigurationManager.Get<TOptions>(); ApprovedBy = "OAuth",
ret = new User() ApprovedTime = DateTime.Now,
{ DisplayName = user.Name,
ApprovedBy = "OAuth", UserName = user.Login,
ApprovedTime = DateTime.Now, Password = LgbCryptography.GenerateSalt(),
DisplayName = user.Name, Icon = user.Avatar_Url,
UserName = user.Login, Description = $"{context.Scheme.Name}({user.Id})"
Password = LgbCryptography.GenerateSalt(), };
Icon = user.Avatar_Url, }
Description = $"{user.Schema}({user.Id})",
App = option.App
};
DbContextManager.Create<User>().Save(ret);
CacheCleanUtility.ClearCache(cacheKey: UserHelper.RetrieveUsersDataKey);
// 根据配置文件设置默认角色 /// <summary>
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); /// </summary>
RoleHelper.SaveByUserId(usr.Id, roles); /// <param name="newUser"></param>
} /// <param name="roles"></param>
return ret; internal static void SaveUser(User newUser, IEnumerable<string> roles)
{
var uid = UserHelper.Retrieves().FirstOrDefault(u => u.UserName == newUser.UserName)?.Id;
if (uid != null) DbContextManager.Create<User>().Delete(new string[] { uid });
DbContextManager.Create<User>().Save(newUser);
// 根据配置文件设置默认角色
var roleIds = DbContextManager.Create<Role>().Retrieves().Where(r => roles.Any(rl => rl.Equals(r.RoleName, StringComparison.OrdinalIgnoreCase))).Select(r => r.Id);
DbContextManager.Create<Role>().SaveByUserId(newUser.Id, roleIds);
CacheCleanUtility.ClearCache(userIds: new string[0], roleIds: new string[0], cacheKey: $"{UserHelper.RetrieveUsersByNameDataKey}-{newUser.UserName}");
} }
} }
} }

View File

@ -1,8 +1,6 @@
using Bootstrap.Security; using Bootstrap.Security;
using Bootstrap.Security.DataAccess; using Bootstrap.Security.DataAccess;
using Longbow.Cache; using Longbow.Cache;
using Longbow.GiteeAuth;
using Longbow.GitHubAuth;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -297,28 +295,7 @@ namespace Bootstrap.DataAccess
/// </summary> /// </summary>
/// <param name="identity"></param> /// <param name="identity"></param>
/// <returns></returns> /// <returns></returns>
public static BootstrapUser RetrieveUserByUserName(IIdentity identity) => CacheManager.GetOrAdd(string.Format("{0}-{1}", RetrieveUsersByNameDataKey, identity.Name), k => public static BootstrapUser RetrieveUserByUserName(IIdentity identity) => CacheManager.GetOrAdd(string.Format("{0}-{1}", RetrieveUsersByNameDataKey, identity.Name), k => DbContextManager.Create<User>().RetrieveUserByUserName(identity.Name), RetrieveUsersByNameDataKey);
{
var userName = identity.Name;
var proxyList = new List<Func<string, BootstrapUser>>();
// 本地数据库认证
proxyList.Add(DbContextManager.Create<User>().RetrieveUserByUserName);
// Gitee 认证
if (identity.AuthenticationType == GiteeDefaults.AuthenticationScheme) proxyList.Add(OAuthHelper.RetrieveUserByUserName<GiteeOptions>);
// GitHub 认证
if (identity.AuthenticationType == GitHubDefaults.AuthenticationScheme) proxyList.Add(OAuthHelper.RetrieveUserByUserName<GitHubOptions>);
BootstrapUser user = null;
foreach (var p in proxyList)
{
user = p.Invoke(userName);
if (user != null) break;
}
return user;
}, RetrieveUsersByNameDataKey);
/// <summary> /// <summary>
/// 通过登录账号获得用户信息 /// 通过登录账号获得用户信息