XkwOAuth2Controller.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  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 HttpTrigger _httpTrigger;
  59. private readonly IWebHostEnvironment _environment;
  60. public IConfiguration _configuration { get; set; }
  61. public XkwOAuth2Controller(IWebHostEnvironment environment, AzureCosmosFactory azureCosmos, SnowflakeId snowflakeId, DingDing dingDing, IOptionsSnapshot<Option> option, AzureStorageFactory azureStorage,
  62. AzureRedisFactory azureRedis, AzureServiceBusFactory serviceBus, IConfiguration configuration, CoreAPIHttpService coreAPIHttpService, HttpTrigger httpTrigger)
  63. {
  64. _azureCosmos = azureCosmos;
  65. _snowflakeId = snowflakeId;
  66. _dingDing = dingDing;
  67. _option = option?.Value;
  68. _azureStorage = azureStorage;
  69. _serviceBus = serviceBus;
  70. _configuration = configuration;
  71. _azureRedis = azureRedis;
  72. _coreAPIHttpService = coreAPIHttpService;
  73. _httpTrigger = httpTrigger;
  74. _environment = environment;
  75. }
  76. /// <summary>
  77. /// 标准OAuth2 方式的回调地址。
  78. /// </summary>D:\VisualStudioProjects\TEAMModelOS\TEAMModelOS.SDK\Models\Service\Third\ScYxptModel.cs
  79. /// <param name="request"></param>
  80. /// <returns></returns>
  81. [HttpPost("oauth")]
  82. [Authorize(Roles = "IES")]
  83. [AuthToken(Roles = "teacher,admin,area,student")]
  84. public async Task<IActionResult> Aauth(OAuthCode authCode) {
  85. string domain = HttpContext?.Request?.Host.Host;
  86. if (domain.Equals("teammodelos.chinacloudsites.cn"))
  87. {
  88. domain = _option.HostName;
  89. }
  90. if (_option.Location.Equals("China"))
  91. {
  92. domain = _option.HostName;
  93. }
  94. // domain = "test.teammodel.cn";
  95. var req = HttpContext?.Request;
  96. //https://ssoserviceurl/oauth2/authorize?client_id=APPKEY&openid=OPENID=&service=SERVICE
  97. var (tmdid, _, _, school) = HttpContext.GetAuthTokenInfo();
  98. StringValues accessToken = "";//应该从别的地方获取 不是mvc 无法从Session 获取
  99. HttpContext.Request.Headers.TryGetValue($"xkw-AccessToken", out accessToken);
  100. if (!_option.Location.Contains("China"))
  101. {
  102. return BadRequest();
  103. }
  104. var client = await GetOpenAuthClient(tmdid,authCode.module, accessToken, domain);
  105. if (authCode.agree == 1) {
  106. //获取醍摩豆id的手机号
  107. var keys =new List<string> { tmdid};
  108. var content = new StringContent(keys.ToJsonString(), Encoding.UTF8, "application/json");
  109. string ujson = await _coreAPIHttpService.GetUserInfos(content);
  110. List<CoreUser> coreUsers = new List<CoreUser>(0);
  111. if (!string.IsNullOrWhiteSpace(ujson))
  112. {
  113. coreUsers = ujson.ToObject<List<CoreUser>>();
  114. if (coreUsers.Any() ) {
  115. var coreus = coreUsers.Find(x => x.searchKey.Equals(tmdid));
  116. if (coreus != null && !string.IsNullOrWhiteSpace(coreus.mobile)) {
  117. client.Extra = coreUsers.Find(x => x.searchKey.Equals(tmdid))?.mobile;
  118. }
  119. }
  120. }
  121. }
  122. string url = client.GetAuthorizationUrl();
  123. return Ok(new { redirect = url });
  124. }
  125. [HttpGet("authorize")]
  126. //[Authorize(Roles = "IES")]
  127. //[AuthToken(Roles = "teacher,admin,area,student")]
  128. public async Task<IActionResult> Authorize([FromQuery] OAuthCode authCode )
  129. {
  130. //var (tmdid, _, _, school) = HttpContext.GetAuthTokenInfo();
  131. StringValues accessToken ;//应该从别的地方获取 不是mvc 无法从Session 获取
  132. HttpContext.Request.Headers.TryGetValue($"xkw-AccessToken", out accessToken);
  133. if (!_option.Location.Contains("China"))
  134. {
  135. return BadRequest();
  136. }
  137. //没有获取到codes的情况
  138. if (string.IsNullOrEmpty(authCode.code))
  139. {
  140. return RedirectToAction("Index");
  141. }
  142. string domain = HttpContext?.Request?.Host.Host;
  143. if (domain.Equals("teammodelos.chinacloudsites.cn"))
  144. {
  145. domain = _option.HostName;
  146. }
  147. if (_option.Location.Equals("China")) {
  148. domain = _option.HostName;
  149. }
  150. var client =await GetOpenAuthClient(authCode.tmdid, authCode.module, accessToken, domain);
  151. string schoolId = "teammodel.cn";
  152. //学科网测试
  153. //if (schoolId.Equals("kong.sso.com"))
  154. //{
  155. // schoolId = "3082";
  156. //}
  157. client.GetAccessTokenByCode(authCode.code, schoolId);
  158. //未登录已认证学科网用户
  159. if (string.IsNullOrEmpty(client.UserId) || "".Equals(client.UserId.Trim()))
  160. {
  161. return Ok(new { status = 0, msg = "未登录" });
  162. // return Redirect($"bind?status=0&accessToken={client.AccessToken}&openId={client.OpenId}&userId={client.UserId}&domain={domain}&msg={HttpUtility.UrlEncode("未登录")}");
  163. }
  164. if (string.IsNullOrEmpty(client.OpenId))
  165. {
  166. string errorMsg = "学科网"+client.ErrorMessage;
  167. return Ok(new { status = 0, msg = errorMsg });
  168. // return Redirect($"bind?status=0&accessToken={client.AccessToken}&openId={client.OpenId}&userId={client.UserId}&domain={domain}&msg={HttpUtility.UrlEncode(errorMsg)}");
  169. }
  170. if (client.IsAuthorized || !string.IsNullOrWhiteSpace(client.OpenId))
  171. {
  172. var table = _azureStorage.GetCloudTableClient().GetTableReference("IESOAuth");
  173. OAuthUser authUser = new OAuthUser
  174. {
  175. PartitionKey = $"OAuthUser-xkw-{domain}",
  176. RowKey = client.UserId,
  177. OpenId = client.OpenId,
  178. Domain = domain,
  179. Time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
  180. Type = "xkw"
  181. };
  182. await table.SaveOrUpdate<OAuthUser>(authUser);
  183. //return Ok(new { status = 1, url=client.SERVICE_URL});
  184. return Redirect(client.SERVICE_URL);
  185. }
  186. else
  187. {
  188. return Ok(new { status = 0, msg = "认证失败" });
  189. // return Redirect($"bind?status=0&accessToken={client.AccessToken}&openId={client.OpenId}&userId={client.UserId}&domain={domain}&msg={HttpUtility.UrlEncode("认证失败")}");
  190. }
  191. }
  192. [HttpGet("bind")]
  193. public async Task<IActionResult> Bind([FromQuery] XkwBindModel authCode)
  194. {
  195. if (authCode.status == 1)
  196. {
  197. var table = _azureStorage.GetCloudTableClient().GetTableReference("IESOAuth");
  198. OAuthUser authUser = new OAuthUser
  199. {
  200. PartitionKey = $"OAuthUser-xkw-{authCode.domain}",
  201. RowKey = authCode.userId,
  202. OpenId = authCode.openId,
  203. Domain = authCode.domain,
  204. Time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
  205. Type = "xkw"
  206. };
  207. await table.SaveOrUpdate<OAuthUser>(authUser);
  208. return Ok(new { status=authCode.status, msg = "绑定成功!" });
  209. }
  210. else {
  211. return Ok(new { status = authCode.status, msg = authCode.msg });
  212. }
  213. }
  214. [HttpGet("unbind")]
  215. public async Task<IActionResult> Unbind(String openId, String userId)
  216. {
  217. //bool ret = xkwOAuthTxtHelper.UnBindXkw(userId);
  218. //string msg = "无解绑关系";
  219. //if (ret)
  220. //{
  221. // openId = "";
  222. // msg = "解绑成功";
  223. //}
  224. //ViewBag.OpenId = openId;
  225. //ViewBag.UserId = userId;
  226. //ViewBag.Message = msg;
  227. return Ok();
  228. }
  229. /// <summary>
  230. /// 退出登录
  231. /// </summary>
  232. /// <returns></returns>
  233. [HttpGet("exit")]
  234. public ActionResult Exit()
  235. {
  236. //HttpCookie uk = new HttpCookie("userId");
  237. //uk.Value = "";
  238. //uk.Expires = DateTime.Now.AddDays(-10);
  239. //Response.Cookies.Set(uk);
  240. //return RedirectToAction("Index", "Demo");
  241. return Ok();
  242. }
  243. /// <summary>
  244. /// 封装一个方法来初始化OpenAuth客户端
  245. /// </summary>
  246. /// <returns></returns>
  247. private async Task<XkwOAuthClient> GetOpenAuthClient(string tmdid,string module , string accessToken,string domain)
  248. {
  249. var table = _azureStorage.GetCloudTableClient().GetTableReference("IESOAuth");
  250. //var accessToken = Session["access_token"] == null ? string.Empty : (string)Session["access_token"];
  251. //var userId = Request.Cookies["userId"] == null ? string.Empty : Request.Cookies["userId"].Value;
  252. var userId = tmdid;//直接传递获取
  253. //var openId = xkwOAuthTxtHelper.GetOpenIdByUserId(userId);
  254. string openId ="";//直接从数据库获取
  255. // var settings = ConfigurationManager.AppSettings;
  256. // var client = new XkwOAuthClient(settings["OAuth_Xkw_AppKey"], settings["OAuth_Xkw_AppSecret"], settings["OAuth_Xkw_RedirectUrl"], settings["OAuth_Xkw_OAuthHost"], accessToken, openId, userId);
  257. List<OAuthUser> authUsers = await table.FindListByDict<OAuthUser>(new Dictionary<string, object>() { { "PartitionKey", $"OAuthUser-xkw-{domain}" }, { "RowKey", tmdid } });
  258. if (authUsers.Any()) {
  259. openId = authUsers[0].OpenId;
  260. }
  261. string RowKey = $"xkw-{domain}";
  262. List<OAuthComConfig> configs = await table.FindListByDict<OAuthComConfig>(new Dictionary<string, object>() { { "PartitionKey", "OAuthComConfig" }, { "RowKey", RowKey } });
  263. if (configs.Any())
  264. {
  265. string OAuth_Xkw_AppKey = configs[0].AppKey;
  266. string OAuth_Xkw_AppSecret = configs[0].AppSecret;
  267. string OAuth_Xkw_RedirectUrl = configs[0].RedirectUrl;
  268. string OAuth_Xkw_OAuthHost = configs[0].OAuthHost;
  269. string OAuth_Xkw_ServiceUrl = configs[0].ServiceUrl;
  270. try {
  271. List<ServiceModule> services= configs[0].ServiceUrl.ToObject<List<ServiceModule>>();
  272. ServiceModule serviceModule= services.Find(x => x.module.Equals(module));
  273. if (serviceModule != null)
  274. {
  275. OAuth_Xkw_ServiceUrl = serviceModule.url;
  276. if (serviceModule.module.Equals("ezj")) {
  277. string domain_port =domain;
  278. if (domain.Equals("kong.sso.com"))
  279. {
  280. domain_port = "kong.sso.com:5001";
  281. }
  282. OAuth_Xkw_ServiceUrl = OAuth_Xkw_ServiceUrl.Replace("{{iframe}}", HttpUtility.UrlEncode($"https://{domain_port}/home/newSchoolPaper"))
  283. .Replace("{{notice}}", HttpUtility.UrlEncode($"https://{domain_port}/home/newSchoolPaper"))
  284. //.Replace("{{notice}}", HttpUtility.UrlEncode($"https://{domain_port}/xkw/paper-notice"))
  285. .Replace("{{openid}}", openId).Replace("{{target}}", "");
  286. }
  287. }
  288. else {
  289. OAuth_Xkw_ServiceUrl = "http://www.zxxk.com/";
  290. }
  291. } catch (Exception ex) {
  292. if (!OAuth_Xkw_ServiceUrl.StartsWith("http://www.zxxk.com"))
  293. {
  294. OAuth_Xkw_ServiceUrl = "http://www.zxxk.com/";
  295. }
  296. }
  297. string OAuth_Xkw_Domain= configs[0].Domain;
  298. string OAuth_Xkw_Param =$"tmdid={tmdid}&module={module}&state={Guid.NewGuid().ToString()}";
  299. var client = new XkwOAuthClient(OAuth_Xkw_AppKey, OAuth_Xkw_AppSecret, OAuth_Xkw_RedirectUrl, OAuth_Xkw_OAuthHost, OAuth_Xkw_Domain, accessToken, openId, userId, OAuth_Xkw_Param);
  300. client.SERVICE_URL = OAuth_Xkw_ServiceUrl;
  301. return client;
  302. }
  303. else {
  304. return null;
  305. }
  306. }
  307. }
  308. }