“等了好久终于等到今天,写了好久终于就快完结,但是网友的反应却让我有一些的伤心。盼了好久终于盼到今天,忍了好久终于把此文撰写,那些受冷落的无奈早就无所谓,累也不说累”(歌词《今天》新演绎)。看着人家的 Blog 文章的评论是一条接一条,再瞧瞧自己:“无人问津呐,真…无…奈……唉,没人理我,还是回家吧。”“哎,还没开始写,怎么就走了?回去干什么呢?”回去写作业去啊,上回交待的课外作业你做了没?(注:http://blog.csdn.net/cityhunter172/archive/2005/11/13/528463.aspx 在第二部分第六节布置的课外作业:此项目有两部门使用,其中每个部门分别都有些特定的页面仅供本部门用户浏览使用,请问该如何使用 Web.config 达到效果?)

不知有多少人做了作业,其实答案并不难。只需要在验证用户名与密码后,取得该用户的部门名称或部门代码,把它作为判断的依据就行了。最好不要用部门的数字ID,那样不利于以后的维护。

有一个秘密,一般人我不告诉他。Web.config 中的 <location> 节点的path 属性可以是一张具体页面的相对 URL 路径,如下:<location path ="ManageSys/Auditing.aspx">

好了,接下来就要揭开“比根目录Web.config 的作用范围还大的配置文件”之谜啦,它就是藏匿在 Windows 系统目录下,支配整个 .Net Framework 配置的传说中的Machine.config !!下面请大家以热烈的掌声,欢迎我们这位神秘侠客的闪亮登场……

九、  Machine.config

Machine.config ,性别不详,年龄未知,家庭出身:XML。深藏于“云深不知处”的操作系统目录下的某某地方(注:C:\WINDOWS【或 WINNT 】\Microsoft.NET\Framework\v1.1.4322【或 v1.0.3705 】\CONFIG),控制着“更上一层楼”的 .NET Framework 的本机配置。接下来简要的讲解一下它的内容,以及它与 Web.config 的关系。

经过“松下问童子”,我们好不容易找到这位隐者,打开一看,乖乖,足有 3700 多行!!“叫我怎么能不难过,偶只想看看是啥结构,可内容实在是太多太繁琐……”还记得偶经常对同事说的一句话么:“办法是人想出来的!”它不是有三千七百多行吗,那我们就不管三七能否得出二十一啦,把它拷出来先。它不是 XML 出身吗,那咱们就还其正身,重新命名为“machine.xml”。接着用 IE 浏览器将这位改头换面的隐者打开,把节点与注释一一合拢。这回你看到了吧,是不是很有成就感?你要是想谢谢我,就让我看到你在此文下面的评论吧。多多益善,呵呵。

Machine.config 与 Web.config 是啥关系?四个字 —— 父子关系。记得我在第二部分第五节讲解 Web.config 作用范围的时提到两点 —— 继承与覆盖(详见http://blog.csdn.net/cityhunter172/archive/2005/11/13/528463.aspx),在此也同样适用。

1、  Machine.config 中的设置将作用于运行在本机的所有站点及其虚拟目录,遇到子目录将一直继承下去。

2、  Web.config 中的设置将覆盖由 Machine.config 中继承下来的对应的节点设置

说到这,再告诉大家一个秘密 —— “世上本无秘密,知道的人多了,便成了不是秘密的秘密!”

a、  Machine.config 中的 <system.web> 节点所有内容都能出现在项目根目录下的 Web.config 中,也就是说能在 Web.config 中的内容已经在 Machine.config 中一一列出;

b、  其中 <system.web> 节点下的 <pages> 还能出现在页面上,如: HTML 视图下,在WebForm1.aspx 的第一行加上<pages> 的节点内容validateRequest="false" (此句意思是不对WebForm1.aspx页面文本框输入的值,是否包含 “<” “>” 等等具有危险性的代码进行检查,下一节将具体运用到)

<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="FromTest.WebForm1" validateRequest="false"  %>

十、  单点登录(Single Sign On)的前提条件

之前说了这么多关于 Machine.config 的事,都是为了实现单点登录作铺垫,那何为单点登录(Single Sign On)?从字面理解就是在一个地方登录,通常运用于 ASP.NET 分布式环境中(跨单个服务器上的多个应用程序或在网络场中)的 Forms 身份验证。打个比方,就好比现在 Sohu(搜狐) 与 Chinren(中国校友录) 的做法,我在 Sohu 登录以后就不需要在 Chinaren 登录了。台湾与香港又把 Single Sign On 称之为“单一登入”。

要想实现此功能,首要条件是需要一组用于加密与验证加密的密钥。它们位于 Machine.config 中,修改  <system.web> 节点下的 <machineKey> 节点属性,如下:

  <machineKey firstKey="172" copyrightKey="Cityhunter172" validationKey="AD117F2F286CDCB15A9D1D4535E16DB0248026939**AUTHOR**CITYHUNTER172****WEBSITE**172*MEIBU*COM****MAILTO**CITYHUNTER172@126*COM*****F2F286CDCB15A9D1D4535E16DB0248026939" secondKey="meibu" decryptionKey="3C89AE62AD117F2F286CDCB15A9D1D4535E16DB0248026939" validation="SHA1" thirdKey="com" />

1、  validationKey 为用于验证加密数据的密钥。最小长度为 40 个字符(20 字节),最大长度为 128 个字符(64 字节)。

2、  decryptionKey 为用于加密数据的密钥。长度只有 16 个字符(8 字节)与 48 个字符(24 字节)两种。

3、  validation 为用数据验证使用的加密类型。拥有“SHA1”“MD5”“3DES”三种方法

4、  大伙参照上述 <machineKey> 试着在WebForm1.aspx运行下列语句:

this.TextBox2.Text ="ht"+"tp"+"://"+firstKey+"."+secondKey +"."+thirdKey

大家在修改之前请先备份一下 Machine.config ,到时要是出错可别怪我没提醒你。以上密钥并不是胡乱得来的,接下来向大家介绍生成密钥的方法。

我们把上一节中提到的 WebForm1.aspx 拖入本项目的 Public 目录下,再往页面上拖入一个 TextMode=MultiLine 的TextBox3 与一个 Button 编写按钮事件与函数:

  private void Button1_Click(object sender, System.EventArgs e)

  {

  string decStr = this.CreateKeyString(int.Parse(this.TextBox1.Text));

  string valStr = this.CreateKeyString(int.Parse(this.TextBox2.Text));

  this.TextBox3.Text=string.Format("<machineKey validationKey=\"{0}\" decryptionKey=\"{1}\" validation=\"SHA1\"/>",valStr,decStr);

}

  /// <summary>

  /// 生成加密型强随机 Key 值

  /// </summary>

  /// <param name="i">Key 的有效长度:

  /// decryptionKey 的有效值为 8 或 24;

  /// validationKay 的有效值为 20 至 64

  /// </param>

  private string CreateKeyString(int i)

  {

  System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();  //加密随机数生成器

  byte[] bt = new byte[i];

  rng.GetBytes(bt);//用加密型强随机值序列填充字节数组

  System.Text.StringBuilder str = new System.Text.StringBuilder();

  for(int j= 0;j<i;j++)

  {

  str.Append(string.Format("{0:X2}",bt[j])); //转换成大写的十六进制文本

  }

  return str.ToString();

  }

每次点击按钮生成密钥都不同,大家不妨多点几次。切换至 HTML 视图,到WebForm1.aspx 第一行把 validateRequest="false" 去掉,然后再多点几次 Button1试试,看看会有什么效果,嘿嘿………

十一、  单点登录(Single Sign On)的站点示例

将上述 TextBox3 产生的文本,覆盖Machine.config 中的,现在你的机器已经具备了单点登录的条件。大伙可以再新建一个项目 FormTest2 ,从 FormTest2 登录后直接输入 FormTest 中的Default.aspx 的网址(http://localhost/FormTest/ Default.aspx),反之亦可。

下面结合实例讲解:偶在山东每步科技网站申请了一个免费二级域名 172.meibu.com,并下载了每步的 4.0 版的动态域名解析客户端。现在使用 ADSL 拔号上网,也就是说我的电脑已经成了 Web 服务器,同时支持 SQL Server 、Oracle 空间高达 200 G 想怎么弄就怎么弄,够牛吧,嘿嘿。布署上来的项目有环胜数码网站、权限管理系统、IT 内部管理网,以上三个项目是偶一人全权开发的。所谓全权就是从数据库存储过程写到 .cs 代码再到 javascript ,最后到美工都是偶一手搞定的。^_^ 我把这三个不相干的项目做成了单点登录的模式,加上整合站点的主页面,共有四个地方可以进行登录。因为用户 Table 的结构不同,因此只有一个入口能在进入后,在跳转站点时不会出错,那就是在整合页面登录。

现在我想把环胜数码这个站点单独脱离出来,而剩下的两个站点继续实现单点登录,该怎么做呢?或者是我的 ASP.NET 的空间是租的,服务商肯定不可能让我修改 Machine.config ,我又咋办哩?“办法是人想出来滴!!”,根据上述 Machine.config 与 Web.config 的关系,我们可以把 <machineKey> 节点放入项目根目录下Web.config的 <system.web> 节点。如下:

1、  权限管理系统项目的 Web.config 用于 Form 认证的设置

<machineKey validationKey="AD117F2F286CDCB15A9D1D4535E16DB0248026939**AUTHOR**CITYHUNTER172****WEBSITE**172*MEIBU*COM****MAILTO**CITYHUNTER172@126*COM*****F2F286CDCB15A9D1D4535E16DB0248026939" decryptionKey="3C89AE62AD117F2F286CDCB15A9D1D4535E16DB0248026939" validation="SHA1" />

<authentication mode="Forms">

<forms loginUrl="Login.aspx" name="172.MEIBU.COM_WARRANT"></forms>

</authentication>

<authorization><deny users="?"></deny></authorization>

2、  IT 内部管理网项目的 Web.config 用于 Form 认证的设置

<machineKey validationKey="AD117F2F286CDCB15A9D1D4535E16DB0248026939**AUTHOR**CITYHUNTER172****WEBSITE**172*MEIBU*COM****MAILTO**CITYHUNTER172@126*COM*****F2F286CDCB15A9D1D4535E16DB0248026939" decryptionKey="3C89AE62AD117F2F286CDCB15A9D1D4535E16DB0248026939" validation="SHA1" />

<authentication mode="Forms">

<forms loginUrl="Login.aspx" name="172.MEIBU.COM_IT"></forms>

</authentication>

<authorization><deny users="?"></deny></authorization>

大家可能会迫不急待的去试一把,偶赞成这样的做法,因为事实是检验真理的唯一办法。你不去试着自己动手,光看我在这说是很难提高的。先别急,我已经知道你想说什么,听听我慢慢向你解释:

a)       两个项目Web.cinfig的<machineKey> 节点确保以下几个字段完全一样:validationKey 、decryptionKey 、validation

b)  两个项目的 Cookie 名称必须相同,也就是 <forms> 中的 name 属性,这里我们把它统一为 name ="172.MEIBU.COM_PROJECT"

c)  注意区分大小写

