1

我在 Reporting Service 2008 中运行了一个 Delivery Extension。

它已经运行了很长时间。但现在我想从扩展中插入数据库。

我得到的第一个错误是:

Exception: System.Security.SecurityException Exception Message: Request for the permission of type 'System.Data.SqlClient.SqlClientPermission, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed. Stacktrace:    at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
   at System.Security.PermissionSet.Demand()
   at System.Data.Common.DbConnectionOptions.DemandPermission()
   at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
   at System.Data.SqlClient.SqlConnection.Open()

然后我在打开连接并插入的代码之前添加了这个:

SqlClientPermission sqlPermission = new SqlClientPermission(System.Security.Permissions.PermissionState.Unrestricted);
sqlPermission.Assert();

然后错误信息变成了这样:

Exception: System.Security.SecurityException Exception Message: Request for the permission of type 'System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed. Stacktrace:    at System.Security.CodeAccessSecurityEngine.CheckNReturnSO(PermissionToken permToken, CodeAccessPermission demand, StackCrawlMark& stackMark, Int32 unrestrictedOverride, Int32 create)
   at System.Security.CodeAccessSecurityEngine.Assert(CodeAccessPermission cap, StackCrawlMark& stackMark)
   at System.Security.CodeAccessPermission.Assert()

然后我添加了以下行:

SecurityPermission permission = new SecurityPermission(PermissionState.Unrestricted);
permission.Assert();

现在我得到的错误是:

Exception: System.Security.SecurityException Exception Message: Stack walk modifier must be reverted before another modification of the same type can be performed. Stacktrace:    at System.Security.CodeAccessSecurityEngine.Assert(CodeAccessPermission cap, StackCrawlMark& stackMark)
   at System.Security.CodeAccessPermission.Assert()

我的包含实际 SqlConnection 特定代码的代码位于从 Delivery Extension 引用的程序集中。特定于权限的代码在该程序集中,但我尝试将其移动到 Delivery Extension 程序集中 - 但没有任何运气。

4

2 回答 2

1

user407428 是正确的,尝试启用两个不同的修饰符是导致您的问题的原因。最好的原则是允许需要的部分代码的权限,然后在后面禁用权限。这样当您需要下一个权限时,您可以再次修改这些权限。

SqlClientPermission sqlClientPermission = new SqlClientPermission(PermissionState.Unrestricted);
sqlClientPermission.Assert();

   //<your code that requires SqlClientPermission here>

CodeAccessPermission.RevertAccess();

SecurityPermission securityPermission = new SecurityPermission(PermissionState.Unrestricted);
securityPermission.Assert();

还有一些需要考虑的事情是,大多数情况下不需要将对象保留在堆栈遍历中,因此断言可以简化为一行,ei。

System.Security.Permissions.SecurityPermission(System.Security.Permissions.PermissionState.Unrestricted).Assert();

如果您在封装方法中修改了堆栈遍历,则内部堆栈可能无法再次修改修饰符。前任。

public void UseSecurityPermission()
{
    CodeAccessPermission.RevertAssert();
    new System.Security.Permissions.SecurityPermission(System.Security.Permissions.PermissionState.Unrestricted).Assert();

    <Some code that requires the SecurityPermission>
}

static void Main(string[] args)
{
    new System.Security.Permissions.FileIOPermission(System.Security.Permissions.PermissionState.Unrestricted).Assert();
    //< Some code that requires IOPermission>
    UseSecurityPermission();
}   

即使 UseSecurityPermission() 恢复堆栈遍历权限,它也不起作用,因为编译器无法在上下文中获取安全描述符。

进一步阅读: 使用 Stack-Walk 修饰符编程

于 2017-01-10T07:27:19.173 回答
0

在您尝试修改访问权限时,您可能已经从更高级别继承了它,或者您可能已经在您之前的某个地方完成了它。

例如我们有这样的代码:

SqlClientPermission sqlClientPermission = new SqlClientPermission(PermissionState.Unrestricted);
sqlClientPermission.Assert();

SecurityPermission securityPermission = new SecurityPermission(PermissionState.Unrestricted);
securityPermission.Assert();

我们会有像你这样的例外。

于 2010-07-31T11:36:37.937 回答