ASP.NET安全问题--ASP.NET生命周期中的验证以及身份验证模块
ASP.NET生命周期中的验证以及身份验证模块
前言:最近一直很忙,没有来得及把之前的文章写完,已经有不少朋友在给我留言催我了,很感谢朋友们的关注,也跟大家说声对不起!
系列文章链接:
ASP.NET安全问题--ASP.NET安全架构--如何实现.NET安全
本篇主要一下话题:
1.ASP.NET运行的生命周期的验证
2.身份验证模块
3.授权模块
1.ASP.NET运行的生命周期的验证
其实在ASP.NET中每一个请求都进行了验证和授权的。进行验证和授权的过程实际上是通过触发相应的事件来完成的。
在讲述验证事件之前,首先清晰一个流程:ASP.NET运行时接到一个请求的处理的流程。
先把流程描述一下,使得大家有个总体把握:一个请求来了,经过IIS,通过ISAPI,就到达了ASP.NET的管道中,然后经过一些的转化和包装,然后ASP.NET运行时开始处理这个请求了,然后是进行验证和授权,然后再进行一系列的处理,最后确定请求是是什么文件,如果是.aspx的,那么然后就开始页面的生命周期,如下图。
下面就处理请求时候触发的事件顺序如下:
BeginRequest: 开发处理请求,是处理ASP.NET请求时触发的第一个事件
AuthenticateRequest:处理身份验证
...
AuthorizeRequest:处理授权
...
所以大家可以看出,其实在请求的处理过程中,身份的验证和授权发生的时期是很早的。而且有关验证的一些信息,如用户名和角色在处理完这两个事件之后就已经确定,并且填充。下面我想用个图来讲述:
一般对于请求的验证和授权,我们是希望也应该自己控制这个过程的,所以我们可以在AuthenticateRequest和AuthorizeRequest的事件处理中加入我们自己的代码。一般在网站中加入 Global.asax文件。
AuthenticateRequest事件:
当一个请求需要进行身份验证时,HttpApplication对象就会触发AuthenticateRequest事件,这也意味着每次对ASP.NET应用程序进行页面请求时都会触发这个事件。
在这个事件中实际上是调用相应的身份验证模块来处理身份验证的。例如对于Forms身份验证模块而言,就是从加密的cookie中提取用户信息。
AuthorizeRequest事件:
AuthorizeRequest事件是在AuthenticateRequest事件中通过了身份验证时候才触发的。AuthorizeRequest事件调用相应的授权模块来检查用户是否被授权访问他们请求的资源。因为在AuthenticateRequest事件完成之后就已经有了用户的表示Identity和IPricipal,也就知道了用户名和角色的信息。
2.身份验证模块
身份验证是利用ASP.NET中的身份验证模块来实现的。在ASP.NET中内置有四个验证模块:
DefaultAuthenticateModule,FormsAuthenticateModule,WindowsAuthenticateModule,PassportAuthenticateModule.他们都实现了IHttpModule接口,当然,如果需要,我们也可以实现自定义的验证模块。
从验证模块就可以看出我们一般的身份验证是怎么进行的,决定采用个验证模块是由我们决定采用哪种身份验证决定的,如Forms验证就是用了FormsAuthenticateModule来处理的。而且还要配置web.config文件
中的<authentication/>元素。
下面我们就先来看看身份验证模块的实现(伪码)
大家可以看到,其实在模块的Init方法中就订阅了AuthenticateRequest事件,而我们在Global.asax中写的代码就是我们具体处理的代码:
{
//自定义验证代码
}
还有一点要注意的就是:每个模块都有一个Authenticate事件。
下面就说说常用的两个个验证模块,因为大同小异:
WindowsAuthenticateModule:
WindowsAuthenticateModule是和IIS身份验证联合试用的,当web.config 的中配置如下:
<authentication mode="Windows"/>
此时,这个模块就激活了,在Global.asax文件中就的Application_Authenticate(object sender,eventArgs e)就是给Windows验证用的。
这里有一个问题要澄清:如果是我们配置的是Windows身份验证,我们在Application_Authenticate中就只能写和Windows身份验证有关的代码,如果是配置的是Forms验证,我们在Application_Authenticate就只能写和Forms有关的代码,如获取cookie信息等。也就是说,Application_Authenticate方法是"一法多用"。
接着谈 Windows验证,在上面的处理程序中,我们可以创建自己的用户信息,如我们创建一个WindowsPrincipal类的实例(实现了IPrincipal接口,包含用户名和角色的信息),然后它赋值给 HttpContext.User属性。这正如我们之前说的,验证事件执行完之后,我们就知道了这个请求的发起者的用户名和角色信息。
FormsAuthenticateModule:
首先还是要配置:<authentication mode="Forms"/>.
FormsAuthenticateModule可以利用cookie解析保存在cookie中的用户的信息,并且创建一个GenericPrincipal,把用户名和角色信息保存在其中,然后赋值给User属性,以备后用。
3.授权模块
在ASP.NET中内置的授权模块主要有两个:FileAuthorizationModule和UrlAuthorizationModule。他们也实现了IHttpModule接口。这些模块可以参照所试用的身份验证类型来决定到底采用哪个授权模块:
如果试用的是Windows身份验证,那么在授权检查的时候就会使用FileAuthorizationModule;
如果在web.config中提供了<authorization/>元素,那么就会采用UrlAuthorizationModule。如下面的:
<allow roles ="" users=""/>
<deny users=""/>
</authorization>
FileAuthorizationModule:
如果使用 Windows身份验证,就会采用FileAuthorizationModule模块。这个模块可以处理Authorization事件,并且能够对IIS提供的请求的令牌和目标资源执行访问检查。而且这也用到了系统的ACL(访问控制列表).
例 如,如果请求的资源是Default.aspx,当前的用户是xiaoyang,那么FileAuthorizationModule就会执行访问检查,看看xiaoyang时候具备访问Default.aspx的读的权限,如果在Windows的用户账户中有xiaoyang这个账户,并且具有访问的权限,那么请求成功,否则,FileAuthorizationModule就把Reponse.StatusCode设置为401(未授权),之后请求就结束了。
UrlAuthorizationModule:
和上面的处理模块不一样,不管使用何种类型的身份验证,只要配置了web.config中的<authorization/>元素,就要使用UrlAuthorizationModule模块。这个模块在处理的时候执行如下:
1,把<authorization/>中声明的用户名和HttpContext.User.Identity进行比较
2.把<authorization/>声明的角色信息和HttpContext.User.IsInRole比较
如果比较成功就可以访问相应的授权的资源,否则把Reponse.StatusCode设置为401(未授权),之后请求就结束了。
今天就到这里,下篇我们详细谈谈Forms验证和授权的各种细节。