ASP.NET 2.0中保证应用程序的安全(1)
上一篇 / 下一篇 2007-05-15 11:48:00 / 个人分类:网络实用技术
登录控件--新的登录控件为站点的基于认证和授权的UI(例如登录窗体、创建用户窗体、密码取回、已登录用户或角色的定制UI)提供了基本模块。这些控件利用ASP.NET 2.0中的内建的成员和角色服务与站点所定义的用户和角色信息交互操作。
大多数Web应用程序的一个重要的部分是辨别用户并控制资源的访问权。检测请求的实体(entity)身份的操作就是认证(authentication)。通常,为了进行认证,用户必须提供凭证,例如帐号/密码。一旦认证过的身份是有效的,就必须检测该身份是否能够访问指定的资源,这个过程就是授权(authorization)。ASP.NET与IIS一起为应用程序提供认证和授权服务。
COM对象的一个重要特性就是,它能够控制那些运行COM对象代码的身份。当COM对象用请求的实体身份运行代码的时候,就称为模仿(impersonation)。ASP.NET框架组件应用程序可以选择模仿请求。
有些应用程序还希望根据请求的身份或者根据请求的身份所属的角色来动态地定制内容。ASP.NET框架组件应用程序可以动态地检测当前请求的身份是否属于某种角色。例如,应用程序可能希望检测当前用户是否属于管理员角色,以便为管理员有条件地生成内容。
ASP.NET 2.0的成员特性使你创建和管理用户更加容易了。成员特性一般与另外一个叫做角色管理器的新特性一起运作。角色管理器为创建角色和给角色指定用户提供了下层结构。当成员、角色管理器特性和窗体认证一起工作的时候,ASP.NET 2.0就可以为创建、认证和授权用户提供端对端的支持。
成员和角色管理器都是用基于提供程序的模型设计的。提供程序从特性所暴露的类和业务逻辑中提取特性的物理数据存储。成员和角色管理器特性都带有Microsoft SQL Server提供程序。成员特性还带有一个用于处理活动目录和活动目录应用程序模式(ADAM)的提供程序。角色管理器特性带有一个能利用Windows Server 2003授权管理特性的提供程序。你可以建立自定义的提供程序,并配置它与成员和角色管理器特性一起使用。使用自定义提供程序的时候,利用成员和角色管理器特性的页面仍然会继续工作,毫无改变。
登录控件是一组自定义的服务器控件,它为认证和授权事务提供了公用的用户界面。登录控件利用了成员、角色管理器和窗体认证特性中的功能。
认证和授权
ASP.NET与IIS一起支持使用基本的、Digest和Windows认证。ASP.NET支持微软Passport认证服务,它支持单点登录服务和用户配置服务。ASP.NET还支持一种使用基于窗体认证的强大的服务。基于窗体的认证使用Cookie来认证用户,并允许应用程序执行自己的凭证验证过程。
我们要认识到,ASP.NET认证服务是受到IIS提供的认证服务制约的。例如,为了在IIS应用程序中使用基本认证,你就必须使用Internet服务管理工具来配置应用程序以使用基本认证。
ASP.NET提供了两种授权服务:
· 检查ACL(访问控制列表)或资源权限,看某个认证过的用户是否能够访问该资源。
· URL授权,它批准一个身份使用一定的Web空间。
为了演示它们的差别,我们来看一个例子,假设某个应用程序允许匿名用户使用IUSR_MYMACHINE帐号访问。当某个ASP.NET页面(例如"/default.aspx")的请求通过认证之后,就会依据该文件(例如"c:\inetpub\wwwroot\default.aspx")的ACL进行检查,看IUSR_MYMACHINE帐号是否有权限读取这个文件。如果有权限,就对访问进行授权。如果Web内容位于NTFS卷中,并且已经配置了虚拟目录使用Windows认证,文件的授权就会自动地执行。
对于URL授权来说,会依据ASP.NET应用程序的配置数据来进行检查。如果允许访问被请求的URL,请求就获得授权了。在例子中,ASP.NET检查匿名用户是否有访问/Default.aspx的权限(也就是说,检查过程是依据URL本身的,没有依据URL最终解析成的文件)。
这种差别看起来很细微,但是它让应用程序能够使用类似基于窗体的认证或Passport认证,在这些认证模式中用户不需要与计算机或域帐号相对应。它还允许你进行虚拟资源的授权(在资源下方并没有物理文件)。例如,应用程序可以把所有对.stk文件的请求映射给一个处理程序,它根据查询字符串中的变量来进行证券报价。在这种情况下,没有物理的.stk文件可供ACL检查,因此使用URL授权来控制虚拟资源的访问权。
文件授权通常依赖IIS提供的通过认证的帐号来执行。如果允许匿名访问,它就是配置的匿名帐号。否则,就是NT帐号。它的工作方式跟ASP是一样的。
在资源管理器属性页面的"安全"选项卡中可以设置文件或目录的ACL(访问控制列表)。URL授权被配置为ASP.NET框架组件应用程序的一部分,在"授权用户和角色"部分有完整的讲解。
为了激活ASP.NET的认证服务,你必须在应用程序的配置文件中配置<authentication>元素。这个元素可以包含下表列举的任何值。
| 值 | 描述 |
| None | 没有激活的ASP.NET认证服务。请注意IIS认证服务仍然存在。 |
| Windows | ASP.NET认证服务给当前请求附加上WindowsPrincipal (System.Security.Principal.WindowsPrincipal),以保证根据NT用户或组进行授权。 |
| Forms | ASP.NET认证服务管理cookie并把未认证的用户重定向到登录页面。它通常在IIS允许匿名访问应用程序的时候使用。 |
| Passport | ASP.NET认证服务提供了Passport SDK (你必须安装)的一个方便的包装。 |
例如,下面的配置文件允许应用程序使用基于窗体(cookie)的认证:
| <configuration> <system.web> <authentication mode="Forms"/> </system.web> </configuration> |
使用登录控件
下面的例子演示了在应用程序中如何使用登录控件。
创建和登录用户
在例子中我们会看到站点的主页,它包含了一个LoginStatus控件,该控件提示用户登录站点。这个页面上的LoginStatus控件检查用户当前是否通过了认证,并向用户显示一个登录链接。用户点击这个链接就可以看到默认的login.aspx页面,在web.config中已经把这个页面配置为窗体认证。Login控件显示在Login.aspx页面上(请注意,在默认的登录页面上登录控件的VisibleWhenLoggedIn属性会被忽略)。在例子中,登录控件设置了额外的属性,显示了"创建用户"链接,点击这个链接会访问另外一个页面,那个页面使用了CreateUserWizard控件。在默认情况下,CreateUserWizard控件包含两个步骤,在第一步中用户输入必要的信息,当他们点击"创建用户"按钮的时候,控件把这些信息传递给成员API。如果成员API不能建立该用户,在控件中会显示适当的错误信息;如果用户创建成功,控件就载入向导的第二步。在例子中,ContinueDestinationPageUrl属性被设置为在用户创建成功之后返回主页。在默认情况下,当用户被成功创建之后,CreateUserWizard会认证并登录用户。当用户返回到主页的时候,他们会注意到LoginStatus被删除了,他们已经通过了认证,并显示了一个登出链接。点击登录链接会引起用户认证票据(ticket)被清除,并显示登录链接。这时用户可以点击登录链接,由于他们已经创建了用户帐号,所以可以在login.aspx上输入用户名和密码来登录网站。你可能注意到Login控件显示了一个"记住帐号(remember me)"检查框。选中这个框并成功登录之后,会向用户的计算机上写入一个cookie,该cookie默认的存续期是50年。你可以通过把Login控件的DisplayRememberMe和RememberMeSet属性设置为false来禁用这个选项。查看示例的代码,你可以发现这项事务并没有任何代码,只设置了少许的几个属性。这些控件的样式属性都是站点应用的样式表设置的。
| Login.aspx <%@ Page Language="VB" MasterPageFile="~/Site.master"%> <asp:Content ID="Content1" ContentPlaceHolderId="MainBody" runat="server"> <asp:login ID="Login1" runat="server" createuserurl="CreateUser.aspx" createusertext="Create a New Account" /> </asp:Content> CreateUser.aspx <%@ Page Language="VB" MasterPageFile="~/Site.master"%> <asp:Content ID="Content1" ContentPlaceHolderId="MainBody" runat="server"> <asp:CreateUserWizard ID="CreateUserWizard1" runat="server" continuedestinationpageurl="Home.aspx"/><br /> <a href="Home.aspx">Return to Default Home Page</a><br /> <a href="HomeLoginView.aspx">Return to LoginView Home Page</a><br /> <a href="HomeChangePassword.aspx">Return to ChangePassword Home Page</a><br /> </asp:Content> |
向认证用户显示不同的内容
下面的例子演示了使用LoginView控件为认证过的用户和匿名用户显示不同的内容。尽管例子中没有显示什么,但是LoginView控件支持基于用户角色来显示不同内容。LoginView控件中的AnonymousTemplate模板包含了一个登录控件,LoggedInTemplate模板包含了LoginName控件。LoginName控件利用格式化字符串属性来显示欢迎和用户姓名。请使用上一个例子中创建的帐号或重新创建一个帐号来登录站点,并点击页面上方的登出链接。
| <%@ Page Language="VB" MasterPageFile="~/Site.master"%> <asp:Content ID="Content1" ContentPlaceHolderId="MainBody" runat="server"> <asp:loginview ID="LoginView1" runat="server"> <loggedintemplate> <h1> <asp:loginname id="LoginName1" runat="server" formatstring="Welcome {0}" /> </h1> </loggedintemplate> <anonymoustemplate> <h1>Welcome to Login Controls</h1> <asp:login ID="Login1" runat="server" createuserurl="CreateUser.aspx" createusertext="Create a New Account" /> </anonymoustemplate> </asp:LoginView> </asp:Content> |
修改密码
在默认情况下,ChangePassword控件要求用户通过了站点的认证才能更改他们的密码。但是,在下面的例子中,我们把DisplayUserName属性设置为真,其结果是用户在改变自己的密码之前,可以由ChangePassword控件进行认证,或者通过站点认证的用户输入不同的帐号来改变密码。例子还链接到了创建用户页面,使你能够创建有效的用户并测试示例。
| <%@ Page Language="VB" MasterPageFile="~/Site.master"%> <asp:Content ID="Content1" ContentPlaceHolderId="MainBody" runat="server"> <asp:ChangePassword ID="ChangePassword1" runat="server" createuserurl="CreateUser.aspx" createusertext="Create a New Account" canceldestinationpageurl="HomeChangePassword.aspx" displayusername="true" continuedestinationpageurl="HomeChangePassword.aspx"/> </asp:Content> |
使用成员和角色管理器API
成员
成员特性是围绕两个核心类构建的:Membership和MembershipUser。Membership类提供创建用户(MembershipUser类处理)的方法,以及通用的管理用户的方法。用Membership类建立的用户是通过ASP.NET应用程序认证的身份。
Membership类执行的通用事务包括:
· 创建新的MembershipUser
· 当用户试图登录的时候验证用户名-密码组合。接下来你可以使用窗体认证来生成一个cookie,表明用户登录了站点。
· 检索MembershipUser实例
· 更新MembershipUser实例
· 根据不同的条件搜索用户
· 获取当前在线的通过认证的用户
· 在不需要用户的时候从系统中删除它
一旦你获取了MembershipUser实例,就可以直接使用MembershipUser类执行下面的事务:
· 访问应用程序中的MembershipUser类的属性
· 检索用户的密码(只有把成员特性配置为允许密码检索才可以使用)
· 改变或重置用户的密码
· 改变用户的密码提问和答案(如果成员特性被配置为在检索或更新密码之前,提示用户密码问题和答案)
· 解锁那些因为密码错误或密码答案错误而被锁定的用户
角色管理器
角色管理器的核心类是Roles类。Roles为创建角色和把用户指定给角色提供方法。它也提供了用于管理角色信息的方法。
使用Roles类可以执行的通用事务包括:
· 创建新角色
· 删除已有的角色
· 把用户指定给角色
· 从角色中删除用户
· 检测某个用户是否获得了特定角色的授权
· 搜索特定角色中的用户,检索角色中的所有用户
· 获取特定用户的角色信息
角色管理器特性也包含了HttpModule。这个模块负责检索用户分配的角色并把这些信息存储在RolePrincipal内,而它存在于页面的HttpContext中。HttpContext中存在RolePrincipal使你能够利用<authorization>元素来保护页面和目录。依据RolePrincipal中存储的角色信息,用户只能获得站点内特定页面和目录的访问权。
示例
下面的例子演示了在应用程序中如何使用成员 API。
创建新用户
下面的例子演示了如何建立新的MembershipUser。示例使用了Membership.CreateUser重载,它返回一个状态参数。其它的重载也可以使用,他们会抛出异常而不是返回状态代码。请注意,在默认情况下,成员特性要求密码至少有7个字符长度,并且密码至少包含一个非数字字符。
| <script runat="server"> Sub btnCreate_Click(ByVal sender As Object, ByVal e As System.EventArgs) Dim userName As String = txtUserId.Text '这个值式加密的或散列过,不会显示 Dim password As String = txtPassword.Text Dim email As String = txtEmail.Text Dim passwordQuestion As String = ddlPasswordQuestion.SelectedValue '这个值式加密的或散列过,不会显示 Dim passwordAnswer As String = txtPasswordAnswer.Text Dim result As MembershipCreateStatus Membership.CreateUser(userName, password, email, passwordQuestion, passwordAnswer, True, result) lblResults.Visible = True Select Case result Case MembershipCreateStatus.Success txtUserId.Text = Nothing txtPassword.Text = Nothing txtEmail.Text = Nothing ddlPasswordQuestion.SelectedIndex = -1 txtPasswordAnswer.Text = Nothing lblResults.Text = "User successfully created!" Case MembershipCreateStatus.InvalidUserName lblResults.Text = "The username format was invalid. Please enter a different username." Case MembershipCreateStatus.InvalidPassword lblResults.Text = "The password was invalid: A password cannot be an empty string and must also meet the pasword strength requirements of the configured provider. Please enter a new password." Case MembershipCreateStatus.InvalidEmail lblResults.Text = "The email format was invalid. Please enter a different username." Case MembershipCreateStatus.InvalidQuestion lblResults.Text = "The password question format was invalid. Please enter a different question." Case MembershipCreateStatus.InvalidAnswer lblResults.Text = "The password answer format was invalid. Please enter a different answer." Case MembershipCreateStatus.DuplicateUsername lblResults.Text = "The username is already in use. Please enter a new username." Case MembershipCreateStatus.DuplicateEmail lblResults.Text = "The email address is already in use. Please enter a different email address." Case Else lblResults.Text = "An error occurred while creating the user." End Select End Sub </script> |
用户登录和访问用户属性
下面的例子演示了用户使用Membership.ValidateUser方法登录。它还演示了在登录用户的时候如何同时使用窗体认证和成员特性。在上面的例子中创建用户之后,请在登录页面上输入凭证。一旦你登录了,你会被重定向到一个页面,该页面利用Membership.GetUser来检索与登录用户相对应的MembershipUser实例。同时请注意,这个页面还显示了目录上设置的用户属性,这些内容只有通过认证的用户才能访问。点击页面底部的登出链接可以退出站点。
| <script runat="server"> Protected memUser As MembershipUser Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) memUser = Membership.GetUser() End Sub Sub linkLogout_Click(ByVal sender As Object, ByVal e As System.EventArgs) FormsAuthentication.SignOut() Roles.DeleteCookie() FormsAuthentication.RedirectToLoginPage() End Sub </script> User Name/ID: <% = Server.HtmlEncode(memUser.Username) %> Email:<% = Server.HtmlEncode(memUser.Email) %> |
更新用户属性
请用前面建立的用户凭证登录。页面会用ASP.NET 2.0中新的DetailsView控件显示用户属性。DetailsView控件与一个数据源控件通讯。在例子中,ObjectDataSource控件检索MembershipUser实例的内容。你可以点击页面底部的"编辑"链接使DetailsView进入编辑模式。MembershipUser的电子邮件和注释都可以修改。点击"更新"链接可以把新值保存到数据库。请注意,在代码中页面实现了ItemUpdating事件,该事件是由ObjectDataSource引发的。这样做是必要的,MembershipUser类没有参数化构造函数,它要求使用ObjectDataSource的双向数据绑定。点击登出链接可以退出。
| Sub DetailsView1_ItemUpdating(ByVal sender As Object, ByVal e as DetailsViewUpdateEventArgs) '必须手动处理更新操作,因为MembershipUser 没有参数化的构造函数 Dim memUser as MembershipUser = Membership.GetUser() memUser.Email = CStr(e.NewValues(0)) memUser.Comment = CStr(e.NewValues(1)) Try Membership.UpdateUser(memUser) e.Cancel = true DetailsView1.ChangeMode(DetailsViewMode.ReadOnly) Catch ex as Exception Response.Write("<div>The following error occurred:<font color='red'> " + ex.Message + "</font></div>") e.Cancel = true End Try End Sub |
标题搜索
日历
|
|||||||||
| 日 | 一 | 二 | 三 | 四 | 五 | 六 | |||
| 1 | 2 | ||||||||
| 3 | 4 | 5 | 6 | 7 | 8 | 9 | |||
| 10 | 11 | 12 | 13 | 14 | 15 | 16 | |||
| 17 | 18 | 19 | 20 | 21 | 22 | 23 | |||
| 24 | 25 | 26 | 27 | 28 | 29 | 30 | |||
| 31 | |||||||||
我的存档
数据统计
- 访问量: 1925
- 日志数: 101
- 建立时间: 2006-11-29
- 更新时间: 2008-07-28
