通过反射加载的程序集中 SqlClientPermission 失败

发布于 2024-07-29 13:32:39 字数 445 浏览 7 评论 0原文

我遇到了一个非常困难的问题。 我刚刚修改了一个 Web 应用程序,允许客户提供自定义程序集,他们可以使用这些程序集挂接到实体保存管道中。 当实体保存到数据库时,这些自定义程序集通过反射加载。 它们指的是处理所有数据访问的通用 DAL 程序集。

我有一个测试服务器(Win2k3),该系统可以完美运行。 现在我已经将它推送到我的生产服务器集群(一个 Win2k3 和一个 Win2k8),我的自定义程序集在第一次调用访问数据库 (SQL2005) 的 DAL 方法时就会崩溃。 我收集的日志信息表明获取 SqlClientPermission 失败。 与最佳实践相反,我的 Web 应用程序在完全信任状态下运行。 我的自定义程序集是强命名的。

对于我可以在哪里查找测试服务器配置和生产服务器配置之间的差异,有什么建议吗? 如果这不是合适的论坛,哪一个才是合适的论坛?

谢谢, 马修

I am having a really tough time with a problem. I have a web application that I have just modified that allows customers to supply custom assemblies that they can use to hook into an entity save pipeline. These custom assemblies are loaded via reflection when an entity is persisted to the database. They refer to a common DAL assembly that handles all of the data access.

I have a test server (Win2k3) where this system works flawlessly. Now that I've pushed it out to my production server cluster (one Win2k3 and one Win2k8), my custom assembly bombs the first time it calls a DAL method that accesses the database (SQL2005). The log information that I gather indicates that there is a failure in getting a SqlClientPermission. Contrary to best practices, I have my web app running in Full Trust. My custom assembly is strong named.

Are there any suggestions to where I can look for differences between my test server config and my production server configs? If this is not the proper forum, which one is?

Thanks,
Matthew

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

追我者格杀勿论 2024-08-05 13:32:39

我在没有反思的情况下遇到了类似的问题。 我正在将一个已编译的项目从我的 Win 2k3 机器移动到 Win 2k8。
- 在 IIS 中,进入 dll 所在的 bin 文件夹并右键单击。
- 转到“编辑权限...”。
- 在“常规”选项卡的最底部可能有一个按钮,显示“取消阻止”。

Win 2k8似乎不喜欢从其他环境复制的dll。

I was running into a similar issue without the reflection. I was moving a compiled project from my Win 2k3 machine to Win 2k8.
- In IIS go under the bin folder where you dll's are to and right click.
- Go to "Edit Permissions...".
- At the very bottom of the "General" tab there may be a button saying UnBlock.

Win 2k8 doesn't seem to like the dll's copied from another environment.

似狗非友 2024-08-05 13:32:39

不是答案,但比我可以在评论中添加的信息更多...

现在看来,这是一个 Win2k8 与 Win2k3 问题,因为我不再在集群中的 Win2k3 服务器的日志中收到任何异常。

基本上,发生的情况是我们的实体保存管道检查要保存的实体类型是否实现某个接口。 如果是这样,则应用程序将前往数据库检索实现客户特定的保存前和保存后功能的类的程序集和类名。 这些程序集位于“App_Data”文件夹下名为“Assemblies\”的文件夹中。 然后应用程序加载程序集; 使用反射将该程序集中的正确类实例化为接口,然后调用该接口上的 pre 和 post save 方法来执行该特定实体类型的客户特定操作。 在我们的示例中,此自定义操作使用我们的 DAL(使用 LLBLGen、FWIW)实体类执行一些数据库操作。

我最初的问题是,我收到了有关不允许部分受信任的调用者的 SecurityException,因此我修饰了与“AllowPartiallyTrustedCallers”属性一起使用的程序集。

在加载的扩展程序集中,我实例化了 SqlClientPermission 和“Assert()”它,但我没有在任何地方实际授予该权限(除了我的 Web 应用程序在 FullTrust 中运行)。

感谢您提供的任何帮助...

-Matthew

这是抛出的异常的 .ToString() 输出:

Error performing post-save operation on entity 373c595e-843b-45a1-82d0-aa166daf75de of type SS2DAL.EntityClasses.SurveyResponseEntity: SD.LLBLGen.Pro.ORMSupportClasses.ORMQueryExecutionException: An exception was caught during the execution of a retrieval query: Request for the permission of type 'System.Data.SqlClient.SqlClientPermission, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.. Check InnerException, QueryExecuted and Parameters of this exception to examine the cause of this exception. ---> System.Security.SecurityException: Request for the permission of type 'System.Data.SqlClient.SqlClientPermission, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
   at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
   at System.Security.CodeAccessPermission.Demand()
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior)
   at SD.LLBLGen.Pro.ORMSupportClasses.RetrievalQuery.Execute(CommandBehavior behavior)
