65.9K
CodeProject 正在变化。 阅读更多。
Home

ASP.NET 身份验证和授权

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.90/5 (261投票s)

2010 年 8 月 3 日

CPOL

19分钟阅读

viewsIcon

1378392

ASP.NET 身份验证和授权

已更新为新视频

ASP.NET 身份验证和授权

引言

身份验证和授权

检测身份验证和授权:- Principal 和 Identity 对象

ASP.NET 中身份验证和授权的类型

Windows 身份验证

 

表单身份验证
 

Passport 身份验证

源代码

参考文献

本视频演示了使用表单身份验证的单一登录


关于 ASP.NET Basic 身份验证被破解的视频


 

引言
 

本文将讨论如何实现 ASP.NET 身份验证和授权。本文首先介绍身份验证和授权的概念,然后解释实现身份验证和授权的三种重要方式:Windows、表单和 Passport。随着文章的深入,它将深入解释 Basic、Digest 和集成身份验证。本文还将深入探讨如何使用表单身份验证来实现自定义身份验证和单一登录身份验证。本文涉及的一个重要概念是 Cookie 中的票证生成,以及 ASP.NET Membership 和 Role 如何帮助我们提高生产力。  

身份验证和授权
 

在继续之前,我们需要理解四个重要的词汇,您将在本文中反复看到它们:- 身份验证 (authentication)、授权 (authorization)、Principal 和 Identity。首先从身份验证和授权开始。如果您在 www.google.com 上搜索身份验证和授权的字典含义,您会看到类似下面的内容:-

身份验证 (Authentication):- 证明真实性

授权 (Authorization):- 授予对资源的批准或权限的过程。

同样的字典含义也适用于 ASP.NET。在 ASP.NET 中,身份验证意味着识别用户,换句话说,就是验证用户是否存在于您的数据库中,并且是正确的用户。
授权意味着用户是否对 IIS 网站上的特定资源具有访问权限。资源可以是 ASP.NET 网页、媒体文件(MP4、GIF、JPEG 等)、压缩文件(ZIP、RAR)等。
因此,首先发生的过程是身份验证,然后是授权。下面是身份验证和授权的简单图形表示。所以当用户输入 'userid' 和 'password' 时,他首先被身份验证并由用户名识别。
现在,当用户开始访问页面、ASPDOTNETauthentication、视频等资源时,会检查他是否对这些资源拥有必要的访问权限。识别资源权限的过程称为“授权”。
 

简单来说,“他是 Shiv”是身份验证,“Shiv 是管理员”是授权。
 

检测身份验证和授权:- Principal 和 Identity 对象
 

任何时候,如果您想知道用户是谁以及他正在使用哪种身份验证类型,您都可以使用 Identity 对象。如果您想知道他关联了哪些角色,那么我们需要使用 Principal 对象。换句话说,要获取身份验证详细信息,我们需要 Identity 对象;要了解该身份的授权详细信息,我们需要 Principal 对象。
 

 
例如,下面是一个简单的示例代码,演示了如何使用 Identity 和 Principal 对象来显示姓名并检查角色。
 

Response.Write(User.Identity.Name +"<br>");
Response.Write(User.Identity.AuthenticationType + "<br>");
Response.Write(User.Identity.IsAuthenticated + "<br>");
Response.Write(User.IsInRole("Administrators") + "<br>"); 

 

如果您在 IIS 的匿名模式下运行此代码,它将显示如下所示的无详细信息。
 

如果您在 IIS 中使用某种身份验证模式(例如下面显示的“Basic authentication”)运行上述代码,它将显示如下所示的所有详细信息。

ASP.NET 中身份验证和授权的类型
 

在 ASP.NET 中有三种实现身份验证和授权的方法:-
Windows 身份验证:- 在这种方法中,ASP.NET 网页将使用本地 Windows 用户和组来对资源进行身份验证和授权。

表单身份验证:- 这是一种基于 Cookie 的身份验证,其中用户名和密码以 Cookie 文件的形式存储在客户端计算机上,或者在每次请求时通过 URL 发送。基于表单的身份验证会向用户显示一个基于 HTML 的网页,提示用户输入凭据。

