ReportViewer: LocalReport и SecurityException

28 октября 2015 г.

При использовании контрола ReportViewer и локальных отчетов (без сервера отчетов) в ASP.NET приложениях иногда возникает исключение SecurityException. В посте пару сценариев возникновения такой ошибки и методы её устранения.

Ошибка при использовании ReportViewer

Сообщения об ошибке могут отличаться в зависимости от версии ReportViewer'а:

Local report processing requires FullTrust Code Access Security permissions, which is unavailable to the calling code. Grant the application FullTrust permissions or use ServerReport to execute the report remotely. The application attempted to perform an operation not allowed by the security policy. To grant this application the required permission please contact your system administrator or change the application's trust level in the configuration file.

Ниже причины и варианты их устранения.

FullTrust

Иногда это происходит из-за уровня доверия приложения. Использовать ReportViewer.LocalReport можно только если приложению предоставлены разрешения FullTrust. Сделать это можно либо в настройках IIS ("Уровни доверия .NET" на уровне сайта или сервера):

Настройка уровня доверия .NET в IIS

Либо указав это в файле web.config приложения:

  1. <?xml version="1.0"?>
  2. <configuration>
  3.   <system.web>
  4.     <trust level="Full"/>
  5.   </system.web>
  6. </configuration>

Заставить работать LocalReport без FullTrust невозможно. Если нет возможности изменить уровень доверия, то необходимо использовать сервер отчетов.

КриптоПро .NET

Если на сервере где исполняется приложение установлен КриптоПро .NET, та даже FullTrust не поможет и будет выброшено исключение со ссылкой на mscorlib:

Local report processing requires FullTrust Code Access Security permissions, which is unavailable to the calling code. Grant the application FullTrust permissions or use ServerReport to execute the report remotely. System.Security.SecurityException: Сбой при запросе. в System.RuntimeMethodHandle.PerformSecurityCheck(Object obj, RuntimeMethodHandleInternal method, RuntimeType parent, UInt32 invocationFlags) в System.RuntimeMethodHandle.PerformSecurityCheck(Object obj, IRuntimeMethodInfo method, RuntimeType parent, UInt32 invocationFlags) в System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) в System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters) в CryptoPro.Sharpei.NetDetours.DomainNeutralDet.TracedInvoke(MethodInfo mi, Object obj, Object[] parameters) в CryptoPro.Sharpei.NetDetours.DomainNeutralDet.MakeOne(Type targetType, DetourDescription item, AssemblyName assemblyName) в CryptoPro.Sharpei.NetDetours.DomainNeutralDet.MakeOneAssembly(DetourDescription item, AssemblyName assemblyName) в CryptoPro.Sharpei.NetDetours.DomainNeutralDet.DetourAssembly(DetDescriptionList allGroups, Assembly toDet) в CryptoPro.Sharpei.NetDetours.CrossDomainList.InitOnNewDomainPolicyNeutralCreateDomain() в System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate) в System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate) в CryptoPro.Sharpei.NetDetours.CrossDomainList.CreateDomain(AppDomain newDomain) в CryptoPro.Sharpei.NetDetours.CPAppDomain.CreateDomain(String friendlyName, Evidence securityInfo, AppDomainSetup info) в System.AppDomain.CreateDomain(String friendlyName, Evidence securityInfo, AppDomainSetup info, PermissionSet grantSet, StrongName[] fullTrustAssemblies) в Microsoft.Reporting.ControlPolicyManager.CreateAppDomainWithPolicy(String appDomainName, Evidence evidence, AppDomainSetup setupInfo, SandboxCasPolicySettings casSettings) в Microsoft.ReportingServices.AppDomainPool.CreateAppDomain(DateTime timeStamp, SandboxCasPolicySettings casSettings) в Microsoft.ReportingServices.AppDomainPool.GetAppDomain(SandboxCasPolicySettings casSettings) в Microsoft.Reporting.WebForms.LocalReport.ReportRuntimeSetupHandler.EnsureSandboxAppDomainIfNeeded() в Microsoft.Reporting.WebForms.LocalReport.ReportRuntimeSetupHandler.get_ReportRuntimeSetup() в Microsoft.Reporting.WebForms.LocalReport.EnsureExecutionSession() Ошибкой завершилось следующее действие: Demand Ошибкой завершилось первое разрешение следующего типа: System.Security.PermissionSet Было предъявлено следующее требование: Для сбойной сборки был предоставлен следующий набор: Ошибкой завершилась следующая сборка или AppDomain: mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

Чтобы справиться с этой ошибкой необходимо добавить приложение в исключения для КриптоПРО. Исключением будет являться исполняемый файл w3wp.exe. Делаем:

  • В реестре находим раздел HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\CProExclude
  • Создаем в нем подраздел, назвав его, например, w3wp
  • В созданном подразделе добавляем Строковый параметр FileName и указываем значение w3wp.exe

Примерно вот так должно получится:

Исключения для КриптоПРО

Теперь исключения не будет. После этого в приложениях, исполняемых на IIS (веб-приложения, веб-службы, SharePoint) не получится использовать КриптоПРО.

legacyCasModel

В случае с КриптоПРО иногда помогает следующий трюк, позволяющий не добавлять w3wp.exe в исключения: в файле web.config веб-приложения добавить атрибут legacyCasModel, равный true:

  1. <?xml version="1.0"?>
  2. <configuration>
  3.   <system.web>
  4.     <trust legacyCasModel="true"/>
  5.   </system.web>
  6. </configuration>

Поделиться

Комментарии