SysOAuthService.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // 大名科技(天津)有限公司版权所有 电话:18020030720 QQ:515096995
  2. //
  3. // 此源代码遵循位于源代码树根目录中的 LICENSE 文件的许可证
  4. using Microsoft.AspNetCore.Authentication;
  5. using System.Security.Claims;
  6. namespace Admin.NET.Core.Service;
  7. /// <summary>
  8. /// 系统OAuth服务
  9. /// </summary>
  10. [AllowAnonymous]
  11. [ApiDescriptionSettings(Order = 495)]
  12. public class SysOAuthService : IDynamicApiController, ITransient
  13. {
  14. private readonly IHttpContextAccessor _httpContextAccessor;
  15. private readonly SqlSugarRepository<SysWechatUser> _sysWechatUserRep;
  16. public SysOAuthService(IHttpContextAccessor httpContextAccessor,
  17. SqlSugarRepository<SysWechatUser> sysWechatUserRep)
  18. {
  19. _httpContextAccessor = httpContextAccessor;
  20. _sysWechatUserRep = sysWechatUserRep;
  21. }
  22. /// <summary>
  23. /// 第三方登录
  24. /// </summary>
  25. /// <param name="provider"></param>
  26. /// <param name="redirectUrl"></param>
  27. /// <returns></returns>
  28. [ApiDescriptionSettings(Name = "SignIn"), HttpGet]
  29. [DisplayName("第三方登录")]
  30. public async Task<IActionResult> SignIn([FromQuery] string provider, [FromQuery] string redirectUrl)
  31. {
  32. if (string.IsNullOrWhiteSpace(provider) || !await _httpContextAccessor.HttpContext.IsProviderSupportedAsync(provider))
  33. throw Oops.Oh("不支持的OAuth类型");
  34. var request = _httpContextAccessor.HttpContext.Request;
  35. var url = $"{request.Scheme}://{request.Host}{request.PathBase}{request.Path}Callback?provider={provider}&redirectUrl={redirectUrl}";
  36. var properties = new AuthenticationProperties { RedirectUri = url };
  37. properties.Items["LoginProvider"] = provider;
  38. return await Task.FromResult(new ChallengeResult(provider, properties));
  39. }
  40. /// <summary>
  41. /// 授权回调
  42. /// </summary>
  43. /// <param name="provider"></param>
  44. /// <param name="redirectUrl"></param>
  45. /// <returns></returns>
  46. [ApiDescriptionSettings(Name = "SignInCallback"), HttpGet]
  47. [DisplayName("授权回调")]
  48. public async Task<IActionResult> SignInCallback([FromQuery] string provider = null, [FromQuery] string redirectUrl = "")
  49. {
  50. if (string.IsNullOrWhiteSpace(provider) || !await _httpContextAccessor.HttpContext.IsProviderSupportedAsync(provider))
  51. throw Oops.Oh("不支持的OAuth类型");
  52. var authenticateResult = await _httpContextAccessor.HttpContext.AuthenticateAsync(provider);
  53. if (!authenticateResult.Succeeded)
  54. throw Oops.Oh("授权失败");
  55. var openIdClaim = authenticateResult.Principal.FindFirst(ClaimTypes.NameIdentifier);
  56. if (openIdClaim == null || string.IsNullOrWhiteSpace(openIdClaim.Value))
  57. throw Oops.Oh("授权失败");
  58. var name = authenticateResult.Principal.FindFirst(ClaimTypes.Name)?.Value;
  59. var email = authenticateResult.Principal.FindFirst(ClaimTypes.Email)?.Value;
  60. var mobilePhone = authenticateResult.Principal.FindFirst(ClaimTypes.MobilePhone)?.Value;
  61. var dateOfBirth = authenticateResult.Principal.FindFirst(ClaimTypes.DateOfBirth)?.Value;
  62. var gender = authenticateResult.Principal.FindFirst(ClaimTypes.Gender)?.Value;
  63. var avatarUrl = "";
  64. var platformType = PlatformTypeEnum.微信公众号;
  65. if (provider == "Gitee")
  66. {
  67. platformType = PlatformTypeEnum.Gitee;
  68. avatarUrl = authenticateResult.Principal.FindFirst(OAuthClaim.GiteeAvatarUrl)?.Value;
  69. }
  70. // 若账号不存在则新建
  71. var wechatUser = await _sysWechatUserRep.AsQueryable().Includes(u => u.SysUser).ClearFilter().FirstAsync(u => u.OpenId == openIdClaim.Value);
  72. if (wechatUser == null)
  73. {
  74. var userId = await App.GetRequiredService<SysUserService>().AddUser(new AddUserInput()
  75. {
  76. Account = name,
  77. RealName = name,
  78. NickName = name,
  79. Email = email,
  80. Avatar = avatarUrl,
  81. Phone = mobilePhone,
  82. OrgId = 1300000000101, // 根组织架构
  83. RoleIdList = new List<long> { 1300000000104 } // 仅本人数据角色
  84. });
  85. await _sysWechatUserRep.InsertAsync(new SysWechatUser()
  86. {
  87. UserId = userId,
  88. OpenId = openIdClaim.Value,
  89. Avatar = avatarUrl,
  90. NickName = name,
  91. PlatformType = platformType
  92. });
  93. wechatUser = await _sysWechatUserRep.AsQueryable().Includes(u => u.SysUser).ClearFilter().FirstAsync(u => u.OpenId == openIdClaim.Value);
  94. }
  95. // 构建Token令牌
  96. var token = await App.GetRequiredService<SysAuthService>().CreateToken(wechatUser.SysUser);
  97. return new RedirectResult($"{redirectUrl}/#/login?token={token.AccessToken}");
  98. }
  99. }