在整合的过程中,我把遇到的问题向大伙说一下,以免你们走同样的路。

1)  首先应该是用户管理的问题,把两个项目的用户整合在一起,可不是一件容易的事,原则是新建一个新的 Table 只存放帐号与密码,用账号做关联,编写触发器,做到 Table 之间的同步;

2)  不要指望两个项目间用 Session 进行传值,两个应用程序的 Session 是无法共享的。网上有人曾把类库(编译后的 .dll 文档)放入同一个 bin 文件夹实现过 Session 共享,这样的做法实际上是把两个项目变相合并成一个应用程序,不是我们所想要的,理由很简单:Sohu 与 Chinaren 的服务器分处两地该怎么办?

3)  项目间的传值,可用 Cookie 实现。在第一部分的第三节(http://blog.csdn.net/cityhunter172/archive/2005/11/06/524043.aspx)我们介绍了只要运行 System.Web.Security.FormsAuthentication.SetAuthCookie 方法即可实现登录,单点登录的实质就是含有身份验证票的 Cookie 能在项目间共用。

接下来,有必要向大家介绍一下 Cookie 在 .Net 中的用法。

十二、  Cookie 在 ASP.NET 中的用法

大家也许和我一样,很少在 ASP.NET 中使用 Cookie ,传参数呀,存变量呀,用的比较多的是 Session 或 ViewState 以及隐藏控件,有的干脆用“ ? ”的请求方式。

1、  Cookie 存放的目录

Cookie 是存放在客户端的东东,放在“Temporary Internet Files”目录,所以说存在安全性的问题。大伙可通过以下方式找到具体位置:打开控制面板 → Internet 选项 → 常规 → Internet 临时文件 → 设置 → 即可看到“当前位置”,→ 点击“查看文件”将直接打开该文件夹,你也可以点击“移动文件夹”变更它所在的位置。参照下图:

2、  Cookie 的有效期

从上图我们可以清楚的看到每个 Cookie 文档的“截止期”(即为有效期)。在有效期内,当登录计算机的用户 Administrator 再次访问 172.meibu.com 时,那么 IE 就会在请求页面的同时,连同上述的名称为“Cookie:administrator@172.meibu.com”的Cookie 文档内容一起发送给服务器。

若该文档包含多个 Cookie 的值时,截止期则以最后的失效期为准。

3、  Cookie 的类型

这里我们按有效期来分,分为两种:

a)   即时型

