网站导航免费论文 原创论文 论文搜索 原创论文 网学软件 学术大家 资料中心 会员中心 问题解答 原创论文 大学论文导航 设计下载 最新论文 下载排行 原创论文 论文源代码
返回网学首页
网学联系
最新论文 推荐专题 热门论文 素材专题
当前位置: 网学 > 编程文档 > ASP.net > 正文

细说ASP.NET Windows身份认证

来源:http://myeducs.cn 联系QQ:点击这里给我发消息 作者: 用户投稿 来源: 网络 发布时间: 13/01/05
许线程以特定的Windows帐户的安全上下文来访问资源。

为了能更好的理解模拟的功能,我准备了一个示例(ShowWindowsIdentity.ashx):

  1. public class ShowWindowsIdentity : IHttpHandler {  
  2.       
  3.     public void ProcessRequest (HttpContext context) {  
  4.         // 要观察【模拟】的影响,  
  5.         // 可以启用,禁止web.config中的设置:<identity impersonate="true"/>  
  6.           
  7.         context.Response.ContentType = "text/plain";  
  8.  
  9.         context.Response.Write(Environment.UserDomainName + "\\" + Environment.UserName + "\r\n");  
  10.           
  11.         WindowsPrincipal winPrincipal = (WindowsPrincipal)HttpContext.Current.User;  
  12.         context.Response.Write(string.Format("HttpContext.Current.User.Identity: {0}, {1}\r\n",   
  13.                 winPrincipal.Identity.AuthenticationType, winPrincipal.Identity.Name));  
  14.           
  15.         WindowsPrincipal winPrincipal2 = (WindowsPrincipal)Thread.CurrentPrincipal;  
  16.         context.Response.Write(string.Format("Thread.CurrentPrincipal.Identity: {0}, {1}\r\n",  
  17.                 winPrincipal2.Identity.AuthenticationType, winPrincipal2.Identity.Name));  
  18.  
  19.         WindowsIdentity winId = WindowsIdentity.GetCurrent();  
  20.         context.Response.Write(string.Format("WindowsIdentity.GetCurrent(): {0}, {1}",  
  21.                 winId.AuthenticationType, winId.Name));  
  22.     } 

首先,在web.config中设置:

  1. <authentication mode="Windows" /> 

注意:要把网站部署在IIS中,否则看不出效果。

此时,访问ShowWindowsIdentity.ashx,将看到如下图所示的结果:

498)this.width=498;'' onmousewheel = ''javascript:return big(this)'' alt="" src="/uploadfile/201301/5/8C151816212.png" />

现在修改一下web.config中设置:(注意:后面加了一句配置

  1. <authentication mode="Windows" /> 
  2. <identity impersonate="true"/> 

此时,访问ShowWindowsIdentity.ashx,将看到如下图所示的结果:

498)this.width=498;'' onmousewheel = ''javascript:return big(this)'' alt="" src="/uploadfile/201301/5/04151816164.png" />

说明:

1. FISH-SRV2003是我的计算机名。它在一个没有域的环境中。

2. fish-li是我的一个Windows帐号的登录名。

3. 网站部署在IIS6中,进程以NETWORK SERVICE帐号运行。

4. 打开网页时,我输入的用户名是fish-li

前面二张图片的差异之处其实也就是ASP.NET的“模拟”所发挥的功能。

关于模拟,我想说四点:

1. 在ASP.NET中,我们应该访问HttpContext.User.Identity获取当前用户标识,那么就不存在问题(此时可以不需要模拟),例如FileAuthorizationModule就是这样处理的。

2. 模拟只是在ASP.NET应用程序访问Windows系统资源时需要应用Windows的安全检查功能才会有用。

3. Forms身份认证也能配置模拟功能,但只能模拟一个Windows帐户。

4. 绝大多数情况下是不需要模拟的。

在IIS中配置Windows身份认证

与使用Forms身份认证的程序不同,使用Windows身份认证的程序需要额外的配置步骤。这个小节将主要介绍在IIS中配置Windows身份认证,我将常用的IIS6和IIS7.5为例分别介绍这些配置。

