/// <summary> /// 获取指定用户的SSO令牌信息。如果本站点不是SSO管理站点,则从管理站点获取 /// </summary> /// <param name="userHandle"></param> /// <param name="timeOutMs"></param> /// <param name="dataAccess">可选参数:数据库访问器。如果调用时使用了数据库事务,需要将开启了事务的数据库访问器传递进来,避免在本方法中查询数据库时因事务锁表而死锁。</param> /// <returns></returns> public static string GetToken(LibHandle userHandle, int timeOutMs = 30 * 1000, LibDataAccess dataAccess = null) { if (userHandle == null || string.IsNullOrEmpty(userHandle.UserId)) { return(string.Empty); } if (EnvProvider.Default.IsSSOManageSite) { return(userHandle.GetToCheckToken()); } if (string.IsNullOrEmpty(EnvProvider.Default.SSOManageSiteUrl)) { return(string.Empty); } try { string url = string.Format("{0}/sysSvc/getTokenByUserId", EnvProvider.Default.SSOManageSiteUrl); string password = string.Empty; string sql = string.Format("select USERPASSWORD from AXPUSER where USERID={0} And ISUSE=1", LibStringBuilder.GetQuotString(userHandle.UserId)); if (dataAccess == null) { password = LibSysUtils.ToString((new LibDataAccess()).ExecuteScalar(sql)); } else { password = LibSysUtils.ToString(dataAccess.ExecuteScalar(sql)); } var postP = new { userId = userHandle.UserId, pwd = password }; string errorInfo = string.Empty; dynamic result = LibNetUtils.HttpPostCall <dynamic>(url, postP, out errorInfo, timeOutMs); if (string.IsNullOrEmpty(errorInfo) == false || result == null) { return(string.Empty); } else { return((string)result.GetTokenByUserIdResult); } } catch (Exception exp) { LibCommUtils.AddOutput("CrossSiteCall", string.Format("error:{0}\r\nStacktrace:{1}", exp.Message, exp.StackTrace)); return(string.Empty); } }
/// <summary> /// 向SSOManage站点发起校验令牌信息的请求 /// </summary> /// <param name="ssoInfo">包含令牌信息的参数</param> /// <param name="timeOutMs">超时时间,单位为毫秒,默认为5000毫秒</param> /// <returns>如果验证成功返回true,否则返回false</returns> public static bool CheckSSOLoginState(SSOInfo ssoInfo, int timeOutMs = 5000) { if (ssoInfo == null || string.IsNullOrEmpty(ssoInfo.UserId) || string.IsNullOrEmpty(ssoInfo.Token)) { return(false); } if (EnvProvider.Default.IsSSOManageSite) { LibHandle handle = LibHandleCache.Default.IsExistsHandle(LibHandeleType.PC, ssoInfo.UserId); if (handle != null) { return(handle.Token == ssoInfo.Token); } return(false); } if (string.IsNullOrEmpty(EnvProvider.Default.SSOManageSiteUrl)) { return(false); } try { string url = string.Format("{0}/sysSvc/CheckSSOLoginState", EnvProvider.Default.SSOManageSiteUrl); var postP = new { ssoInfo = ssoInfo }; string errorInfo = string.Empty; dynamic result = LibNetUtils.HttpPostCall <dynamic>(url, postP, out errorInfo, timeOutMs); if (string.IsNullOrEmpty(errorInfo) == false || result == null) { return(false); } else { // 私钥解密 string ret = LibRSAHelper.Decrypt((string)result.CheckSSOLoginStateResult);//对于直接返回基本类型的接口调用,结果会包装成方法名+Result return(ret == "0"); } } catch (Exception exp) { LibCommUtils.AddOutput("CrossSiteCall", string.Format("CheckSSOLoginState error:{0}\r\nStacktrace:{1}", exp.Message, exp.StackTrace)); return(false); } }
/// <summary> /// 在跨站登陆前,访问获取Token /// </summary> /// <param name="userHandle">当前用户句柄</param> /// <returns></returns> public string GetToken(string userHandle) { LibHandle handle = LibHandleCache.Default.GetCurrentHandle(userHandle); if (handle == null) { return(string.Empty); } if (EnvProvider.Default.IsSSOManageSite) { return(handle.GetToCheckToken()); } else { try { string sql = string.Format("select USERPASSWORD from AXPUSER where USERID = {0}", LibStringBuilder.GetQuotString(handle.UserId)); LibDataAccess dataAccess = new LibDataAccess(); var pwd = dataAccess.ExecuteScalar(sql); if (pwd == null) { return(string.Empty); } string baseUrl = EnvProvider.Default.SSOManageSiteUrl; string url = baseUrl + "/sysSvc/getTokenByUserId"; string errorInfo = ""; dynamic obj = LibNetUtils.HttpPostCall <dynamic>(url, new { userId = handle.UserId, pwd = pwd.ToString() }, out errorInfo); if (string.IsNullOrEmpty(errorInfo)) { string token = obj.GetTokenByUserIdResult.Value; return(token); } return(string.Empty); } catch (Exception) { return(string.Empty); //throw; } } }
private bool CheckToken(SSOInfo ssoInfo) { if (EnvProvider.Default.IsSSOManageSite) { LibHandle handle = LibHandleCache.Default.IsExistsHandle(LibHandeleType.PC, ssoInfo.UserId); if (handle != null) { if (handle.Token == ssoInfo.Token) { return(true); } } } else { try { string baseUrl = EnvProvider.Default.SSOManageSiteUrl; string url = baseUrl + "/sysSvc/checkSSOLoginState"; string errorInfo = ""; dynamic obj = LibNetUtils.HttpPostCall <dynamic>(url, new { ssoInfo = ssoInfo }, out errorInfo); if (string.IsNullOrEmpty(errorInfo)) { string ret = LibRSAHelper.Decrypt(obj.CheckSSOLoginStateResult.Value); if (ret == "0") { return(true); } } } catch (Exception) { //throw; } } return(false); }
/// <summary> /// 向多个目标站点发起跨站Bcf方法调用请求。 /// 此方法执行时会阻塞 /// 如果有向多个站点请求执行,会同时(并发线程)向多个站点发起请求,请求完毕后再汇总执行结果返回 /// 如果参数有误会抛出异常 /// </summary> /// <param name="handle">当前用户的标识Handle</param> /// <param name="linkSiteIds">目标站点代码列表</param> /// <param name="callParams">包含SSO令牌信息、请求方法、请求参数等callParams</param> /// <param name="dataAccess">可选参数:数据库访问器。如果调用时使用了数据库事务,需要将开启了事务的数据库访问器传递进来,避免在本方法中查询数据库时因事务锁表而死锁。</param> /// <returns>返回执行结果字典,键值为目标站点Id,值为执行结果</returns> public static Dictionary <string, ExecuteBcfMethodResult> CrossSiteBcfCall(string handle, List <string> linkSiteIds, ExecuteBcfMethodParam callParams, LibDataAccess dataAccess = null) { if (string.IsNullOrEmpty(handle) || linkSiteIds == null || linkSiteIds.Count == 0 || callParams == null) { throw new ArgumentNullException("handle、linkSiteIds、callParams", "检查参数时发现有空参数。"); } LibHandle libHandle = LibHandleCache.Default.GetCurrentHandle(handle) as LibHandle; if (libHandle == null) { throw new Exception("该账户未登录。"); } callParams.IsCrossSiteCall = true; callParams.UserId = libHandle.UserId; callParams.Token = GetToken(libHandle, 30 * 1000, dataAccess); if (string.IsNullOrEmpty(callParams.Token)) { throw new Exception("获取跨站访问令牌信息失败。"); } Dictionary <string, string> urls = GetSiteUrls(linkSiteIds); if (urls == null || urls.Count == 0) { throw new Exception("查找到的站点Url为空。"); } Dictionary <string, ExecuteBcfMethodResult> dicResults = new Dictionary <string, ExecuteBcfMethodResult>(); string errorInfo = string.Empty; List <Task> tasks = new List <Task>(); foreach (string siteId in urls.Keys) { var url = urls[siteId]; if (string.IsNullOrEmpty(url)) { continue; } url = string.Format("{0}/billSvc/invorkBcf", url); var task = Task.Factory.StartNew(() => { try { var sendObj = new { param = callParams };//参数名必须一致 dynamic ret = LibNetUtils.HttpPostCall <dynamic>(url, sendObj, out errorInfo, callParams.TimeoutMillSecs); if (ret != null) { ExecuteBcfMethodResult result = JsonConvert.DeserializeObject <ExecuteBcfMethodResult>((string)ret.ExecuteBcfMethodResult); lock (dicResults) { dicResults.Add(siteId, result); } } else if (string.IsNullOrEmpty(errorInfo) == false) { ExecuteBcfMethodResult result = new ExecuteBcfMethodResult(); result.Messages.Add(new LibMessage() { MessageKind = LibMessageKind.Error, Message = string.Format("执行跨站请求出现异常:{0}", errorInfo) }); lock (dicResults) { dicResults.Add(siteId, result); } } } catch (Exception exp) { LibCommUtils.AddOutput(@"Error\CrossSiteCall", string.Format("CheckSSOLoginState error:{0}\r\nStacktrace:{1}", exp.Message, exp.StackTrace)); ExecuteBcfMethodResult result = new ExecuteBcfMethodResult(); result.Messages.Add(new LibMessage() { MessageKind = LibMessageKind.Error, Message = string.Format("执行跨站请求出现异常:{0}", exp.Message) }); lock (dicResults) { dicResults.Add(siteId, result); } } }); tasks.Add(task); } //循环检查等待所有task都执行完毕 int waitMillSecs = callParams.TimeoutMillSecs + 1000;//多等一秒 int waitCount = 0; //等待超时时间到来,或者全部已经执行完毕 while (waitCount < waitMillSecs) { bool isAllFinished = tasks.All(t => { return(t.IsCompleted); }); if (isAllFinished) { break; } waitCount += 100; Thread.Sleep(100); } return(dicResults); }