指的是关闭浏览器(所有浏览 172.meibu.com 的 IE)后,Cookie 便失效,此类 Cookie 不会在“Temporary Internet Files”目录出现。其实它也有截止期的,为“0001-01-01”

b)  持久型

就是已指定具体“截止期”的,能够在“Temporary Internet Files”目录里面找到的 Cookie

4、  Cookie 的内容

双击打开“Cookie:administrator@172.meibu.com”,我们看到以下内容,如下图:

  上图中,“■”是换行符,你若是要打破什么锅来问我到底是怎么知道的话。我倒是会很乐意的告诉你:这就是经验!偶从学习 C# 那刻起,就拿第一个 Windows 程序 —— 记事本 来开刀,保存文档时得来的经验。

所以服务器读出来的格式如下图:

5、  在 ASP.NET 页面发放 Cookie

发送上述 Cookie 的 .cs 代码为:

  System.Web.HttpCookie ck = new HttpCookie("ckValue0");

  ck["Author"] ="CityHunter";

  ck.Expires = System.DateTime.Now.AddMinutes(10);//若不指定,则为即时型 Cookie

//ck.Path="/FormTest/ManageSys"; //设置 Cookie 的虚拟路径,注意一定要以“/”开头,否则为无效 Cookie ;请大家自行看一下它与在客房端的 Cookie 文档“名称”与 “Internet 地址”的关系

  Response.Cookies.Add(ck);

  ck = new HttpCookie("ckValue1"); //重新新建一个名为 ckValue1 的 Cookie

  ck.Expires = System.DateTime.Now.AddMinutes(20);   //即刻起 20 分钟后失效

  ck["E_Mail"] ="cityhunter172@126.com";   //设置 ckValue1 中的 E_Mail 值

  ck["PersonalWeb"] ="172.meibu.com";

