security - El intento del método transparente de seguridad X para acceder al método crítico de seguridad Y falló
.net-4.0 cas (4)
En caso de que ayude a otros, publico mi solución para este problema:
1) En AssemblyInfo.cs, se eliminó / comentó la línea [assembly: SecurityTransparent].
2) La Clase y el Método que hace el Trabajo real se marcaron como [SecuritySafeCritical]
, en mi caso estableciendo una conexión de red:
[SecuritySafeCritical]
public class NetworkConnection : IDisposable
{
[SecuritySafeCritical]
public NetworkConnection(string networkName, NetworkCredential credentials)
{
.............
}
}
3) La clase y el método de llamada se comercializaron como [SecurityCritical]:
[SecurityCritical]
public class DBF_DAO : AbstractDAO
{
[SecurityCritical]
public bool DBF_EsAccesoExclusivo(string pTabla, ref ArrayList exepciones)
{
....
using (new NetworkConnection(DBF_PATH, readCredentials))
{
....
}
}
}
Tengo una versión de la aplicación de servidor bastante estable que se ha implementado durante casi un año en docenas de clientes.
Un nuevo cliente recientemente configuró la aplicación y está recibiendo el siguiente error:
System.MethodAccessException: el intento por el método transparente de seguridad [SomeMethod] para acceder al método crítico de seguridad [SomeOtherMethod] falló.
Tanto SomeMethod como SomeOtherMethod son métodos en ensamblados que escribí, que se construyen contra .NET 4 y que se ejecutan dentro de un Servicio de Windows. Si hace una diferencia, SomeOtherMethod hace referencia a un tipo de un ensamblado de terceros (EntLib 4.1) creado contra .NET 2.0. Al observar el código de EntLib 4.1, veo que usan los atributos SecurityTransparent y APTC, pero esto nunca ha causado problemas en otros clientes.
Estos ensamblajes se actualizaron desde .NET 2.0 CLR, pero hace mucho tiempo. Este código exacto se está ejecutando en otros clientes muy bien, y no estoy usando explícitamente el atributo APTC ni estoy usando el atributo SecurityCritical en ninguna parte.
Esto me lleva a la conclusión de que es un problema de configuración o quizás un problema de parche de .NET Framework. ¿Se ha lanzado un parche para .NET que causaría este cambio de ruptura? ¿Hay algún ajuste de configuración en el que se aplique este tipo de verificación que está desactivada de forma predeterminada pero que mi cliente pudo haber habilitado?
Un último punto. Mi servicio utiliza RDRS SSRS para generar archivos PDF. Debido a algunos cambios en .NET 4, debo forzar al servicio a usar la política de seguridad heredada a través de la siguiente configuración:
<runtime>
<NetFx40_LegacySecurityPolicy enabled="true" />
</runtime>
Para obtener más detalles sobre por qué debo hacer esto, consulte esta publicación de stackoverflow: Uso muy alto de memoria en .NET 4.0
El punto importante es que hago esto en todos mis otros clientes también. Sólo este cliente está teniendo problemas.
En mi caso, fue un problema cuando administré paquetes de NuGet en la solución, algunos paquetes anulan el enlace de la versión de ensamblado System.Web.Mvc en el proyecto del sitio web principal. Establecer de nuevo a 4.0.0.0 (tuve 5.0 instalado). No cambié, note el cambio porque Mvc v4.0 estaba instalado y accesible a través de GAC. Retrasar
Me enfrentaba a un problema similar mientras ejecutaba la muestra WCF descargada de http://www.idesign.net/ mientras utilizaba su biblioteca ServiceModelEx. Comenté la siguiente línea en AssemblyInfo.cs en el proyecto ServiceModelEx
//[assembly: AllowPartiallyTrustedCallers]
Y funcionó para mí.
Suspiro, los patrones y prácticas empleados por el equipo de Microsoft Patterns And Practices que es responsable de las bibliotecas de Enterprise son bastante deplorables. Bueno, la excepción es precisa, no puedes llamar a un método que esté decorado como "Definitivamente verificaré la seguridad" del código que está decorado con "Meh, no revisaré la seguridad, así que no te molestes en quemar los ciclos de la CPU para verificarlo" . Que se adapta tanto a las especificaciones de excepción como a las utilizadas en Java. CAS es increíblemente útil, pero diagnosticar las excepciones es un gran dolor de cabeza y, a menudo, implica un código que no posee y que no puede arreglar. Gran razón por la que se desaprobó en .NET 4.
Editorial realizada. Tomando una oportunidad para resolver el problema, debe averiguar por qué se está aplicando el CAS aquí. La explicación más sencilla para esto es que el servicio no se ejecuta con plena confianza. La explicación más sencilla para esto es que el cliente no instaló el servicio en el disco duro local. O generalmente ejecuta el código en el modo de no confiar en él, incluso en ensamblajes locales, un administrador muy paranoico bien podría preferir eso. Eso debe configurarse con Caspol.exe, una herramienta cuyas opciones de línea de comando son tan misteriosas como CAS. Al disparar en la explicación de la ubicación no confiable, su cliente necesita ejecutar Caspol como se muestra en esta publicación del blog . O simplemente despliegue el servicio localmente para que se aplique el valor predeterminado "Confío en ti".
Edición en la razón real descubierta por el OP: tenga cuidado con el flujo de datos alternativo que se agrega a un archivo cuando se descarga desde una ubicación de red o de Internet no confiable. El archivo obtendrá una secuencia llamada "Zone.Identifier" que realiza un seguimiento de dónde proviene con el valor "ZoneId". Es ese valor el que anula la confianza derivada de la ubicación de almacenamiento. Por lo general poniéndolo en la zona de internet. Use el Explorador, haga clic con el botón derecho en el archivo y haga clic en "Desbloquear" para eliminar esa secuencia. Después de estar seguro de que puede confiar en el archivo :)