XkwOAuth2Controller.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. using Microsoft.AspNetCore.Mvc;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Threading.Tasks;
  6. using TEAMModelOS.Models;
  7. using TEAMModelOS.SDK.DI;
  8. using System.Text.Json;
  9. using TEAMModelOS.SDK.Models;
  10. using Microsoft.AspNetCore.Http;
  11. using TEAMModelOS.SDK.Extension;
  12. using Azure.Cosmos;
  13. using System.Text;
  14. using TEAMModelOS.SDK.DI.AzureCosmos.Inner;
  15. using Microsoft.Extensions.Options;
  16. using Azure.Messaging.ServiceBus;
  17. using Microsoft.Extensions.Configuration;
  18. using HTEXLib.COMM.Helpers;
  19. using TEAMModelOS.SDK;
  20. using System.IdentityModel.Tokens.Jwt;
  21. using TEAMModelOS.Services;
  22. using TEAMModelOS.SDK.Models.Service;
  23. using System.IO;
  24. using System.Dynamic;
  25. using Microsoft.AspNetCore.Authorization;
  26. using Azure.Storage.Blobs.Models;
  27. using static TEAMModelOS.SDK.Models.Teacher;
  28. using System.Web;
  29. using static TEAMModelOS.Controllers.FixDataController;
  30. using static TEAMModelOS.SDK.SchoolService;
  31. using Microsoft.AspNetCore.Hosting;
  32. using TEAMModelOS.Filter;
  33. using TEAMModelOS.Controllers.Third.Xkw;
  34. using Microsoft.Extensions.Primitives;
  35. using System.Net.Http;
  36. namespace TEAMModelOS.Controllers
  37. {
  38. // <summary>
  39. /// 标准OAuth2
  40. /// </summary>
  41. ///
  42. [ProducesResponseType(StatusCodes.Status200OK)]
  43. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  44. //
  45. //[Route("")]
  46. [Route("xkw")]
  47. [ApiController]
  48. public class XkwOAuth2Controller : ControllerBase
  49. {
  50. private readonly SnowflakeId _snowflakeId;
  51. private readonly AzureCosmosFactory _azureCosmos;
  52. private readonly DingDing _dingDing;
  53. private readonly Option _option;
  54. private readonly AzureStorageFactory _azureStorage;
  55. private readonly AzureServiceBusFactory _serviceBus;
  56. private readonly AzureRedisFactory _azureRedis;
  57. private readonly CoreAPIHttpService _coreAPIHttpService;
  58. private readonly ThirdApisService _scsApisService;
  59. private readonly HttpTrigger _httpTrigger;
  60. private readonly IWebHostEnvironment _environment;
  61. /// <summary>
  62. /// 机构安全码
  63. /// </summary>
  64. public string _sc_passKey;
  65. /// <summary>
  66. /// 机构ID
  67. /// </summary>
  68. public string _sc_trainComID;
  69. /// <summary>
  70. /// 机构 AES 密钥
  71. /// </summary>
  72. public string _sc_privateKey;
  73. /// <summary>
  74. /// 访问地址
  75. /// </summary>
  76. public string _sc_url;
  77. public IConfiguration _configuration { get; set; }
  78. public XkwOAuth2Controller(IWebHostEnvironment environment, AzureCosmosFactory azureCosmos, SnowflakeId snowflakeId, DingDing dingDing, IOptionsSnapshot<Option> option, AzureStorageFactory azureStorage,
  79. AzureRedisFactory azureRedis, AzureServiceBusFactory serviceBus, IConfiguration configuration, CoreAPIHttpService coreAPIHttpService, ThirdApisService scsApisService, HttpTrigger httpTrigger)
  80. {
  81. _azureCosmos = azureCosmos;
  82. _snowflakeId = snowflakeId;
  83. _dingDing = dingDing;
  84. _option = option?.Value;
  85. _azureStorage = azureStorage;
  86. _serviceBus = serviceBus;
  87. _configuration = configuration;
  88. _azureRedis = azureRedis;
  89. _coreAPIHttpService = coreAPIHttpService;
  90. _scsApisService = scsApisService;
  91. _httpTrigger = httpTrigger;
  92. _environment = environment;
  93. }
  94. /// <summary>
  95. /// 标准OAuth2 方式的回调地址。
  96. /// </summary>D:\VisualStudioProjects\TEAMModelOS\TEAMModelOS.SDK\Models\Service\Third\ScYxptModel.cs
  97. /// <param name="request"></param>
  98. /// <returns></returns>
  99. [HttpPost("oauth")]
  100. [Authorize(Roles = "IES")]
  101. [AuthToken(Roles = "teacher,admin,area,student")]
  102. public async Task<IActionResult> Aauth(OAuthCode authCode) {
  103. //https://ssoserviceurl/oauth2/authorize?client_id=APPKEY&openid=OPENID=&service=SERVICE
  104. var (tmdid, _, _, school) = HttpContext.GetAuthTokenInfo();
  105. StringValues accessToken = "";//应该从别的地方获取 不是mvc 无法从Session 获取
  106. HttpContext.Request.Headers.TryGetValue($"XKW-AccessToken", out accessToken);
  107. if (!_option.Location.Contains("China"))
  108. {
  109. return BadRequest();
  110. }
  111. var client = await GetOpenAuthClient(tmdid, accessToken);
  112. if (authCode.agree == 1) {
  113. //获取醍摩豆id的手机号
  114. var keys =new List<string> { tmdid};
  115. var content = new StringContent(keys.ToJsonString(), Encoding.UTF8, "application/json");
  116. string ujson = await _coreAPIHttpService.GetUserInfos(content);
  117. List<CoreUser> coreUsers = new List<CoreUser>(0);
  118. if (!string.IsNullOrWhiteSpace(ujson))
  119. {
  120. coreUsers = ujson.ToObject<List<CoreUser>>();
  121. if (coreUsers.Any() ) {
  122. client.Extra = coreUsers.Find(x=>x.searchKey.Equals(tmdid))?.mobile;
  123. }
  124. }
  125. }
  126. string url = client.GetAuthorizationUrl();
  127. return Ok(new { redirect = url });
  128. }
  129. [HttpPost("authorize")]
  130. [Authorize(Roles = "IES")]
  131. [AuthToken(Roles = "teacher,admin,area,student")]
  132. public async Task<IActionResult> Authorize(OAuthCode authCode )
  133. {
  134. var (tmdid, _, _, school) = HttpContext.GetAuthTokenInfo();
  135. StringValues accessToken ;//应该从别的地方获取 不是mvc 无法从Session 获取
  136. HttpContext.Request.Headers.TryGetValue($"XKW-AccessToken", out accessToken);
  137. if (!_option.Location.Contains("China"))
  138. {
  139. return BadRequest();
  140. }
  141. //没有获取到codes的情况
  142. if (string.IsNullOrEmpty(authCode.code))
  143. {
  144. return RedirectToAction("Index");
  145. }
  146. var client =await GetOpenAuthClient(tmdid, accessToken);
  147. string schoolId = "tmdedu";
  148. if (_option.Location.Contains("Test", StringComparison.OrdinalIgnoreCase) || _option.Location.Contains("Dep", StringComparison.OrdinalIgnoreCase))
  149. {
  150. schoolId = "3082";
  151. }
  152. client.GetAccessTokenByCode(authCode.code, schoolId);
  153. //未登录已认证学科网用户
  154. if (string.IsNullOrEmpty(client.UserId) || "".Equals(client.UserId.Trim()))
  155. {
  156. return Redirect($"bind?status=0&accessToken={client.AccessToken}&openId={client.OpenId}&userId={client.UserId}&msg={HttpUtility.UrlEncode("未登录")}");
  157. }
  158. if (string.IsNullOrEmpty(client.OpenId))
  159. {
  160. string errorMsg = "学科网"+client.ErrorMessage;
  161. return Redirect($"bind?status=0&accessToken={client.AccessToken}&openId={client.OpenId}&userId={client.UserId}&msg={HttpUtility.UrlEncode(errorMsg)}");
  162. }
  163. if (client.IsAuthorized || !string.IsNullOrWhiteSpace(client.OpenId))
  164. {
  165. return Redirect($"bind?status=1&accessToken={client.AccessToken}&openId={client.OpenId}&userId={client.UserId}&msg={HttpUtility.UrlEncode("认证成功")}");
  166. }
  167. else
  168. {
  169. return Redirect($"bind?status=0&accessToken={client.AccessToken}&openId={client.OpenId}&userId={client.UserId}&msg={HttpUtility.UrlEncode("认证失败")}");
  170. }
  171. }
  172. [HttpGet("bind")]
  173. public async Task<IActionResult> Bind([FromQuery] XkwBindModel authCode)
  174. {
  175. if (authCode.status == 1)
  176. {
  177. var table = _azureStorage.GetCloudTableClient().GetTableReference("IESOAuth");
  178. OAuthUser authUser = new OAuthUser
  179. {
  180. PartitionKey = "OAuthUser-Xkw",
  181. RowKey = authCode.userId,
  182. OpenId = authCode.openId,
  183. Time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
  184. Type = "Xkw"
  185. };
  186. await table.SaveOrUpdate<OAuthUser>(authUser);
  187. return Ok(new { status=authCode.status, msg = "绑定成功!" });
  188. }
  189. else {
  190. return Ok(new { status = authCode.status, msg = authCode.msg });
  191. }
  192. }
  193. [HttpGet("unbind")]
  194. public async Task<IActionResult> Unbind(String openId, String userId)
  195. {
  196. //bool ret = xkwOAuthTxtHelper.UnBindXkw(userId);
  197. //string msg = "无解绑关系";
  198. //if (ret)
  199. //{
  200. // openId = "";
  201. // msg = "解绑成功";
  202. //}
  203. //ViewBag.OpenId = openId;
  204. //ViewBag.UserId = userId;
  205. //ViewBag.Message = msg;
  206. return Ok();
  207. }
  208. /// <summary>
  209. /// 退出登录
  210. /// </summary>
  211. /// <returns></returns>
  212. [HttpGet("exit")]
  213. public ActionResult Exit()
  214. {
  215. //HttpCookie uk = new HttpCookie("userId");
  216. //uk.Value = "";
  217. //uk.Expires = DateTime.Now.AddDays(-10);
  218. //Response.Cookies.Set(uk);
  219. //return RedirectToAction("Index", "Demo");
  220. return Ok();
  221. }
  222. /// <summary>
  223. /// 封装一个方法来初始化OpenAuth客户端
  224. /// </summary>
  225. /// <returns></returns>
  226. private async Task<XkwOAuthClient> GetOpenAuthClient(string tmdid,string accessToken)
  227. {
  228. var table = _azureStorage.GetCloudTableClient().GetTableReference("IESOAuth");
  229. //var accessToken = Session["access_token"] == null ? string.Empty : (string)Session["access_token"];
  230. //var userId = Request.Cookies["userId"] == null ? string.Empty : Request.Cookies["userId"].Value;
  231. var userId = tmdid;//直接传递获取
  232. //var openId = xkwOAuthTxtHelper.GetOpenIdByUserId(userId);
  233. string openId =null;//直接从数据库获取
  234. // var settings = ConfigurationManager.AppSettings;
  235. // var client = new XkwOAuthClient(settings["OAuth_Xkw_AppKey"], settings["OAuth_Xkw_AppSecret"], settings["OAuth_Xkw_RedirectUrl"], settings["OAuth_Xkw_OAuthHost"], accessToken, openId, userId);
  236. List<OAuthUser> authUsers = await table.FindListByDict<OAuthUser>(new Dictionary<string, object>() { { "PartitionKey", "OAuthUser-Xkw" }, { "RowKey", tmdid } });
  237. if (authUsers.Any()) {
  238. openId = authUsers[0].OpenId;
  239. }
  240. string RowKey = "Xkw";
  241. if (_option.Location.Contains("Test", StringComparison.OrdinalIgnoreCase) || _option.Location.Contains("Dep", StringComparison.OrdinalIgnoreCase)) {
  242. RowKey = "Xkw-Test";
  243. }
  244. List<OAuthComConfig> configs = await table.FindListByDict<OAuthComConfig>(new Dictionary<string, object>() { { "PartitionKey", "OAuthComConfig" }, { "RowKey", RowKey } });
  245. if (configs.Any())
  246. {
  247. string OAuth_Xkw_AppKey = configs[0].AppKey;
  248. string OAuth_Xkw_AppSecret = configs[0].AppSecret;
  249. string OAuth_Xkw_RedirectUrl = configs[0].RedirectUrl;
  250. string OAuth_Xkw_OAuthHost = configs[0].OAuthHost;
  251. string OAuth_Xkw_ServiceUrl = configs[0].ServiceUrl;
  252. var client = new XkwOAuthClient(OAuth_Xkw_AppKey, OAuth_Xkw_AppSecret, OAuth_Xkw_RedirectUrl, OAuth_Xkw_OAuthHost, accessToken, openId, userId);
  253. client.SERVICE_URL = OAuth_Xkw_ServiceUrl;
  254. return client;
  255. }
  256. else {
  257. return null;
  258. }
  259. }
  260. }
  261. }