refactor: 优化第三方登陆认证流程
This commit is contained in:
parent
9c0324002a
commit
d0ac2373ae
|
@ -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}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
/// 通过登录账号获得用户信息
|
/// 通过登录账号获得用户信息
|
||||||
|
|
Loading…
Reference in New Issue