The action that failed was:
Demand
The type of the first permission that failed was:
System.Data.SqlClient.SqlClientPermission
The first permission that failed was:
<IPermission
version="1"
AllowBlankPassword="False">
<add KeyRestrictions=""
KeyRestrictionBehavior="AllowOnly"/>
</IPermission>

The demand was for:
<IPermission
version="1"
AllowBlankPassword="False">
<add KeyRestrictions=""
KeyRestrictionBehavior="AllowOnly"/>
</IPermission>

The granted set of the failing assembly was:
<PermissionSet
version="1">
<IPermission
version="1"
Access="Open"/>
<IPermission
version="1"
Allowed="ApplicationIsolationByUser"
UserQuota="512000"/>
<IPermission
version="1"
Flags="Execution"/>
<IPermission
version="1"
Window="SafeTopLevelWindows"
Clipboard="OwnClipboard"/>
<IPermission
version="1"
PublicKeyBlob="0024000004800000940000000602000000240000525341310004000001000100B55C03865E07BCB230B04EF7D9ACF1E7BF41C618DB1327895C25328446039F51CF237A50989E542D3FA9BB5991D303388C5AAC7AE4E071CD7B42B96B16256FF905EC610107DB2A0872E971253919BA528187489FC89FD083118F562319BF3B66CB79035EC50D2291561D4F2B9733AD5E0ECD9BFF9B80B94C40F5888D4E1C5BDD"
Name="ProjectHelpers.Extensions"
AssemblyVersion="2.2009.208.1821"/>
<IPermission
version="1"
Url="file://dc01.bizspeed.datacenter/websites/sitesupervisor files/prjh/ProjectHelpers.Extensions.dll"/>
<IPermission
version="1"
Zone="Internet"/>
<IPermission
version="1"
Level="SafePrinting"/>
</PermissionSet>

The assembly or AppDomain that failed was:
ProjectHelpers.Extensions, Version=2.2009.208.1821, Culture=neutral, PublicKeyToken=4405fd38c7d52787
The method that caused the failure was:
SD.LLBLGen.Pro.ORMSupportClasses.EntityBase2 AfterSave(SD.LLBLGen.Pro.ORMSupportClasses.EntityBase2, SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase)
The Zone of the assembly that failed was:
Internet
The Url of the assembly that failed was:
file://dc01.bizspeed.datacenter/websites/sitesupervisor files/prjh/ProjectHelpers.Extensions.dll
   --- End of inner exception stack trace ---
   at SD.LLBLGen.Pro.ORMSupportClasses.RetrievalQuery.Execute(CommandBehavior behavior)
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.ExecuteSingleRowRetrievalQuery(IRetrievalQuery queryToExecute, IEntityFields2 fieldsToFill, IFieldPersistenceInfo[] fieldsPersistenceInfo)
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntityUsingFilter(IEntityFields2 fieldsToFetch, IFieldPersistenceInfo[] persistenceInfos, IRelationPredicateBucket filter)
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntityUsingFilter(IEntity2 entityToFetch, IPrefetchPath2 prefetchPath, Context contextToUse, IRelationPredicateBucket filter, ExcludeIncludeFieldsList excludedIncludedFields)
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntity(IEntity2 entityToFetch, IPrefetchPath2 prefetchPath, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields)
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntity(IEntity2 entityToFetch, IPrefetchPath2 prefetchPath)
   at ProjectHelpers.Extensions.SurveyResponseSaveHelper.AfterSave(EntityBase2 entity, DataAccessAdapterBase adapter)
   at SS2.RemoteObjects.DataPortal.EntitySaveWithoutRemoting(EntityBase2 entity, AuditSettings auditSettings, AuthTicket at)  [NDC:(null)]

Not an answer, but more info than I can put in a comment...

It would appear now that this is a Win2k8 vs Win2k3 issue since I no longer get any exceptions in the logs from the Win2k3 server in our cluster.

Basically, what happens is that our entity save pipeline checks to see if the entity type being saved implements a certain interface. If so, then the application goes out to the database to retrieve the assembly and class name of the class that implements the customer-specific pre- and post- save functionality. Those assemblies are under the "App_Data" folder in an folder called "Assemblies\". The application then loads the assembly; uses reflection to instantiate the proper class from that assembly as an interface, then calls the pre and post save methods on that interface to perform the customer specific actions for that particular entity type. In our case, this custom action performs some database operations using our DAL (which uses LLBLGen, FWIW) entity classes.

My initial issue was that I was getting a SecurityException about not allowing partially trusted callers, so I decorated the assemblies that are used with the "AllowPartiallyTrustedCallers" attribute.