Response.Cookies.Add(ck);   //添加此 Cookie

6、  取回已发放 Cookie 的值

Response.Write(Request.Cookies["ckValue0"]["Author"]+"<br>");//用不着说明了吧

Response.Write(Request.Cookies["ckValue1"]["E_Mail"]+"<br>");

Response.Write(Request.Cookies["ckValue1"]["PersonalWeb"]);

好久没有出作业啦(何出此言?),这第三篇呀,可是花了偶两个星期的业余时间调试、总结、撰写哪,都说时光贵如金,不知我花的这些时间能换来多少银子?换银子,我看是没指望啦,能得到阁下的一句评论,偶也满足了。记住,你的评论就是偶继续写下去的动力。

作业:给 Cookie 赋于以下值,怎样得到它的正确值

  ck["str1"] ="2222";

  ck["str"] ="str0=11111&str1=223";

可以肯定的是Request.Cookies["ckValue1"]["str"] 得不到 “str0=11111&str1=223”这个字串,大家不妨试一下 Request.Cookies["ckValue1"]["str1"] 会得到意想不到的字串哟。

提示:使用 Server.UrlEncode()与Server.UrlDecode()

十三、  发放永久性的验证 Cookie

终于……终于……最后一个章节,蓦然回首,洋洋洒洒十二章。没想到年少时写不完作文的偶,居然也能编出几千余字的文章来呀,不得不佩服偶自己呀!再回首,一大片晕倒的人……。永远到底有多远?永久究竟是多久?只有天知道。