IIS6的配置 请参考下图:

498)this.width=498;'' onmousewheel = ''javascript:return big(this)'' alt="" src="/uploadfile/201301/5/6C151816486.png" />

IIS7.5的配置 请参考下图:

498)this.width=498;'' onmousewheel = ''javascript:return big(this)'' alt="" src="/uploadfile/201301/5/A3151817437.png" />

注意:Windows身份认证是需要安装的,方法请参考下图:

498)this.width=498;'' onmousewheel = ''javascript:return big(this)'' alt="" src="/uploadfile/201301/5/6A151817835.png" />

关于浏览器的登录对话框问题

当我们用浏览器访问一个使用Windows身份认证的网站时,浏览器都会弹出一个对话框(左IE,右Safari):

498)this.width=498;'' onmousewheel = ''javascript:return big(this)'' alt="" src="/uploadfile/201301/5/6E151817372.png" />

此时,要求我们输入Windows的登录帐号,然后交给IIS验证身份。

首次弹出这个对话框很正常:因为程序要验证用户的身份。

然而,每次关闭浏览器下次重新打开页面时,又会出现此对话框,此时感觉就很不方便了。

虽然有些浏览器能记住用户名和密码,但我发现FireFox,Opera,Chrome仍然会弹出这个对话框,等待我们点击确定,只有Safari才不会打扰用户直接打开网页。 IE的那个“记住我的密码”复选框完全是个摆设,它根本不会记住密码!

因此,我所试过的所有浏览器中,只有Safari是最人性化的。

虽然在默认情况下,虽然IE不会记住密码,每次都需要再次输入。

不过,IE却可以支持不提示用户输入登录帐号而直接打开网页, 此时IE将使用用户的当前Windows登录帐号传递给IIS验证身份。

要让IE打开一个Windows身份认证的网站不提示登录对话框,必须满足以下条件:

1. 必须在 IIS 的 Web 站点属性中启用 Windows 集成身份验证。

2. 客户端和Web服务器都必须在基于Microsoft Windows的同一个域内。

3. Internet Explorer 必须把所请求的 URL 视为 Intranet(本地)。

4. Internet Explorer 的 Intranet 区域的安全性设置必须设为“只在 Intranet 区域自动登录”。

5. 请求Web页的用户必须具有访问该Web页以及该Web页中引用的所有对象的适当的文件系统(NTFS)权限。

6. 用户必须用域帐号登录到Windows 。

在这几个条件中,如果网站是在一个Windows域中运行,除了第3条可能不满足外,其它条件应该都容易满足(第4条是默认值)。因此,要让IE不提示输入登录帐号,只要确保第3条满足就可以了。下面的图片演示了如何完成这个配置:(注意:配置方法也适合用域名访问的情况)

498)this.width=498;'' onmousewheel = ''javascript:return big(this)'' alt="" src="/uploadfile/201301/5/28151817340.png" />

另外,除了在IE中设置Intranet外,还可以在访问网站时,用计算机名代替IP地址或者域名,那么IE始终认为是在访问Intranet内的网站,此时也不会弹出登录对话框。

在此,我想再啰嗦三句:

1. IE在集成Windows身份认证时,虽然不提示登录对话框,但是不表示不安全,它会自动传递登录凭据。

2. 这种行为只有IE才能支持。(其它的浏览器只是会记住密码,在实现上其实是不一样的。)

3. 集成Windows身份认证,也只适合在Intranet的环境中使用。

在客户端代码中访问Windows身份认证的页面

在上篇博客中,我演示了如何用代码访问一个使用Forms身份认证的网站中的受限页面,方法是使用CookieContainer对象接收服务端生的登录Cookie。然而,在Windows身份认证的网站中,身份验证的过程发生在IIS中,而且根本不使用Cookie保存登录状态,而是需要在请求时发送必要的身份验证信息。

