系统需配合使用
validateServer中存放ServerCookie。
client中,第一次读页面时,needcheck必然为真,需要跳入server做验证,第二次做判断时
needcheck为假,在本地验证,过后needcheck马上变为真,因此,即使外部用户直接修改v参数,在
login前都不会建立用户对象,保证安全性
自己都已经有点忘记了用法,所以要保存下
server
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Security.Cryptography;
using System.IO;
using IMSCore.Longyeah;
using IMSCore.Longyeah.Data;
using Oracle.DataAccess.Client;
using System.Collections.Generic;
namespace ServerPage
{
public class Validate
{
#region 登陆 -- 补用户登陆的数据方法
/// <summary>
/// 验证登陆
/// </summary>
/// <param name="userName"></param>
/// <param name="password"></param>
/// <returns></returns>
public LoginResult Check(string userName, string password)
{
LoginResult lr = Validating.LoginMember(userName, password);
switch (lr)
{
case LoginResult.NoMember:
break;
case LoginResult.PasswordError:
break;
case LoginResult.Success:
HttpCookie myCookie = new HttpCookie("ServerUserSettings");
myCookie["Name"] = userName;
//cookie设为永久性,用于避免用户正在操作时cookie超时问题.客户端的cookie超时时间是无法获取的
myCookie.Expires = DateTime.Now.AddYears(50);
HttpContext.Current.Response.Cookies.Add(myCookie);
break;
}
return lr;
}
#endregion
#region 登出 -- 补查询所有模块地址的数据方法
public void SystemLogout()
{
//0.先检查本模块有无cookie
if (HttpContext.Current.Request.Cookies["ServerUserSettings"] == null)
{
//转回 跳入login
HttpContext.Current.Response.Redirect("Login.aspx");
}
//1.设定cookie记录申请退出状态
if (HttpContext.Current.Request.Cookies["RequestLogout"] == null)//假如cookies是空的,表明是刚申请退出
{
HttpCookie myCookie = new HttpCookie("RequestLogout");
//20分钟后删除
//开始处理cookie
//2.无数据,查数据库获取数据填充cookie
//在这里才填充cookie的好处是为了保证数据最新
string[] arrayaddress = { "http://192.168.2.135/client1/", "http://localhost/client2/", "http://192.168.2.7/client3/" };
//-- 模拟数据库 将所有地址添加入去
//字符数组处理
//拆分字符串,删除第一条并跳到那一条指定的页面
string tmplink = arrayaddress[0];
//--表示移出数据
string tmpaddress = "";
if (arrayaddress.Length > 1) //有多项才重组
{
for (int i = 1; i < arrayaddress.Length; i++)
{
if (i == 1)
{
tmpaddress = arrayaddress[i];
}
else
{
tmpaddress = tmpaddress + "," + arrayaddress[i];
}
}
}
//处理完毕设cookie值
myCookie["Address"] = tmpaddress;
//设cookie属性
myCookie.Expires = DateTime.Now.AddMinutes(20);
HttpContext.Current.Response.Cookies.Add(myCookie);//添加记录
//跳转
HttpContext.Current.Response.Redirect(tmplink + "logout.aspx?url=" + HttpContext.Current.Request.Url);
//跳转结束
}
else//已有申请退出,记录地址cookie串
{
if (HttpContext.Current.Request.Cookies["RequestLogout"]["Address"].Length > 0)//未跳完,继续处理
{
HttpCookie myCookie = new HttpCookie("RequestLogout");
//拆数组
string[] arrayaddress = HttpContext.Current.Request.Cookies["RequestLogout"]["Address"].Split(new char[] { ',' });
string tmplink = arrayaddress[0]; //第一项进行跳转
string tmpaddress = "";
if (arrayaddress.Length > 1) //有多项时才再组数组
{
for (int i = 1; i < arrayaddress.Length; i++)
{
if (i == 1)
{
tmpaddress = arrayaddress[i];
}
else
{
tmpaddress = tmpaddress + "," + arrayaddress[i];
}
}
}
//重设地址记录
myCookie["Address"] = tmpaddress;
HttpContext.Current.Response.Cookies.Add(myCookie);//添加记录
//跳转
HttpContext.Current.Response.Redirect(tmplink + "logout.aspx?url=" + HttpContext.Current.Request.Url);
//跳转结束
}
else
{
//已全部页面均跳完
//删除cookie
HttpCookie myCookie = new HttpCookie("RequestLogout");
//设置过时时间为一天前
myCookie.Expires = DateTime.Now.AddDays(-1);
HttpContext.Current.Response.Cookies.Add(myCookie);
}
}
//完成处理,返回,logout页面再控制validatelogout方法
}
/// <summary>
/// 本模块用户登出
/// </summary>
public void ValidateLogout()
{
//如果有cookie,重设超时时间用于删除本模块用户
if (HttpContext.Current.Request.Cookies["ServerUserSettings"] != null)
{
HttpCookie myCookie = new HttpCookie("ServerUserSettings");
//设置过时时间为一天前
myCookie.Expires = DateTime.Now.AddDays(-1);
HttpContext.Current.Response.Cookies.Add(myCookie);
HttpContext.Current.Response.Redirect("login.aspx");
}
}
#endregion
#region SSO -- 补通过module查allowhttp的数据方法
/// <summary>
/// 单点登陆,包含安全检查
/// </summary>
public void RemoteGet()
{
//检查进入的页面是否有权限 用module name查询出地址结构,然后使用string.indexof判断传来的页面是否为有效页面
//如果没有返回的url,跳入错误信息提示页面,防止死循环
if (HttpContext.Current.Request.QueryString["url"] == null || HttpContext.Current.Request.QueryString["url"] == "")
{
HttpContext.Current.Response.Redirect("Error.aspx"); //临时
}
//如果没有传递module参数即转入错误信息提示页面,防止死循环
if (HttpContext.Current.Request.QueryString["module"] == null || HttpContext.Current.Request.QueryString["module"] == "")
{
HttpContext.Current.Response.Redirect("Error.aspx"); //临时
}
//判断是不是有效页
//待数据库
//用indexof来做判断,数据库内容包含"http://";为>-1
//如果是有效页
string rurl = HttpContext.Current.Request.QueryString["url"];
if (rurl.IndexOf("?") > 0)
{
rurl = rurl + "&v=";
}
else
{
rurl = rurl + "?v=";
}
string Name = GetLoginedUser();
HttpContext.Current.Response.Redirect(rurl + DesEncrypt(Name));
}
/// <summary>
/// 供远程获取身份验证票
/// </summary>
/// <returns></returns>
public string GetLoginedUser()
{
//输出验证
if (HttpContext.Current.Request.Cookies["ServerUserSettings"] != null)
{
if (HttpContext.Current.Request.Cookies["ServerUserSettings"]["Name"] != null)
{
return HttpContext.Current.Request.Cookies["ServerUserSettings"]["Name"];
}
else
{
return "";
}
}
else
{
return "";
}
}
#endregion
#region DES对称加解密
/// <summary>
/// DES对称加密
/// </summary>
/// <param name="SourceStr">源需加密字符串</param>
/// <returns>加密字符串</returns>
public string DesEncrypt(string SourceStr)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
//需要改为从数据库读出密钥和向量
des.Key = System.Text.Encoding.Default.GetBytes("12345678");
des.IV = System.Text.Encoding.Default.GetBytes("ABCDEFGH");
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
StreamWriter sw = new StreamWriter(cs);
sw.Write(SourceStr);
sw.Flush();
cs.FlushFinalBlock();
ms.Flush();
//将byte[]转换为字符串输出
return Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length);
}
/// <summary>
/// DES对称解密
/// </summary>
/// <param name="SourceStr">源需解密字符串</param>
/// <returns>解密字符串</returns>
public string DesDecrypt(string SourceStr)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
//将源串转换为byte[]
byte[] buffer = Convert.FromBase64String(SourceStr);
//需要改为从数据库读出密钥和向量
des.Key = System.Text.Encoding.Default.GetBytes("12345678");
des.IV = System.Text.Encoding.Default.GetBytes("ABCDEFGH");
MemoryStream ms = new MemoryStream(buffer);
CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Read);
StreamReader sr = new StreamReader(cs);
return sr.ReadToEnd();
}
#endregion
}
}
client
//========================================================
//需使用单点登陆验证模块的客户模块页面验证类
//fwp 2007-7-20
//使用注意:除了引用项目外,需要在web.config里配置如下
//<appSettings>
// <!-- SSO登陆用url-->
// <add key="url" value="http://192.168.2.135/validate/check.aspx?url="/>
// <add key="module" value ="client1"/>
// </appSettings>
//
//========================================================
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Security.Cryptography;
using System.IO;
namespace ClientPage
{
/// <summary>
/// SSO的验证页面类
/// </summary>
public class ValidatePage : BasePage
{
#region 远程验证单点登陆
/// <summary>
/// 远程连接验证用户状态,实现单点登陆
/// </summary>
/// <param name="htc">页面内容</param>
public void Check()
{
if (!(HttpContext.Current.Request.Cookies["UserSettings"] == null || HttpContext.Current.Request.Cookies["UserSettings"]["Name"] == null))
{
return;
}
if (Session["NeedCheck"] == null || bool.Parse(Session["NeedCheck"].ToString()))
{
Session["NeedCheck"] = true;
}
if ((HttpContext.Current.Request.Cookies["UserSettings"] == null || HttpContext.Current.Request.Cookies["UserSettings"]["Name"] == null) && NeedCheck())
{
//本身的url处理并准备提交
string tmpstring = "";
string rUrl = "";
if (Request.QueryString.Count > 1) //超过一组键/值
{
//只要有键为v的就删除
if (Request.Url.ToString().IndexOf("?v=") > 0) //如在第一位
{
//为删除v=14位,需要将 ? + v=14 + &去除,共16位
tmpstring = Request.Url.ToString().Substring(Request.Url.ToString().IndexOf("?v="), 16);
//将?v=x&替换为?,重新返回url
rUrl = Request.Url.ToString().Replace(tmpstring, "?");
}
else if (Request.Url.ToString().IndexOf("&v=") > 0) //如在第二或其他位置
{
//为删除v=14位,需要将 & + v=14去除,共15位
tmpstring = Request.Url.ToString().Substring(Request.Url.ToString().IndexOf("&v="), 15);
//将 &v=x替换为空,重新返回url
rUrl = Request.Url.ToString().Replace(tmpstring, "");
}
else
{
rUrl = Request.Url.ToString();
}
}
else //只有一组键/值
{
if (Request.Url.ToString().IndexOf("?v=") > 0) //如存在
{
//需要将 ? + v=14去除,共15位
tmpstring = Request.Url.ToString().Substring(Request.Url.ToString().IndexOf("?v="), 15);
rUrl = Request.Url.ToString().Replace(tmpstring, ""); //将v参数去除
}
else
{
rUrl = Request.Url.ToString();
}
}
//url处理结束
Response.Redirect(System.Configuration.ConfigurationManager.AppSettings["url"].ToString() + rUrl +"&module=" + System.Configuration.ConfigurationManager.AppSettings["module"].ToString());
}
else
{
ServerReceived(Request.QueryString["v"]);
}
if (UserName != "")
{
HttpCookie myCookie = new HttpCookie("UserSettings");
myCookie["Name"] = UserName;
//cookie设为永久性,用于避免用户正在操作时cookie超时问题.客户端的cookie超时时间是无法获取的
myCookie.Expires = DateTime.Now.AddYears(50);
HttpContext.Current.Response.Cookies.Add(myCookie);
}
//为下一次刷新设置标志位
Session["NeedCheck"] = true;
}
/// <summary>
/// 验证是否已经进行远程服务器连接,避免发生死循环
/// </summary>
/// <returns>验证标志,true表示已发生服务器验证</returns>
public bool NeedCheck()
{
if (bool.Parse(Session["NeedCheck"].ToString()))
{
Session["NeedCheck"] = false;
return true;
}
if (Request.QueryString["v"] != null)
{
Session["NeedCheck"] = false;
return false; //已过服务器验证
}
else
{
return true;
}
}
/// <summary>
/// 处理远程服务器传递的数据
/// </summary>
/// <param name="sReceived">获取的数据,进行解密</param>
public void ServerReceived(string sReceived)
{
string derReceived = DesDecrypt(sReceived);
//未来可能存在传递的为数组的情况
UserName = derReceived;
}
#endregion
#region 加密解密方法 -- 要补通过module查询密钥和向量方法
/// <summary>
/// DES对称加密
/// </summary>
/// <param name="SourceStr">源需加密字符串</param>
/// <returns>加密字符串</returns>
public string DesEncrypt(string SourceStr)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
//需要改为从数据库读出密钥和向量
des.Key = System.Text.Encoding.Default.GetBytes("12345678");
des.IV = System.Text.Encoding.Default.GetBytes("ABCDEFGH");
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
StreamWriter sw = new StreamWriter(cs);
sw.Write(SourceStr);
sw.Flush();
cs.FlushFinalBlock();
ms.Flush();
//将byte[]转换为字符串输出
return Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length);
}
/// <summary>
/// DES对称解密
/// </summary>
/// <param name="SourceStr">源需解密字符串</param>
/// <returns>解密字符串</returns>
public string DesDecrypt(string SourceStr)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
//将源串转换为byte[]
byte[] buffer = Convert.FromBase64String(SourceStr);
//需要改为从数据库读出密钥和向量
des.Key = System.Text.Encoding.Default.GetBytes("12345678");
des.IV = System.Text.Encoding.Default.GetBytes("ABCDEFGH");
MemoryStream ms = new MemoryStream(buffer);
CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Read);
StreamReader sr = new StreamReader(cs);
return sr.ReadToEnd();
}
#endregion
#region 属性
private string ms_UserName = "";
public string UserName
{
get { return ms_UserName; }
set { ms_UserName = value; }
}
#endregion
}
}