原理:客户访问我的超链接,传来一个key值,我通过这个key‘值去客户的esb系统去验证,若验证成功,返回用户信息,我拿到用户信息,跟本地服务器的用户信息进行比对,若一致,跳过登陆页面,直接授权进入系统。客户是内网,域名又有限制,访问不到接口,只能进行远程调试;因为获取用户用的是soap协议,所以还需要生成wsdl文件的代理类。
主要代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
using System.Security.Cryptography;
using TechExcel.Project.DataAccess;
using TechExcel.Project.DataAccess.Service;
using TechExcel.Project.DataAccess.Utility;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.IO;
using System.Xml;
using TechExcel.PPM.ProjectWeb.WebServiceEastHope;
namespace TechExcel.PPM.ProjectWeb
{
public partial class SSOLogin4EastHope : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
CookieContainer cookieContainer = new CookieContainer();
string url = ConfigurationManager.AppSettings.Get("EastHopeEsbUrl");//esb接口的url
string strUser= string.Empty;//用户信息
string token = string.Empty;//key值
string iPlanetDirectoryProVal = string.Empty;//
int timeout = 0;
string userAgent = string.Empty;
string strLang = string.Empty;
int nLangID = 0;
int.TryParse(strLang, out nLangID);
string strRuntimeKey = string.Empty;
if (Request.Cookies == null)
{
Response.Write("cookie is null");
//Response.Redirect("login.aspx");
return;
}
if (HttpContext.Current.Request.Cookies["tokenID"] != null)
{
iPlanetDirectoryProVal = HttpContext.Current.Request.Cookies["tokenID"].Value;
}
if (HttpContext.Current.Request.Cookies["iPlanetDirectoryPro"] != null)
{
string tokenTemp = HttpContext.Current.Request.Cookies["iPlanetDirectoryPro"].Value;
Response.Write("iPlanetDirectoryPro is not null " + tokenTemp);
string xmlToken=GetXml(tokenTemp);
//拿到cookies的key值并且生成xml数据的格式之后,到ESB系统获取用户信息
//Cookie cookie = new Cookie("tokenID", tokenTemp);
//HttpHelper httpR = new HttpHelper();
//HttpWebResponse re = httpR.CreateGetHttpResponse(url, timeout, userAgent, cookie,xmlToken);
AuthenticationWSClient authticayion=new AuthenticationWSClient();
string xmlIn=authticayion.getTokenUser(xmlToken);
if (xmlIn != null)
{
//string xmlIn = new StreamReader(re.GetResponseStream(), Encoding.UTF8).ReadToEnd();
strUser = getXmlUser(xmlIn);
Response.Write("xmlIn is not null " + xmlToken + " xmlIn:"+xmlIn+" strUser:"+strUser);
if (strUser != null)
{
if (SSOAuthentication(nLangID, strRuntimeKey, strUser))
return;
}
}
else
{
Response.Write("re is null "+xmlToken);
}
}
Response.Write(" token is null");
//Response.Redirect("login.aspx");
Response.End();
}
public string GetXml(string tokenID)//要发送的XML
{
StringBuilder strBuilder = new StringBuilder();
strBuilder.Append("");
//strBuilder.Append("");
//strBuilder.Append(" ");
//strBuilder.Append("");
// strBuilder.Append(" ");
//strBuilder.Append(" ");
strBuilder.Append("");
strBuilder.Append("");
strBuilder.Append(tokenID);
strBuilder.Append(" ");
strBuilder.Append(" ");
//strBuilder.Append(" ");
//strBuilder.Append(" ");
// strBuilder.Append(" ");
//strBuilder.Append(" ");
return strBuilder.ToString();
}
private string getXmlUser(string xml)
{
XmlDocument xmlDoc = new XmlDocument();
try
{
xmlDoc.LoadXml(xml);
XmlNodeList xnList = xmlDoc.SelectNodes("//ESBMessage/DATA/ITEM");
Console.WriteLine("共有{0}个节点", xnList.Count);//输出xnList中节点个数。
foreach (XmlNode xn in xnList)
{
//无法使用xn["ActivityId"].InnerText
string userIF = (xn.SelectSingleNode("USERID")).InnerText;
return userIF;
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return null;
}
private bool SSOAuthentication(int languageID, string runtimeKey, string ssoKey)
{
string client = Request.UserHostAddress;//获取用户的客户端的主机地址
try
{
//? SSOHelper
TechExcel.SSO.ISSOHandle ssoHandler = SSOHelper.GetSSOHandle();
if (ssoHandler != null)
{
//验证用户是否存在我们的数据库中
TechExcel.SSO.ValidateResult result = ssoHandler.ValidateTicket(ssoKey);
if (result.Code == 1)
{
//定义url,usernam两个变量接收他们的值
string url = String.Empty;
string userName = result.Username;
int enableValidateClientIP = 0;
int.TryParse(ConfigurationManager.AppSettings["EnableValidateClientIP"], out enableValidateClientIP);
//Response.Redirect(GetFriendlyUrl('terry-j', 78, 0), false);
SystemDataHandler handler = new SystemDataHandler();
//TUserLoginData data = handler.UserSSOLoginEx(client, userName, languageID, enableValidateClientIP);
TUserLoginData data = handler.UserSSOLoginEx(client, userName, languageID, enableValidateClientIP);
if (data != null)//如果data不为null,表示授权成功,并成功跳过登陆界面
{
//给客户端设置session的值
SetSessionValue(data.UserID, data.SessionID, 0, languageID);
//如果runtime存在的话,就加上runtime的后缀,如果runtime没有值,那就不设置后缀
if (runtimeKey == "")
{
url = "ProjectFrame.aspx";
}
else
{
url = string.Format("ProjectFrame.aspx?RuntimeKey={0}", runtimeKey);
}
Response.Redirect(GetFriendlyUrl(data.UserID, data.SessionID, languageID), false);
return true;
}
}
else
{
string strLoginurl = ssoHandler.GetLoginUrl();
Response.Redirect("login.aspx");
Response.End();
}
}
}
catch
{
}
return false;
}
private string GetFriendlyUrl(int userID, int SessionID, int languageID)
{
TTabSetting setting = UserPreferenceService.GetUserTabSetting(userID, SessionID, languageID);
string selectedHash = setting.SelectedTabHash;
return "#" + selectedHash.Trim(new char[] { ' ', '#' });
}
private void SetSessionValue(int userid, int sessionid, int ldapid, int languageid)
{
//获取客户端的主机地址
string client = Request.UserHostAddress;
//然后将他们转化为一个字符串对象的形式
string data = string.Format("{0}&{1}&{2}&{3}&{4}&{5}", userid, sessionid, ldapid, languageid, client, DateTime.Now.Ticks);
//以下在返回的reposnse中创建三个cookies
HttpCookie cookie = Response.Cookies["DevSuiteWebUserData"];
cookie.Expires = DateTime.Now.AddYears(1);//设置cookies的超时时间为一年,不设置的话,默认值是session,就是将和session一起失效
cookie.HttpOnly = true;//设置js脚本禁止读取cookies的信息,这样有效防止了cookie被人攻击,提高安全性
cookie.Secure = Request.IsSecureConnection;//secure属性可防止信息在传递的过程中被监听捕获后导致信息泄露,如果设置为true,可以限制只有通过https访问时,才会将浏览器保存的cookie传递到服务端,如果通过http访问,不会传递cookie。
cookie.Value = DESHelper.EncryptData(data);//将cookies进行加密
cookie = Response.Cookies["txdevtrackltmsid"];
cookie.Expires = DateTime.Now.AddYears(1);
cookie.HttpOnly = true;
cookie.Secure = Request.IsSecureConnection;
cookie.Value = DESHelper.EncryptData_DevTrack(string.Format("{0}", sessionid));//
cookie = Response.Cookies["DSCSID"];
cookie.Expires = DateTime.Now.AddYears(1);
cookie.HttpOnly = true;
cookie.Secure = Request.IsSecureConnection;
cookie.Value = DESHelper.EncryptData_DevSpec(string.Format("{0}&{1}", sessionid, userid));
}
}
///
/// 创建GET方式的HTTP请求
///
///
public class HttpHelper
{
public HttpWebResponse CreateGetHttpResponse(string url, int timeout, string userAgent,Cookie cookie,string xmlToken)
{
if (string.IsNullOrEmpty(url))
{
throw new ArgumentNullException("url");
}
HttpWebRequest request = null;
HttpWebResponse res;
request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "text/xml";
request.Headers.Add("charset:utf-8");
if (xmlToken != null)
{
var encoding = Encoding.GetEncoding("utf-8");
byte[] buffer = encoding.GetBytes(xmlToken);
request.ContentLength = buffer.Length;
request.GetRequestStream().Write(buffer, 0, buffer.Length);
}
if(false)
{
try
{
request.CookieContainer = new CookieContainer();
request.CookieContainer.Add(cookie);
}
catch (CookieException ex)
{
}
}
//设置代理UserAgent和超时
//request.UserAgent = userAgent;
//request.Timeout = timeout;
try
{
res = (HttpWebResponse)request.GetResponse();
return res;
}
catch (WebException ex)
{
res = (HttpWebResponse)ex.Response;
}
return res;
}
}
}
因为写完代码不能直接就发布,我这边是自己模拟了客户的后台环境进行了简单的测试,当然这个测试没有利用soap协议,是post的http方式。代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
using System.Security.Cryptography;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.IO;
using System.Xml;
namespace WebApplication1
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (getXmlUser() == "13jklj")
{
string xmlRepon = GetXml("terry-j");
Response.ContentType = "text/xml";
Response.Write(xmlRepon.ToString());
Response.End();
}
}
public XmlDocument GetDataSet()
{
try
{
Stream inputstream = Request.InputStream;
byte[] b = new byte[inputstream.Length];
inputstream.Read(b, 0, (int)inputstream.Length);
string inputstr = UTF8Encoding.UTF8.GetString(b);
XmlDocument d = new XmlDocument();
d.LoadXml(inputstr);
return d;
}
catch
{
}
return null;
}
public string GetXml(string tokenID)//要发送的XML
{
StringBuilder strBuilder = new StringBuilder();
strBuilder.Append("");
strBuilder.Append("");
strBuilder.Append("");
strBuilder.Append("- ");
strBuilder.Append("
");
strBuilder.Append(tokenID);
strBuilder.Append(" ");
strBuilder.Append(" ");
strBuilder.Append("");
strBuilder.Append(" ");
return strBuilder.ToString();
}
private string getXmlUser()
{
XmlDocument xmlDoc = GetDataSet();
try
{
XmlNodeList xnList = xmlDoc.SelectNodes("//params");
Console.WriteLine("共有{0}个节点", xnList.Count);//输出xnList中节点个数。
foreach (XmlNode xn in xnList)
{
//无法使用xn["ActivityId"].InnerText
string userIF = (xn.SelectSingleNode("tokenID")).InnerText;
return userIF;
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return null;
}
}
}