•
|
匿名
。如果不需要对客户端进行身份验证(或者使用自定义身份验证机制,如窗体身份验证),则可将
IIS
配置为允许匿名访问。在该事件中,
IIS
创建一个
Windows
令牌来表示具有相同匿名(或客人)帐户的所有匿名用户。默认的匿名帐户是
IUSR_MACHINENAME
,其中
MACHINENAME
是安装期间指定的计算机的
NetBIOS
名称。
|
||||||
•
|
基本
。基本身份验证要求用户以用户名和密码的形式提供凭据来证明他们的身份。基本身份验证基于
Internet
标准
RFC 2617
,所有常用浏览器都支持它。用户的凭据以未加密的
Base64
编码格式从浏览器传送到
Web
服务器。为了更好保护这些凭据,只要在使用基本身份验证同时再使用安全套接字层
(SSL)
即可。由于
Web
服务器包含未加密的用户凭据,因此
ASP.NET
应用程序可以模拟调用方并使用他们的凭据来访问网络资源。
|
||||||
•
|
集成的
Windows
。集成的
Windows
身份验证(以前称为
NTLM
,也称为
Windows NT
质询
/
应答身份验证,
Windows NT Challenge/Response
)是使用
Kerberos v5
身份验证还是
NTLM
身份验证,取决于客户端和服务器的配置。服务器与客户端协商确定要使用的协议。如果满足以下条件,则使用
Kerberos
身份验证:
|
•
|
用户请求访问
。用户尝试通过提供用户凭据登录到客户端。登录前,客户端计算机缓存密码的哈希值并放弃密码。客户端向服务器发送一个请求,该请求包括用户名以及纯文本格式的请求。
|
•
|
服务器发送质询消息
。服务器生成一个称为质询的
16
字节随机数(即
NONCE
),并将它发送到客户端。
|
•
|
客户端发送应答消息
。客户端使用由用户的密码生成的一个密码哈希值来加密服务器发送的质询。它以应答的形式将这个加密的质询发回到服务器。
|
•
|
服务器将质询和应答发送到域控制器
。服务器将用户名、原始质询以及应答从客户端计算机发送到域控制器。
|
•
|
域控制器比较质询和应答以对用户进行身份验证
。域控制器获取该用户的密码哈希值,然后使用该哈希值对原始质询进行加密。接下来,域控制器将加密的质询与客户端计算机的应答进行比较。如果匹配,域控制器则发送该用户已经过身份验证的服务器确认。
|
•
|
服务器向客户端发送应答
。假定凭据有效,服务器授予对所请求的服务或资源的客户端访问权。
|
•
|
相互身份验证
。当客户端使用
Kerberos v5
协议对特定服务器上的特定服务进行身份验证,
Kerberos
为客户端提供网络上恶意代码不会模拟该服务的保证。
|
•
|
委托支持
。使用
Kerberos
身份验证对客户端进行身份验证的服务器可以模拟这些客户端,并使用该客户端的安全上下文访问网络资源。
|
•
|
性能
。
Kerberos
身份验证提供优于
NTLM
身份验证的改进的性能。
|
•
|
简化的信任管理
。具有多个域的网络不再需要一组复杂的显式、点对点信任关系。
|
•
|
互操作性
。
Microsoft
实现的
Kerberos
协议基于向
Internet
工程任务组
(IETF)
推荐的标准跟踪规范。因此,
Windows 2000
中协议的实现为与其他网络的互操作奠定了基础(其中
Kerberos
版本
5
用于身份验证)。
|
•
|
客户端从
KDC
请求
TGT
。用户试图通过提供用户凭据登录到客户端。客户端计算机上的
Kerberos
服务向密钥发行中心
(KDC)
发送一个
Kerberos
身份验证服务请求。该请求包含用户名、请求票证授予票证(
ticket-granting ticket
,
TGT
)所获取的服务信息,以及使用用户的长期密钥(即密码)加密的时间戳。
注
在
Windows 2000 Server
或
Windows Server 2003
操作系统上,域控制器充当
KDC
,而
Active Directory
宿主安全帐户数据库。
|
•
|
身份验证服务发送加密的
TGT
和会话密钥
。
KDC
为来自
Active Directory
的用户获取长期密钥(即密码),然后解密随请求一起传送的时间戳。如果该时间戳有效,则用户是真正的用户。
KDC
身份验证服务创建一个登录会话密钥,并使用用户的长期密钥对该副本进行加密。然后,该身份验证服务创建一个
TGT
,它包括用户信息和登录会话密钥。最后,该身份验证服务使用自己的密钥加密
TGT
,并将加密的会话密钥和加密的
TGT
传递给客户端。
|
•
|
客户端从
TGT
请求服务器访问
。客户端使用其长期密钥(即密码)解密登录会话密钥,并在本地缓存它。此外,客户端还将加密的
TGT
存储在它的缓存中。访问网络服务时,客户端向
KDC
票证授予服务(
ticket-granting service
,
TGS
)发送一个包含信息的请求,这些信息包括用户名、使用用户登录会话密钥加密的验证者消息、
TGT
,以及用户想访问的服务(和服务器)名称。
|
•
|
TGS
发送加密的会话密钥和票证
。
KDC
上的
TGS
使用自己的密钥解密
KDC
并提取登录会话密钥。它使用该登录会话密钥解密验证者消息(通常是时间戳)。如果验证者消息成功解密,
TGS
从
TGT
提取用户信息,并使用用户信息创建一个用于访问该服务的服务会话密钥。它使用该用户的登录会话密钥对该服务会话密钥的一个副本进行加密,创建一个具有服务会话密钥和用户信息的服务票证,然后使用该服务的长期密钥(密码)对该服务票证进行加密。然后,
TGS
将加密的服务会话密钥和服务票证添加到客户端。
|
•
|
客户端发送服务票证
。客户端访问服务时,向服务器发送一个请求。该请求包含验证者消息(时间戳),该消息使用服务会话密钥和服务票证进行加密。
|
•
|
服务器发送加密的时间戳以进行客户端验证
。服务器解密服务票证并提取服务会话密钥。通过使用服务会话密钥,服务器解密验证者消息(时间戳)并计算它。如果验证者通过测试,则服务器使用服务会话密钥对验证者(时间戳)进行加密,然后将验证者传回到客户端。客户端解密时间戳,如果该时间戳与原始时间戳相同,则该服务是真正的,客户端继续连接。
|
•
|
支持相互身份验证。
|
•
|
允许一个客户端请求票证,进而允许该客户端与特定服务通讯。
|
•
|
WindowsAuthenticationModule
使用从
IIS
传递到
ASP.NET
的
Windows
访问令牌创建一个
windowsprincipal
对象。该令牌包装在
httpcontext
类的
workerrequest
属性中。引发
authenticaterequest
事件时,
windowsauthenticationmodule
从
httpcontext
类检索该令牌并创建
windowsprincipal
对象。
httpcontext.user
用该
windowsprincipal
对象进行设置,它表示所有经过身份验证的模块和
ASP.NET
页的经过身份验证的用户的安全上下文。
|
•
|
WindowsAuthenticationModule
类使用
P/Invoke
调用
Win32
函数并获得该用户所属的
Windows
组的列表。这些组用于填充
windowsprincipal
角色列表。
|
•
|
WindowsAuthenticationModule
类将
windowsprincipal
对象存储在
httpcontext.user
属性中。随后,授权模块用它对经过身份验证的用户授权。
注:
defaultauthenticationmodule
类(也是
ASP.NET
管道的一部分)将
thread.currentprincipal
属性设置为与
httpcontext.user
属性相同的值。它在处理
authenticaterequest
事件之后进行此操作。
|
<httpModules>
<add name="UrlAuthorization"
type="System.Web.Security.UrlAuthorizationModule" />
<add name="FileAuthorization"
type="System.Web.Security.FileAuthorizationModule" />
<add name="AnonymousIdentification"
type="System.Web.Security.AnonymousIdentificationModule" />
</httpModules>
•
|
System.Security.Principal.IPrincipal
|
•
|
System.Security.Principal.IIdentity
(它公开为
iprincipal
接口中的一个属性。)
|
using System.Security.Principal;
...
// Obtain the authenticated user's Identity
WindowsPrincipal winPrincipal = (WindowsPrincipal)HttpContext.Current.User;
using System.Security.Principal;
...
// Obtain the authenticated user's identity.
WindowsIdentity winId = WindowsIdentity.GetCurrent();
WindowsPrincipal winPrincipal = new WindowsPrincipal(winId);
using System.Security.Principal;
...
// Obtain the authenticated user's identity
WindowsPrincipal winPrincipal = (WindowsPrincipal) Thread.CurrentPrincipal();
表
1
:线程公开的
CurrentPrincipal Object
|
||
Web.config
设置
|
变量位置
|
结果标识
|
<identity impersonate="true"/> <authentication mode="Windows" /> |
HttpContext WindowsIdentity 线程 |
Domain\UserName Domain\UserName Domain\UserName |
<identity impersonate="false"/> <authentication mode="Windows" /> |
HttpContext WindowsIdentity 线程 |
Domain\UserName NT AUTHORITY\NETWORK SERVICE Domain\UserName |
<identity impersonate="true"/> <authentication mode="Forms" /> |
HttpContext WindowsIdentity 线程 |
用户提供的名称
Domain\UserName 用户提供的名称 |
<identity impersonate="false"/> <authentication mode="Forms" /> |
HttpContext WindowsIdentity 线程 |
用户提供的名称
NT AUTHORITY\NETWORK SERVICE 用户提供的名称 |
<authentication mode="Windows" />
<identity impersonate="true" />
using System.Security.Principal;
...
// Obtain the authenticated user's identity.
WindowsIdentity winId = (WindowsIdentity)HttpContext.Current.User.Identity;
WindowsImpersonationContext ctx = null;
try
{
// Start impersonating.
ctx = winId.Impersonate();
// Now impersonating.
// Access resources using the identity of the authenticated user.
}
// Prevent exceptions from propagating.
catch
{
}
finally
{
// Revert impersonation.
if (ctx != null)
ctx.Undo();
}
// Back to running under the default ASP.NET process identity.
•
|
如果在
NetworkService
帐户下运行应用程序,
Web
服务器计算机帐户必须在
Active Directory
中标记为受信任委托。
|
•
|
如果在自定义域帐户下运行应用程序,该用户帐户必须在
Active Directory
中标记为受信任委托。
|
•
|
如果应用程序模拟一个用户帐户,请确保应用程序模拟的用户帐户在
Active Directory
中未标记为
"
敏感帐户,不能被委托
"
。
|