您好,欢迎访问三七文档
1/20细说ASP.NETForms身份认证阅读目录开始ASP.NET身份认证基础ASP.NET身份认证过程如何实现登录与注销保护受限制的页面登录页不能正常显示的问题认识Forms身份认证理解Forms身份认证实现自定义的身份认证标识在多台服务器之间使用Forms身份认证在客户端程序中访问受限页面用户登录是个很常见的业务需求,在ASP.NET中,这个过程被称为身份认证。由于很常见,因此,我认为把这块内容整理出来,与大家分享应该是件有意义的事。在开发ASP.NET项目中,我们最常用的是Forms认证,也叫【表单认证】。这种认证方式既可以用于局域网环境,也可用于互联网环境,因此,它有着非常广泛的使用。这篇博客主要讨论的话题是:ASP.NETForms身份认证。有一点我要申明一下:在这篇博客中,不会涉及ASP.NET的登录系列控件以及membership的相关话题,我只想用比较原始的方式来说明在ASP.NET中是如何实现身份认证的过程。回到顶部ASP.NET身份认证基础在开始今天的博客之前,我想有二个最基础的问题首先要明确:1.如何判断当前请求是一个已登录用户发起的?2.如何获取当前登录用户的登录名?在标准的ASP.NET身份认证方式中,上面二个问题的答案是:1.如果Request.IsAuthenticated为true,则表示是一个已登录用户。2.如果是一个已登录用户,访问HttpContext.User.Identity.Name可获取登录名(都是实例属性)。接下来,本文将会围绕上面二个问题展开,请继续阅读。回到顶部2/20ASP.NET身份认证过程在ASP.NET中,整个身份认证的过程其实可分为二个阶段:认证与授权。1.认证阶段:识别当前请求的用户是不是一个可识别(的已登录)用户。2.授权阶段:是否允许当前请求访问指定的资源。这二个阶段在ASP.NET管线中用AuthenticateRequest和AuthorizeRequest事件来表示。在认证阶段,ASP.NET会检查当前请求,根据web.config设置的认证方式,尝试构造HttpContext.User对象供我们在后续的处理中使用。在授权阶段,会检查当前请求所访问的资源是否允许访问,因为有些受保护的页面资源可能要求特定的用户或者用户组才能访问。所以,即使是一个已登录用户,也有可能会不能访问某些页面。当发现用户不能访问某个页面资源时,ASP.NET会将请求重定向到登录页面。受保护的页面与登录页面我们都可以在web.config中指定,具体方法可参考后文。在ASP.NET中,Forms认证是由FormsAuthenticationModule实现的,URL的授权检查是由UrlAuthorizationModule实现的。回到顶部如何实现登录与注销前面我介绍了可以使用Request.IsAuthenticated来判断当前用户是不是一个已登录用户,那么这一过程又是如何实现的呢?为了回答这个问题,我准备了一个简单的示例页面,代码如下:fieldsetlegend用户状态/legendformaction=%=Request.RawUrl%method=post%if(Request.IsAuthenticated){%当前用户已登录,登录名:%=Context.User.Identity.Name.HtmlEncode()%br/inputtype=submitname=Logonvalue=退出/%}else{%b当前用户还未登录。/b%}%/form/fieldset页面显示效果如下:3/20根据前面的代码,我想现在能看到这个页面显示也是正确的,是的,我目前还没有登录(根本还没有实现这个功能)。下面我再加点代码来实现用户登录。页面代码:fieldsetlegend普通登录/legendformaction=%=Request.RawUrl%method=post登录名:inputtype=textname=loginNamestyle=width:200pxvalue=Fish/inputtype=submitname=NormalLoginvalue=登录//form/fieldset现在页面的显示效果:登录与退出登录的实现代码:publicvoidLogon(){4/20FormsAuthentication.SignOut();}publicvoidNormalLogin(){//-----------------------------------------------------------------//注意:演示代码为了简单,这里不检查用户名与密码是否正确。//-----------------------------------------------------------------stringloginName=Request.Form[loginName];if(string.IsNullOrEmpty(loginName))return;FormsAuthentication.SetAuthCookie(loginName,true);TryRedirect();}现在,我可试一下登录功能。点击登录按钮后,页面的显示效果如下:从图片的显示可以看出,我前面写的NormalLogin()方法确实可以实现用户登录。当然了,我也可以在此时点击退出按钮,那么就回到了图片2的显示。写到这里,我想有必要再来总结一下在ASP.NET中实现登录与注销的方法:1.登录:调用FormsAuthentication.SetAuthCookie()方法,传递一个登录名即可。2.注销:调用FormsAuthentication.SignOut()方法。5/20回到顶部保护受限制的页面在一个ASP.NET网站中,有些页面会允许所有用户访问,包括一些未登录用户,但有些页面则必须是已登录用户才能访问,还有一些页面可能会要求特定的用户或者用户组的成员才能访问。这类页面因此也可称为【受限页面】,它们一般代表着比较重要的页面,包含一些重要的操作或功能。为了保护受限制的页面的访问,ASP.NET提供了一种简单的方式:可以在web.config中指定受限资源允许哪些用户或者用户组(角色)的访问,也可以设置为禁止访问。比如,网站有一个页面:MyInfo.aspx,它要求访问这个页面的访问者必须是一个已登录用户,那么可以在web.config中这样配置:locationpath=MyInfo.aspxsystem.webauthorizationdenyusers=?//authorization/system.web/location为了方便,我可能会将一些管理相关的多个页面放在Admin目录中,显然这些页面只允许Admin用户组的成员才可以访问。对于这种情况,我们可以直接针对一个目录设置访问规则:locationpath=Adminsystem.webauthorizationallowroles=Admin/denyusers=*//authorization/system.web/location这样就不必一个一个页面单独设置了,还可以在目录中创建一个web.config来指定目录的访问规则,请参考后面的示例。在前面的示例中,有一点要特别注意的是:1.allow和deny之间的顺序一定不能写错了,UrlAuthorizationModule将按这个顺序依次判断。2.如果某个资源只允许某类用户访问,那么最后的一条规则一定是denyusers=*/6/20在allow和deny的配置中,我们可以在一条规则中指定多个用户:1.使用users属性,值为逗号分隔的用户名列表。2.使用roles属性,值为逗号分隔的角色列表。3.问号(?)表示匿名用户。4.星号(*)表示所有用户。回到顶部登录页不能正常显示的问题有时候,我们可能要开发一个内部使用的网站程序,这类网站程序要求禁止匿名用户的访问,即:所有使用者必须先登录才能访问。因此,我们通常会在网站根目录下的web.config中这样设置:authorizationdenyusers=?//authorization对于我们的示例,我们也可以这样设置。此时在浏览器打开页面时,呈现效果如下:从图片中可以看出:页面的样式显示不正确,最下边还多出了一行文字。这个页面的完整代码是这样的(它引用了一个CSS文件和一个JS文件):页面最后一行文字平时不显示是因为JScript.js中有以下代码:7/20document.getElementById(hideText).setAttribute(style,display:none);这段JS代码能做什么,我想就不用再解释了。虽然这段JS代码没什么价值,但我主要是想演示在登录页面中引用JS的场景。根据前面图片,我们可以猜测到:应该是CSS和JS文件没有正确加载造成的。为了确认就是这样原因,我们可以打开FireBug再来看一下页面加载情况:根据FireBug提供的线索我们可以分析出,页面在访问CSS,JS文件时,其实是被重定向到登录页面了,因此获得的结果肯定也是无意义的,所以就造成了登录页的显示不正确。还记得前所说的【授权】吗?是的,现在就是由于我们在web.config中设置了不允许匿名用户访问,因此,所有的资源也就不允许匿名用户访问了,包括登录页所引用的CSS,JS文件。当授权检查失败时,请求会被重定向到登录页面,所以,登录页本身所引用的CSS,JS文件最后得到的响应内容其实是登录页的HTML代码,最终导致它们不能发挥作用,表现为登录页的样式显示不正确,以及引用的JS文件也不起作用。不过,有一点比较奇怪:为什么访问登录页面时,没有发生重定向呢?原因是这样的:在ASP.NET内部,当发现是在访问登录面时,会设置HttpContext.SkipAuthorization=true(其实是一个内部调用),这样的设置会告诉后面的授权检查模块:跳过这次请求的授权检查。因此,登录页总是允许所有用户访问,但是CSS文件以及JS文件是在另外的请求中发生的,那些请求并不会要跳过授权模块的检查。为了解决登录页不能正确显示的问题,我们可以这样处理:1.在网站根目录中的web.config中设置登录页所引用的JS,CSS文件都允许匿名访问。8/202.也可以直接针对JS,CSS目录设置为允许匿名用户访问。3.还可以在CSS,JS目录中创建一个web.config文件来配置对应目录的授权规则。可参考以下web.config文件:?xmlversion=1.0?configurationsystem.webauthorizationallowusers=*//authorization/system.web/configuration第三种做法可以不修改网站根目录下的web.config文件。注意:在IIS中看到的情况就和在VisualStudio中看到的结果就不一样了。因为,像js,css,image这类文件属于静态资源文件,IIS能直接处理,不需要交给ASP.NET来响应,因此就不会发生授权检查失败,所以,如果这类网站部署在IIS中,看到的结果又是正常的。回到顶部认识Forms身份认证前面我演示了如何用代码实现登录与注销的过程,下面再来看一下登录时,ASP.NET到底做了些什么事情,它是如何知道当前请求是一个已登录用户的?在继续探索这个问题前,我想有必要来了解一下HTTP协议的一些特点。HTTP是一个无状态的协议,无状态的意思可以理解为:WEB服务器在处理所有传入请求时,根本就不知道某个请求是否是一个用户的第一次请求与后续请求,或者是另一个用户的请求。WEB服务器每次在处理请求时,都会按照用
本文标题:细说ASP
链接地址:https://www.777doc.com/doc-2065834 .html