In my extension assemby that gets loaded, I instantiate a SqlClientPermission and "Assert()" it, but I haven't anywhere actually granted that permission (except that my web app runs in FullTrust).

Thanks for whatever help you can offer...

-Matthew

Here is the .ToString() output of the exception that gets thrown:

Error performing post-save operation on entity 373c595e-843b-45a1-82d0-aa166daf75de of type SS2DAL.EntityClasses.SurveyResponseEntity: SD.LLBLGen.Pro.ORMSupportClasses.ORMQueryExecutionException: An exception was caught during the execution of a retrieval query: Request for the permission of type 'System.Data.SqlClient.SqlClientPermission, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.. Check InnerException, QueryExecuted and Parameters of this exception to examine the cause of this exception. ---> System.Security.SecurityException: Request for the permission of type 'System.Data.SqlClient.SqlClientPermission, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
   at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
   at System.Security.CodeAccessPermission.Demand()
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior)
   at SD.LLBLGen.Pro.ORMSupportClasses.RetrievalQuery.Execute(CommandBehavior behavior)
The action that failed was:
Demand
The type of the first permission that failed was:
System.Data.SqlClient.SqlClientPermission
The first permission that failed was:
<IPermission
version="1"
AllowBlankPassword="False">
<add KeyRestrictions=""
KeyRestrictionBehavior="AllowOnly"/>
</IPermission>

The demand was for:
<IPermission
version="1"
AllowBlankPassword="False">
<add KeyRestrictions=""
KeyRestrictionBehavior="AllowOnly"/>
</IPermission>

The granted set of the failing assembly was:
<PermissionSet
version="1">
<IPermission
version="1"
Access="Open"/>
<IPermission
version="1"
Allowed="ApplicationIsolationByUser"
UserQuota="512000"/>
<IPermission
version="1"
Flags="Execution"/>
<IPermission
version="1"
Window="SafeTopLevelWindows"
Clipboard="OwnClipboard"/>
<IPermission
version="1"
PublicKeyBlob="0024000004800000940000000602000000240000525341310004000001000100B55C03865E07BCB230B04EF7D9ACF1E7BF41C618DB1327895C25328446039F51CF237A50989E542D3FA9BB5991D303388C5AAC7AE4E071CD7B42B96B16256FF905EC610107DB2A0872E971253919BA528187489FC89FD083118F562319BF3B66CB79035EC50D2291561D4F2B9733AD5E0ECD9BFF9B80B94C40F5888D4E1C5BDD"
Name="ProjectHelpers.Extensions"
AssemblyVersion="2.2009.208.1821"/>
<IPermission
version="1"
Url="file://dc01.bizspeed.datacenter/websites/sitesupervisor files/prjh/ProjectHelpers.Extensions.dll"/>
<IPermission
version="1"
Zone="Internet"/>
<IPermission
version="1"
Level="SafePrinting"/>
</PermissionSet>

The assembly or AppDomain that failed was:
ProjectHelpers.Extensions, Version=2.2009.208.1821, Culture=neutral, PublicKeyToken=4405fd38c7d52787
The method that caused the failure was:
SD.LLBLGen.Pro.ORMSupportClasses.EntityBase2 AfterSave(SD.LLBLGen.Pro.ORMSupportClasses.EntityBase2, SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase)
The Zone of the assembly that failed was:
Internet
The Url of the assembly that failed was:
file://dc01.bizspeed.datacenter/websites/sitesupervisor files/prjh/ProjectHelpers.Extensions.dll
   --- End of inner exception stack trace ---
   at SD.LLBLGen.Pro.ORMSupportClasses.RetrievalQuery.Execute(CommandBehavior behavior)
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.ExecuteSingleRowRetrievalQuery(IRetrievalQuery queryToExecute, IEntityFields2 fieldsToFill, IFieldPersistenceInfo[] fieldsPersistenceInfo)
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntityUsingFilter(IEntityFields2 fieldsToFetch, IFieldPersistenceInfo[] persistenceInfos, IRelationPredicateBucket filter)
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntityUsingFilter(IEntity2 entityToFetch, IPrefetchPath2 prefetchPath, Context contextToUse, IRelationPredicateBucket filter, ExcludeIncludeFieldsList excludedIncludedFields)
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntity(IEntity2 entityToFetch, IPrefetchPath2 prefetchPath, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields)
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntity(IEntity2 entityToFetch, IPrefetchPath2 prefetchPath)
   at ProjectHelpers.Extensions.SurveyResponseSaveHelper.AfterSave(EntityBase2 entity, DataAccessAdapterBase adapter)
   at SS2.RemoteObjects.DataPortal.EntitySaveWithoutRemoting(EntityBase2 entity, AuditSettings auditSettings, AuthTicket at)  [NDC:(null)]