Passport 身份验证:- Passport 身份验证基于 Microsoft 提供的 passport 网站。
因此,当用户使用凭据登录时,将被导向 passport 网站(即 hotmail、devhood、windows live 等),在那里进行身份验证。如果身份验证成功,它将返回一个令牌到您的网站。

匿名访问:- 如果您不希望进行任何类型的身份验证,那么您将选择匿名访问。

GenericPrincipal 和 GenericIdentity 对象表示使用表单身份验证或其他自定义身份验证机制进行身份验证的用户。使用这些对象,角色列表是以自定义方式获得的,通常来自数据库。
FormsIdentity 和 PassportIdentity 对象分别表示使用表单和 Passport 身份验证进行身份验证的用户。
 

Windows 身份验证
 

当您将 ASP.NET 应用程序配置为 Windows 身份验证时,它将使用本地 Windows 用户和组来为您的 ASP.NET 页面进行身份验证和授权。下面是一个简单的快照,显示了我计算机上的 Windows 用户和角色。
 

使用 Windows 启用身份验证和授权的 5 个步骤
 

我们将做一个小的样本来了解身份验证和授权如何与 Windows 配合使用。我们将创建两个用户,一个“Administrator”,另一个是一个普通用户,名为“Shiv”。我们将创建两个简单的 ASPX 页面,“User.aspx”页面和“Admin.aspx”页面。“Administrator”用户将可以访问“Admin.aspx”和“User.aspx”页面,而用户“Shiv”将只能访问“User.aspx”页面。

步骤 1:- 创建网站。


下一步是创建一个简单的网站,包含 3 个页面(User.aspx、Admin.aspx 和 Home.aspx),如下图所示。
 

步骤 2:- 在 Windows 目录中创建用户
 

下一步,我们进入 Windows 目录并创建两个用户。您可以看到在我的计算机上有“Administrator”和“Shiv”。
 

步骤 3:- 设置 ‘web.config’ 文件
 

在 ‘web.config’ 文件中,将身份验证模式设置为 ‘Windows’,如下面的代码片段所示。
 

<authentication mode="Windows"/>

 

我们还需要确保除授权用户外,所有用户都被拒绝。下面的代码片段位于 authorization 标签内,表示所有用户都被拒绝。‘?’ 表示任何用户

unknown user.
<authorization>
<deny users="?"/>
</authorization>

 

步骤 4:- 设置授权
我们还需要指定授权部分。我们需要将以下片段插入到 ‘web.config’ 文件中,声明只有‘Administrator’用户才能访问

‘Admin.aspx’ pages.
<location path="Admin.aspx">
<system.web>
<authorization>
<allow roles="questpon-srize2\Administrator"/>
<deny users="*"/>
</authorization>
</system.web>
</location>

 

步骤 5:- 配置 IIS 设置
下一步是编译项目并将其上传到 IIS 虚拟目录。在 IIS 虚拟目录上,我们需要确保删除匿名访问并选中集成 Windows 身份验证,如下图所示。
 


 

现在,如果您运行 Web 应用程序,将弹出一个用户 ID 和密码框,如下图所示。

输入凭据后,您应该能够看到 home.aspx,如下图所示。

如果您不是管理员(即在此例中是“shiv”),并且导航到“Admin.aspx”,将会出现一个错误,如下图所示。

如果您想知道用户是谁以及他以何种授权登录,您可以使用“WindowsPrincipal”和“WindowsIdentity”。这两个对象代表使用 Windows 身份验证进行身份验证的用户。您还可以获取这些用户拥有的角色。
 

收集用户名和密码的不同方法
 

在上面的分步文章中,您可能已经注意到 IIS 上的以下选项(Integrated、digest 和 basic)。这三个复选框决定了 Windows 用户名和密码凭据如何从客户端桌面传递到 IIS。
有三种不同的方法可以将 Windows 用户名和密码传递给 IIS:-
• Basic
• Digest
• Windows
在接下来的章节中,我们将深入了解这 3 个选项。
 

基本身份验证
 