在使用代码做为客户端访问Web服务器时,我们仍然需要使用HttpWebRequest对象。为了能让HttpWebRequest在访问IIS时发送必要的身份验证信息,HttpWebRequest提供二个属性都可以完成这个功能:

  1. // 获取或设置请求的身份验证信息。  
  2. //  
  3. // 返回结果:  
  4. //     包含与该请求关联的身份验证凭据的 System.Net.ICredentials。默认为 null。  
  5. public override ICredentials Credentials { getset; }  
  6.  
  7.  
  8. // 获取或设置一个 System.Boolean 值,该值控制默认凭据是否随请求一起发送。  
  9. //  
  10. // 返回结果:  
  11. //     如果使用默认凭据,则为 true;否则为 false。默认值为 false。  
  12. public override bool UseDefaultCredentials { getset; } 

下面是我准备的完整的示例代码(注意代码中的注释)

  1. static void Main(string[] args)  
  2. {  
  3.     try {  
  4.         // 请把WindowsAuthWebSite1这个网站部署在IIS中,  
  5.         // 开启Windows认证方式,并禁止匿名用户访问。  
  6.         // 然后修改下面的访问地址。  
  7.         HttpWebRequest request =   
  8.             (HttpWebRequest)WebRequest.Create("http://localhost:33445/Default.aspx");  
  9.  
  10.         // 下面三行代码,启用任意一行都是可以的。  
  11.         request.UseDefaultCredentials = true;  
  12.         //request.Credentials = CredentialCache.DefaultCredentials;  
  13.         //request.Credentials = CredentialCache.DefaultNetworkCredentials;  
  14.         // 如果上面的三行代码全被注释了,那么将会看到401的异常信息。  
  15.  
  16.         using( HttpWebResponse response = (HttpWebResponse)request.GetResponse() ) {  
  17.             using( StreamReader sr = new StreamReader(response.GetResponseStream()) ) {  
  18.                 Console.WriteLine(sr.ReadToEnd());  
  19.             }  
  20.         }  
  21.     }  
  22.     catch( WebException wex ) {  
  23.         Console.WriteLine("=====================================");  
  24.         Console.WriteLine("异常发生了。");  
  25.         Console.WriteLine("=====================================");  
  26.         Console.WriteLine(wex.Message);  
  27.     }  

其实关键部分还是设置UseDefaultCredentials或者Credentials,代码中的三种方法是有效的。

这三种方法的差别:
1. Credentials = CredentialCache.DefaultCredentials; 表示在发送请求会带上当前用户的身份验证凭据。
2. UseDefaultCredentials = true; 此方法在内部会调用前面的方法,因此与前面的方法是一样的。
3. Credentials = CredentialCache.DefaultNetworkCredentials; 是在.NET 2.0中引用的新方法。

关于DefaultCredentials和DefaultNetworkCredentials的更多差别,请看我整理的表格:

Credentials属性 申明类型 实例类型 .NET支持版本
DefaultCredentials ICredentials SystemNetworkCredential 从1.0开始
DefaultNetworkCredentials NetworkCredential SystemNetworkCredential 从2.0开始

三个类型的继承关系:
1. NetworkCredential实现了ICredentials接口,
2. SystemNetworkCredential继承自NetworkCredential。

在结束这篇博客之前,我想我应该感谢新蛋。

在新蛋的网络环境中,让我学会了使用Windows身份认证。

除了感谢之外,我现在还特别怀念 fl45 这个登录名......

点击此处下载示例代码

原文链接:http://www.cnblogs.com/fish-li/archive/2012/05/07/2486840.html

网学推荐

免费论文

原创论文

设为首页 | 加入收藏 | 论文首页 | 论文专题 | 设计下载 | 网学软件 | 论文模板 | 论文资源 | 程序设计 | 关于网学 | 站内搜索 | 网学留言 | 友情链接 | 资料中心
版权所有 QQ:3710167 邮箱:3710167@qq.com 网学网 [Myeducs.cn] 您电脑的分辨率是 像素
Copyright 2008-2015 myeducs.Cn www.myeducs.Cn All Rights Reserved 湘ICP备09003080号