乖乖 2024-08-05 13:32:39

这是轰炸的反射对象中的方法:

    public EntityBase2 AfterSave(EntityBase2 entity, DataAccessAdapterBase adapter)
    {
        SurveyResponseEntity response = entity as SurveyResponseEntity;

        if (response.IsComplete) // we only really want to do this if the survey has been completed.
        {
            SurveyEntity survey = new SurveyEntity(response.SurveyRefId);
            IPrefetchPath2 questionSetPath = new PrefetchPath2((int)SS2DAL.EntityType.SurveyEntity);
            IPredicateExpression filter = new PredicateExpression(QuestionSetFields.Current == 1);
            questionSetPath.Add(SurveyEntity.PrefetchPathQuestionSetCollection, 1, filter)
                .SubPath.Add(QuestionSetEntity.PrefetchPathQuestionPageCollection)
                    .SubPath.Add(QuestionPageEntity.PrefetchPathQuestionCollection);

            if (adapter.FetchEntity(survey, questionSetPath))
            {
                // we need to instantiate the survey template save handler from this survey response (if it exists)
                // then execute

                if (!String.IsNullOrEmpty(survey.PostSaveAssemblyName) && !String.IsNullOrEmpty(survey.PostSaveClassName))
                {
                    try
                    {
                        string assemblyPath = (new FileService()).GetRootAssemblyURL();

                        Assembly asm = Assembly.Load(File.ReadAllBytes(Path.Combine(assemblyPath, survey.PostSaveAssemblyName)));

                        if (asm != null)
                        {
                            Type t = asm.GetType(survey.PostSaveClassName);
                            ISurveyPostSaveHandler cls = (ISurveyPostSaveHandler)Activator.CreateInstance(t);
                            if (cls != null)
                            {
                                cls.AfterSave(response, survey, adapter);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        // at some point, we need to add some logging here.
                        Logger.ErrorFormat("There was an error post-processing survey response {0} from survey {1}: {2}", response.SurveyResponseId, survey.Name, ex.ToString());
                        throw ex;
                    }
                }
            }
            else
            {
                Logger.ErrorFormat("Could not post process response {0} because the parent survey could not be located", response.SurveyResponseId);
                throw new ApplicationException(String.Format("Could not post process response {0} because the parent survey could not be located", response.SurveyResponseId));
            }
        }

        return response;
    }

    #endregion
}

Here is the method in the reflected object that bombs:

    public EntityBase2 AfterSave(EntityBase2 entity, DataAccessAdapterBase adapter)
    {
        SurveyResponseEntity response = entity as SurveyResponseEntity;

        if (response.IsComplete) // we only really want to do this if the survey has been completed.
        {
            SurveyEntity survey = new SurveyEntity(response.SurveyRefId);
            IPrefetchPath2 questionSetPath = new PrefetchPath2((int)SS2DAL.EntityType.SurveyEntity);
            IPredicateExpression filter = new PredicateExpression(QuestionSetFields.Current == 1);
            questionSetPath.Add(SurveyEntity.PrefetchPathQuestionSetCollection, 1, filter)
                .SubPath.Add(QuestionSetEntity.PrefetchPathQuestionPageCollection)
                    .SubPath.Add(QuestionPageEntity.PrefetchPathQuestionCollection);

            if (adapter.FetchEntity(survey, questionSetPath))
            {
                // we need to instantiate the survey template save handler from this survey response (if it exists)
                // then execute

                if (!String.IsNullOrEmpty(survey.PostSaveAssemblyName) && !String.IsNullOrEmpty(survey.PostSaveClassName))
                {
                    try
                    {
                        string assemblyPath = (new FileService()).GetRootAssemblyURL();

                        Assembly asm = Assembly.Load(File.ReadAllBytes(Path.Combine(assemblyPath, survey.PostSaveAssemblyName)));

                        if (asm != null)
                        {
                            Type t = asm.GetType(survey.PostSaveClassName);
                            ISurveyPostSaveHandler cls = (ISurveyPostSaveHandler)Activator.CreateInstance(t);
                            if (cls != null)
                            {
                                cls.AfterSave(response, survey, adapter);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        // at some point, we need to add some logging here.
                        Logger.ErrorFormat("There was an error post-processing survey response {0} from survey {1}: {2}", response.SurveyResponseId, survey.Name, ex.ToString());
                        throw ex;
                    }
                }
            }
            else
            {
                Logger.ErrorFormat("Could not post process response {0} because the parent survey could not be located", response.SurveyResponseId);
                throw new ApplicationException(String.Format("Could not post process response {0} because the parent survey could not be located", response.SurveyResponseId));
            }
        }

        return response;
    }

    #endregion
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文