当选择 Basic 身份验证时,‘userid’和‘password’是通过 Base64 编码格式传递的。这就是为什么名称是 Basic 身份验证的原因。‘Base64’是编码而不是加密。所以很容易被破解。您可以访问 http://en.wikipedia.org/wiki/Base64 阅读更多关于‘Base64’编码的内容。这是一种非常弱的保护形式。
 

 

下面是一个小演示,展示了破解 Basic 身份验证有多么容易。您可以在下面的图中看到我们选中了‘Basicauthentication’复选框,并运行了 fiddler 工具来查看数据。

然后我们复制了‘Authorization:Basic’数据并运行了下面的程序。哈哈,我们可以看到我们的 Windows 用户 ID 和密码。

下面是解码‘Base64’编码的代码片段。
 

public static string DecodeFrom64(string encodedData)
{

byte[] encodedDataAsBytes = System.Convert.FromBase64String(encodedData);

string returnValue = System.Text.Encoding.ASCII.GetString(encodedDataAsBytes);

return returnValue;}

 

Base64 是一种编码机制,不是加密
 

Basic 身份验证,换句话说,‘Base64’编码用于传输二进制数据并将其转换为文本,以便它们可以在网络上传输。某些协议可能会将您的二进制数据解释为控制字符。例如,FTP 协议对于某些二进制字符组合可能会将其解释为 FTP 行尾符。

归根结底,它不是一种加密算法,而是一种编码机制。这就是为什么我们在上一节中演示了破解 Basic 身份验证的容易程度。
 

摘要式身份验证
 

使用 Digest 身份验证可以解决 Basic 身份验证存在的问题。我们在上一节中看到了破解 Basic 身份验证有多么容易。Digest 身份验证通过网络传输数据,其形式是 MD5 哈希或消息摘要。这个哈希或摘要很难破解。
换句话说,Digest 身份验证取代了蹩脚的 Basic 身份验证。
 

然而,Digest 身份验证有一个很大的问题,那就是它在某些浏览器上不受支持。
 

集成身份验证
 