大家登录 CSDN的时候是否留意到一个“2 周内不用再登录”的复选框,它又是怎么做到的呢?大家是否曾遇到过这样的困惑:在执行System.Web.Security.FormsAuthentication.SetAuthCookie 时明明已指定createPersistentCookie 为 true 为何关闭浏览器仍不能直接访问网站?下面我们就这个问题给大家解释一下,且介绍如何手工创建身份验证票并加入 Cookie 中。

System.Web.Security.FormsAuthenticationTicket tk = new System.Web.Security.FormsAuthenticationTicket(

  1,           //指定版本号:可随意指定

"Admin", //登录用户名:对应 Web.config 中 <allow users="Admin" … /> 的 users 属性

  System.DateTime.Now,   //发布时间

  System.DateTime.Now.AddYears(100),   //失效时间:100 年以后,够永够久了吧

false,   //是否为持久 Cookie:尚未发现有何用,至少目前偶还不知,下面会有说明

"测试用户数据"//用户数据:可用 ((System.Web.Security.FormsIdentity)User.Identity).Ticket.UserData 获取

  );

string str = System.Web.Security.FormsAuthentication.Encrypt(tk);//加密身份验票

//声明一个 Cookie,名称为 Web.config 中 <forms name=".APSX" … /> 的 name 属性,对应的值为身份验票加密后的字串

System.Web.HttpCookie ck = new HttpCookie(System.Web.Security.FormsAuthentication.FormsCookieName,str);   

  

//指定 Cookie 为 Web.config 中 <forms path="/" … /> path 属性,不指定则默认为“/”

ck.Path=System.Web.Security.FormsAuthentication.FormsCookiePath;

//此句非常重要,少了的话,就算此 Cookie 在身份验票中指定为持久性 Cookie ,也只是即时型的 Cookie 关闭浏览器后就失效;因此上面我说:我是真的还不知在身份验票中指定为持久性 Cookie 有何用。

ck.Expires = System.DateTime.Now.AddYears(100);

Response.Cookies.Add(ck); //添加至客房端

后记

