对ASP.NET网站执行代码覆盖率测试发生System.Security.VerificationException异常的解决方案

简介:

当你对ASP.NET 4.0网站执行代码覆盖率测试时,可能会遇到下面这个异常:

System.Security.VerificationException: Operation could destabilize the runtime.

一般来说,VerificiationException都是关于代码访问安全(CAS)的问题,.NET在执行托管代码之前,首先会验证这个托管程序的强签名,通过确定其来源来判定该托管程序应该拥有的权限。比如说,如果托管程序是微软公司的签名,我们当然是无比的信任它—除非你不用Windows操作系统。机器管理员也可以依据托管程序的来源来决定该托管程序应该拥有的权限,例如读磁盘文件、操作注册表这些操作都是可以配置的权限。比方说,管理员可以在机器上设置,由360以及QQ发行的托管程序,只能访问显卡(绘制界面)以及读写网络,而不能执行访问磁盘文件等操作。

执行代码安全的前提是,整个程序完全是由托管代码写成的,如果托管代码里混合非托管代码,无论是通过托管C++写成的,还是里面执行了平台调用(P/Invoke)。就破坏规矩了,因为非托管代码可以使用指针操作,以及调用其它非托管代码的方式,甚至—启动一个进程,然后将原来的托管程序杀掉。因此,进行代码访问安全的前提条件是,整个应用程序都是使用托管代码写成的,为了保证这个前提条件,CLR在执行托管程序之前,首先会验证程序是否满足—整个程序都是用托管代码编写这一条件。如果不满足这个条件,那么CLR会扔出VerificationException,中断托管程序的执行,在.NET SDK里,你可以通过PEVerify.exe这个程序验证一个程序是否可以通过这个验证。

 

当然,你可能会说,很多本机运行的托管程序,即使调用了非托管代码,例如执行了一个平台调用,还是可以照常执行啊。那是因为,当你的程序使用了/unsafe编译选项时,C#编译器会自动在托管程序添加上SuppressUnmanagedCodeSecurityAttribute这个属性,这个属性告诉CLR。如果程序是在本机执行,那么就跳过验证是否调用了非托管代码这一环节。有兴趣的读者可以把调用非托管代码的托管程序放在一个网络路径上,从那里执行,应该就可以看到SecurityException了。

 

回到ASP.NET网站的情形,当你将ASP.NET网站的装配件(Assembly)使用 vsinstr.exe创建一个可以收集代码覆盖率的装配件(Assembly)时,vsinstr.exe实际上在装配件(Assembly)的IL代码里,添加了很多收集代码覆盖率的代码。这个过程可以参考我以前的文章:软件自动化测试—代码覆盖率。这些代码里,有一个很重要的步骤,就是联系本机运行的VSPerfMon.exeVSPerfMon.exe是用来收集整个机器上代码覆盖率的,不知道是什么愿意,联系本机运行的VSPerfMon.exe过程是通过非托管的API实现的,这就意味着vsinstr.exe生成的 装配件(Assembly)就必须调用到非托管代码,因此也就通过CLR的验证过程。

 

在2.0的时候,你可能还不会碰到这个问题,但是在4.0里面,你就很有可能碰到这个问题—特别是在网站运行在IIS下的话,经常发生。

 

既然道理已经明白了,修复起来也很容易:

  1. 将网站,以及所有需要做代码覆盖率的装配件(Assembly)—也就是被vsinstr.exe处理过的装配件(Assembly),在它们的源代码(既然你要收集代码覆盖率,那肯定是由源代码的)里的AssemblyInfo.cs里,加上下面这一行

 

[assembly: SecurityRules(SecurityRuleSet.Level1, SkipVerificationInFullTrust=true)]

 

  1. 然后在网站的web.config里,做如下修改(这个选项也可以通过IISAdmin.exe修改):

 

 <system.web>

    <trust level="Medium" />

 

     …

 </system.web>

 

说明,SecurityRules这个属性,告诉CLR,这个装配件(Assembly)有自定义的安全机制,SecurityRuleSet.Level1说明采用.NET 2.0下面的安全验证策略,SkipVerificationInFullTrust告诉CLR,只有网站运行在FullTrust模式下,才可以跳过安全验证。最后第二步就是将网站的运行模式改在FullTrust模式下。

标签:  CLR


本文转自 donjuan 博客园博客,原文链接:   http://www.cnblogs.com/killmyday/archive/2010/11/16/1878847.html ,如需转载请自行联系原作者
相关文章
|
9天前
|
测试技术 C语言
网站压力测试工具Siege图文详解
网站压力测试工具Siege图文详解
18 0
|
1月前
|
敏捷开发 运维 安全
链家网站系统测试设计与实现_kaic
链家网站系统测试设计与实现_kaic
|
4月前
|
前端开发 Java 测试技术
JavaSE碎碎念:记录一次异常测试和一些个人的浅显理解
JavaSE碎碎念:记录一次异常测试和一些个人的浅显理解
|
7月前
|
自然语言处理 测试技术 C#
NSubstitute:一个简单易用、灵活多变的.NET单元测试模拟框架
NSubstitute是一个开源的.NET单元测试模拟类库,该框架设计的主要目标是提供一个简单明了、易用性强、贴近自然语言的模拟测试框架。它使得开发者能够专注于测试工作,而不是纠结于测试替代实例的创建和配置。
78 5
|
7月前
|
存储 C# 数据库
.NET开源的在Windows上统计软件使用时长和网站浏览时长工具 - Tai
.NET开源的在Windows上统计软件使用时长和网站浏览时长工具 - Tai
|
9天前
|
测试技术 Linux Apache
网站压力测试工具webbench图文详解
网站压力测试工具webbench图文详解
8 0
|
1月前
|
SQL Apache 流计算
Apache Flink官方网站提供了关于如何使用Docker进行Flink CDC测试的文档
【2月更文挑战第25天】Apache Flink官方网站提供了关于如何使用Docker进行Flink CDC测试的文档
139 3
|
2月前
|
前端开发 测试技术 Android开发
自动化测试学习网站
自动化测试学习网站
|
2月前
|
敏捷开发 测试技术 持续交付
几个有用的测试网站
几个有用的测试网站
|
2月前
|
SQL 安全 测试技术
面试题10: 如何测试一个网站?
面试题10: 如何测试一个网站?