集成 Windows 身份验证(以前称为 NTLM,也称为 Windows NT Challenge/Response 身份验证)使用 Kerberos v5 身份验证或 NTLM 身份验证,具体取决于客户端和服务器配置。
(以上段落摘自 http://msdn.microsoft.com/en-us/library/ff647076.aspx )。
让我们尝试理解 NTLM 和 Kerberos 身份验证的原理,然后我们将尝试理解集成身份验证的其他方面。
NTLM 是一种挑战-响应身份验证协议。下面是事件发生的顺序:-
• 客户端将用户名和密码发送给服务器。
• 服务器发送一个挑战。
• 客户端使用 24 字节的结果响应挑战。
• 服务器通过联系域控制器来检查响应是否正确计算。
• 如果一切正常,则授予请求。
 

Kerberos 是一个多头(3 个头)的看守冥界之门的神话。同样,Kerberos 安全有 3 个参与者:身份验证服务、服务服务器和票证授予服务器。让我们一步一步地了解这 3 个实体如何参与确保安全。

图片来源:- http://24-timepass.com/postimg/three-headed-dog.jpg
Kerberos 使用对称密钥进行身份验证和授权。下面是 Kerberos 的工作原理:-

• 步骤 1:客户端将用户名和密码发送给 AS(身份验证服务)。
• AS 验证用户并确保他是一个已通过身份验证的用户。
• AS 然后要求 TGT(票证授予服务)为用户创建一张票证。
• 此票证将用于验证用户是否已通过身份验证。换句话说,在后续的客户端交互中,不会发送密码。
 

优先顺序
 

您可能已经注意到的一件事是,集成、Digest 和 Basic 身份验证是复选框。换句话说,我们可以同时选中所有三个。如果您一次性选中所有 3 个选项,则根据浏览器的安全支持,以上方法之一将具有优先权。
 

让我们了解一下根据浏览器安全设置,安全优先顺序是如何工作的。
• 浏览器发出请求,它将第一个请求作为匿名请求发送。换句话说,它不发送任何凭据。

• 如果服务器不接受匿名请求,IIS 会响应“访问被拒绝”错误消息,并发送浏览器支持的身份验证类型列表。

• 如果 Windows NT Challenge/Response 是唯一支持的方法,那么浏览器必须支持该方法才能与服务器通信。否则,它无法与服务器协商,用户将收到“访问被拒绝”错误消息。

• 如果 Basic 是唯一支持的方法,那么浏览器中会出现一个对话框来获取凭据,然后将这些凭据传递给服务器。它会尝试发送这些凭据最多三次。如果所有这些都失败,浏览器将无法连接到服务器。

• 如果 Basic 和 Windows NT Challenge/Response 都受支持,浏览器将确定使用哪种方法。如果浏览器支持 Windows NT Challenge/Response,它将使用该方法,而不会回退到 Basic。如果 Windows NT Challenge/Response 不受支持,浏览器将使用 Basic。
您可以通过 http://support.microsoft.com/kb/264921 阅读更多关于优先顺序的信息。

换句话说,优先顺序是:-

1. Windows NT 挑战(集成安全)
2. Digest
3. Basic
 

Basic、Digest 和 Windows 身份验证的比较

 

  浏览器支持 身份验证机制
Basic 几乎所有浏览器 弱,使用 Base64。
摘要  IE 5 及更高版本 强,MD5
集成 Windows  

• Kerberos

 IE5 及以上版本  使用 AD、TGT 和 KDC 进行票证加密

• Challenge / response

IE5 及以上版本 发送挑战

 

表单身份验证
 

表单身份验证是一种基于 Cookie/URL 的身份验证,其中用户名和密码以 Cookie 文件的形式存储在客户端计算机上,或者在不支持 Cookie 的情况下,在每次请求时通过 URL 加密发送。
下面是表单身份验证中发生的各种步骤:-
• 步骤 1:- 用户通过为身份验证和授权开发的自定义登录屏幕输入“userid”和“password”。

• 步骤 2:- 会进行检查以确保用户有效。用户可以从‘web.config’文件、SQL Server、客户数据库、Windows Active Directory 和各种其他数据源进行验证。

• 步骤 3:- 如果用户有效,则在客户端创建一个 Cookie 文本文件。此 Cookie 文本文件表示用户已通过身份验证。此后,当客户端计算机浏览您的 ASP.NET 站点的其他资源时,将不再进行验证。Cookie 文件表示用户已登录。
 

使用 ‘web.config’ 作为数据存储的表单身份验证
 

所以,让我们一步一步地了解如何配置表单身份验证。如前几节所述,您可以将用户存储在‘web.config’文件中。当然,将用户存储在“web.config”文件中并不是最好的方法,但它确实有助于我们理解表单身份验证。一旦我们理解了这一点,我们就可以继续改进表单身份验证的版本。

步骤 1:- 我们需要做的第一件事是在 web.config 文件中进行一个条目,将身份验证模式设置为 forms,如下所示。我们还需要提供以下内容:-

• LoginUrl:- 此属性有助于我们提供身份验证和授权的起始页。

• defaultUrl:- 用户验证成功后,他将被重定向到此值,目前是“Home.aspx”。

• Cookieless:- 如前所述,表单身份验证使用 Cookie。有四种方法可以更改此行为:-

oAutoDetect:- 根据您的浏览器配置,它可以选择使用 Cookie 或通过浏览器 URL 加密传递身份验证信息。

o UseCookies:- 您希望表单身份验证机制在身份验证成功时创建 Cookie。

o UseURI:- 您希望通过浏览器 URL 查询字符串加密传递数据。

o UseDeviceProfile:- 这是默认值。当您设置此值时,表单身份验证机制将在
 “C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG\Browsers”中查找,以查看浏览器是否支持 Cookie,然后决定是使用 Cookie 还是不使用。换句话说,它不会在实际运行时检查浏览器是否启用了 Cookie。

• Credentials:- 在 credentials 标签中,我们还有一些具有名称和密码的用户。如前所述,我们将首先使用存储在 web.config 文件中的用户名的表单身份验证。
 

<authentication mode="Forms">
<forms loginUrl="Login.aspx" timeout="30" defaultUrl="Home.aspx" cookieless="AutoDetect">
<credentials passwordFormat="Clear">
<user name="Shiv" password="pass@123"/>
<user name="Raju" password="pass@123"/>
</credentials>
</forms>
</authentication>

 

‘cookieless’属性的不同自定义值。
 

 

如果您将 cookieless 设置为‘UseDeviceProfile’,它将使用来自以下文件的浏览器数据。您可以看到 Ericsson 浏览器不支持 Cookie。因此,如果有人使用 Ericsson 浏览器连接,并且值为‘UseDeviceProfile’,表单身份验证将通过查询字符串传递数据。

 

步骤 2:- 设置完“forms”标签值后,就该确保匿名用户无法浏览您的网站了。您可以使用 authorization 标签来完成此操作,如下面的代码片段所示。
 

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

 

步骤 3:- 我们还需要定义哪个用户可以访问哪个页面。在此项目中,我们创建了两个页面“Admin.aspx”和“User.aspx”。“Admin.aspx”仅对用户“Shiv”可访问,而“Admin.aspx”和“User.aspx”对两个用户都可访问。

下面的 web.config 设置显示了我们如何将用户设置为可访问的页面。
 

<location path="Admin.aspx">
<system.web>
<authorization>
<allow users="Shiv"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
<location path="User.aspx">
<system.web>
<authorization>
<allow users="Shiv"/>
<allow users="Raju"/>
<deny users="*"/>
</authorization>
</system.web>
</location>

 

步骤 4:- 现在我们创建自定义页面,它将接受用户 ID 和密码。
 

在按钮点击事件中,我们提供以下代码。“FormsAuthentication.Authenticate”会在 web.config 中查找用户名和密码。“FormsAuthentication.RedirectFromLoginPage”会在浏览器端创建 Cookie。

如果您运行您的应用程序,输入正确的凭据,您应该能够看到创建了一个 Cookie 文本文件,如下图所示。

如果您在浏览器设置中禁用了 Cookie,凭据将通过查询字符串传递,如下图所示。

 

使用 SQL Server 作为数据存储的表单身份验证
 

为了进行自定义身份验证,您需要将“FormsAuthentication.Authenticate”语句替换为您自己的验证。例如,在下面的代码中,我们使用‘clsUser’类进行身份验证,但我们仍然使用了‘FormAuthentication’系统提供的 Cookie 创建机制。

clsUser objUser = new clsUser();
if (objUser.IsValid(txtUser.Text,txtPass.Text))
{
FormsAuthentication.RedirectFromLoginPage(txtUser.Text, true);
}

 

使用 ASP.NET Membership 和 Role 的表单身份验证
 

我们使用了表单身份验证机制来生成 Cookie,这极大地减少了我们的开发工作。我们仍然在执行许多其他任务,例如:-
• 创建用户和角色表。
• 维护这些表的代码级实现。
• 用户 ID 和密码的用户界面。

我们确信您一定在每个项目中都一遍又一遍地完成了上述任务。好消息!!!所有这些现在都因 Membership 和 Roles 的引入而变得简单。要实现 ASP.NET Membership 和 Roles,我们需要执行以下步骤:-

• 从‘C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727’文件夹运行 aspnet_regsql.exe。输入 SQL Server 凭据并运行 exe。这将安装所有必需的存储过程和表,如下图所示‘aspnet_regsql.exe 创建的对象’。
 

 

• 在‘web.config’文件中指定您的 ASP.NET 角色表和存储过程所在的连接字符串。

<connectionStrings>
<remove name="LocalSqlServer1"/>
<add name="LocalSqlServer1" connectionString="Data Source=localhost;Initial 
Catalog=test;Integrated Security=True"/> 
</connectionStrings>

 


• 指定 ASP.NET Membership Provider,并将其与上一步提供的连接字符串连接。

<membership>
<providers>
<remove name="AspNetSqlMembershipProvider"/>
<add name="AspNetSqlMembershipProvider" 
type="System.Web.Security.SqlMembershipProvider, System.Web, 
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" 
connectionStringName="LocalSqlServer1" enablePasswordRetrieval="false" 
enablePasswordReset="true" applicationName="/" minRequiredPasswordLength="7"/>

</providers>
</membership>


• 我们还需要指定 Role Provider,并将其与上一届提供的连接字符串连接。
 

<roleManager enabled="true">
<providers>
<clear/>
<add name="AspNetSqlRoleProvider" connectionStringName="LocalSqlServer1" 
applicationName="/" type="System.Web.Security.SqlRoleProvider, System.Web, 
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
</providers>
</roleManager>

 

现在您可以使用“Membership”类来创建用户和角色,如下面的 2 个图所示。
 

 

 

您可以看到使用表单身份验证开发身份验证和授权有多么容易
 以及 ASP.NET Membership 和 Roles。
 

双重组合
 

任何应用程序中的身份验证和授权都需要 2 个要素:-
• 生成 Cookie 的机制:- 由 Forms Authentication 提供。

• SQL Server 中的自定义表用于存储用户和角色:- 由 ASP.NET Provider 和 Roles 提供。

换句话说,通过结合使用表单身份验证生成的票证和 ASP.NET Provider 和 Roles,我们可以提出一个简洁快速的解决方案来在 ASP.NET 应用程序中实现身份验证和授权。
 

使用单一登录的表单身份验证
 

很多时候我们希望在多个站点之间实现单一登录。这可以通过表单身份验证来完成。您可以在两个网站中都实现表单身份验证,并使用相同的 machine key。一旦在一个网站上完成验证,就会创建一个 Cookie 文本文件。当用户访问另一个网站时,将使用相同的 Cookie 文件来确保用户是否正确。
请注意,您需要确保您的 Web 应用程序的两个 web.config 文件中具有相同的 machine key。
 

<machineKey 
validationKey="C50B3C89CB21F4F1422FF158A5B42D0E8DB8CB5CDA1742572A487D9401E340
0267682B202B746511891C1BAF47F8D25C07F6C39A104696DB51F17C529AD3CABE" 
decryptionKey="8A9BE8FD67AF6979E7D20198CFEA50DD3D3799C77AF2B72F" 
validation="SHA1" />

 

您可以在 http://msdn.microsoft.com/en-us/library/ms972971.aspx 上找到关于单一登录的非常详细的文章。您还可以从 http://download.microsoft.com/download/B/7/8/B78D1CED-2275-4AEE-B0BE-0DEA1A2A9581/MSDNEnterpriseSecurity.msi 下载代码。
以上讨论了内部内部网和互联网应用程序如何通过单一登录设施登录。
 

 

上图摘自 http://msdn.microsoft.com/en-us/library/ms972971.aspx
 

Passport 身份验证
 

Passport 身份验证基于 Microsoft 提供的 passport 网站。因此,当用户使用凭据登录时,将被导向 passport 网站(即 hotmail、devhood、windows live 等),在那里进行身份验证。如果身份验证成功,它将返回一个令牌到您的网站。
我现在将此部分留空,稍后将更新更多详细信息
 

源代码

您可以从此处下载本教程的源代码

如需进一步阅读,请观看以下面试准备视频和分步视频系列。

参考文献

子域中的单一登录 SingleSignon.aspx 

不同身份验证机制的优秀参考

http://msdn.microsoft.com/en-us/library/ee817643.aspx 

MSDN 文章解释了如何进行表单身份验证 http://support.microsoft.com/kb/301240

MSND 文章解释了 Identity 和 Principal 对象 http://msdn.microsoft.com/en-us/library/ftx85f8x(v=VS.85).aspx 

Patterns and practices 页面提供了一个表格,说明了 IIS 身份验证设置的范围。 http://msdn.microsoft.com/en-us/library/ff649264.aspx 

Windows 身份验证、Basic 身份验证和 Digest 身份验证的优先顺序 http://support.microsoft.com/kb/264921 

关于表单身份验证的精彩文章,深入讲解 http://www.4guysfromrolla.com/webtech/110701-1.shtml 

使用漂亮的序列图解释的表单身份验证 http://www.asp.net/security/tutorials/an-overview-of-forms-authentication-vb 

关于表单身份验证最佳实践的精美 PDF http://www.foundstone.com/us/resources/whitepapers/aspnetformsauthentication.pdf

© . All rights reserved.