此系列文章共三部分,历时一个月完成(2005-11-05 ~ 2005-12-06)。以上是我学习并用于实践的一些经验,在此拿出来与大家一起分享。代码都是经过调试的,如有任何疑问,可在 CSDN 论坛(http://community.csdn.net/)找到我,我的 ID 是 cityhunter172 (可用此 ID 发短消息给我),昵称为 寒羽枫,欢迎大家批评指正。

转载于:https://www.cnblogs.com/mgod/archive/2009/04/02/1428237.html

[转]ASP.NET 安全认证(三): 用Form 表单认证实现单点登录相关推荐

  1. ASP.NET 安全认证(二)——灵活运用 Form 表单认证中的 deny 与 allow 及保护 .htm 等文件 ....

    话说上回,简单地说了一下 Form 表单认证的用法.或许大家觉得太简单,对那些大内高手来说应该是"洒洒水啦""小 Kiss 啦(小意思)".今天咱们来点的花样吧 ...

  2. ASP.NET 安全认证(三)—— 用Form 表单认证实现单点登录(Single Sign On) .

    第三部分 实现单点登录(Single Sign On) "等了好久终于等到今天,写了好久终于就快完结,但是网友的反应却让我有一些的伤心.盼了好久终于盼到今天,忍了好久终于把此文撰写,那些受冷 ...

  3. 前端学习笔记--AJAX的应用(三)form表单改为AJAX提交

     无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家.教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家.点这里可以跳转到教程. 参考博客:http://ww ...

  4. HTML第三章 form表单(详解,内含详细代码示例)

    目录 1.特点 2. 表单的语法和属性 3. input元素 4. select和下拉选择框 5. textarea多行文本域 6.label关联控件 每日一句 1.特点 提供了一些可视化的输入控件 ...

  5. 7.20 Bootstrap、企业黄页2.0、form表单、全选不选反选

    Bootstrap.企业黄页2.0.form表单.全选不选反选 一.Bootstrap PPT内容 HTML中导入Bootstrap Bootstrap教程网站 二.企业黄页2.0 三.form表单 ...

  6. Html前端基础(form表单、img标签、a href标签、id的作用)

    文章目录 一.img标签 二.a标签(带href) 三.form表单 本篇主要分析Html前端开发中的img图片标签.a href超链接标签.form表单标签,其中form是重点 一.img标签 1. ...

  7. 面包屑的实现+tag功能实现+form表单

    一 面包屑实现 打开VC/后台管理文件夹 在store/tab.js页面: 在CommonAside页面添加红方框代码: CommonHeader页面添加红方框代码: CommonHeader页面添加 ...

  8. elementui 按钮 表单_仿ElementUI实现一个Form表单的实现代码

    使用组件就像流水线上的工人:设计组件就像设计流水线的人,设计好了给工人使用. 一. 目标 仿 ElementUI 实现一个简单的 Form 表单,主要实现以下四点: Form FormItem Inp ...

  9. React之Form表单封装

    文章目录 一.form表单封装之树形选择框封装 1. 代码结构 (1)html代码 (2)树形选择框的结构 (3)css (4)转化函数 2. 使用方法 (1)单独使用 (2)和form表单一起使用 ...

  10. php form表单提交方式,form表单提交数据的几种方式

    一.submit提交 一般表单提交通过type=submit实现,input type="submit",浏览器显示为button按钮,通过点击这个按钮提交表单数据跳转到/url. ...

最新文章

  1. Nginx使用uninx socket来连接fastcgi(php)
  2. web后门隐藏与检测思路
  3. 前端工程师的一大神器——puppeteer
  4. python显示等待和隐式等待_荐selenium内的隐式等待和显示等待的区别
  5. Yaniv Erlich:DNA 很可能是人类终极的储存设备
  6. servlet解析演进(1)
  7. Windows XP 开机优化
  8. 如何下载Xcode DMG或XIP文件?
  9. 编写Test3.jsp,在JSP页面中静态包含文件Sqrt.jsp(该页面计算数据的算术平方根)。要求程序有两个文件,主文件静态包含一个能够计算数据的算术平方根的页面。
  10. 电力猫服务器的网页,电力猫怎么配对?快速配置电力猫的图文教程
  11. 苹果上网本报价_买水果“送”水泥?无良商家昧良心!苹果纸箱灌水泥,商户坦言:“赚箱子钱”|水泥|水果箱|水泥浆|水果...
  12. 计算机ps相框怎么做,PS教程制作相框
  13. VMWare Workstation、GSX Server、ESX Server的区别?
  14. Android连接蓝牙打开SCO,实现蓝牙耳机输入
  15. 伪相关、伪关系与中介变量——统计名词中的迷思
  16. PoE交换机的多种连接方式 PoE交换机的4种连接方式
  17. CVPR2019 Oral论文《Side Window Filtering》解读及算法 Python 实现
  18. 关于称重系统,你知道这六点吗?
  19. mysql hy000 1030_解决MySQL数据库SQL Error:1030, SQLState: HY000,Got error 28 from storage engine...
  20. 版权原因,QQ不再内置flash插件,需安装二个插件

热门文章

  1. 原生js页面滚动顶部显示滚动总进度条效果
  2. Altuim Designer PCB设计
  3. ROMS四维变分测试
  4. 解决 Exception: ROM is missing for pong, see https://github.com/openai/atari-py#roms for instructions
  5. 用rtl8139网卡制作的bios编程器(不用并口)
  6. c语言编程一个登陆界面设计,怎么用C语言编写个登陆界面?
  7. 计算机大学老师简介,南开大学计算机学院导师教师师资介绍简介-李敏
  8. CDH安全认证及使用
  9. flashfxp怎么用,flashfxp怎么用
  10. LiveZilla 详细 配置 设置 (二) 安装 LiveZilla