none
Error de solicitud de permiso de tipo 'System.Security.Permissions.FileIOPermission

    Pregunta

  • Saludos colegas, actualmente estoy probando un código relacionado con un Assemblies desarrollado en C# y el cuál se integra con SQL Server para permitirme manipular una cadena XML y aplicar un formato XSLT, al momento de ejecutar el test de mi aplicación el logra generar el cambio, y mando a guardar el resultado en un archivo de salida, siendo este proceso el que me genera el siguiente error:

    System.Security.SecurityException: Error de solicitud de permiso de tipo 'System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.

    System.Security.SecurityException: 

       en System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)

       en System.Security.CodeAccessPermission.Demand()

       en System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)

       en System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)

       en System.IO.StreamWriter.CreateFile(String path, Boolean append)

    El metodo en donde se produce el error es el siguiente:

     

    using System.Data.SqlTypes;
    using System.Xml;
    using System.IO;
    
    namespace Samples
    {
        public partial class XsltAssembly
        {
            [Microsoft.SqlServer.Server.SqlProcedure]
            public static void p_XsltTransformToFile(SqlXml source_xml,
                SqlXml source_xslt,
                SqlString output_file)
            {
                SqlXml result = new SqlXml();
                if (!source_xml.IsNull &&
                    !source_xslt.IsNull &&
                    !output_file.IsNull)
                {
                    result = Transform(source_xml, source_xslt);
                    StreamWriter sw = new StreamWriter(output_file.Value);
                    sw.Write(result.Value);
                    sw.Dispose();
                }
            }
        };
    }

     


    Mi aplicación esta desarrollada en Visual Studio 2010, SO: Windows 7, SGBD: SQL Server 2008 R2.  Por lo pronto agradezco su valioso apoyo.

     


    viernes, 02 de septiembre de 2011 5:29

Respuestas

  • Hola Geovanny,

    Lo primero es comentarte que leas  CREATE ASSEMBLY la parte de PERMISION SET, como puedes ver, excepto que tu lo especifiques la instrucción asigna SAFE, nivel más restrictivo  y jamas te recomendaría que usases otro. 

    Por lo que veo en la definición eso no permite acceder a Archivos y por tu código veo que el tercer parámetro es una ruta física donde quieres guardar el resultado de aplicar la transformación xslt, para ello tendrias que haber asignado al crear el Assembly en PERMISION SET EXTERNAL_ACCESS, cosa que como te he comentado antes no te lo recomiendo.

    Te propongo la siguiente alternativa y es que en vez de pasar la ruta pases una variable del tipo SqlXml y la declares como output tal y como te muestro en el siguiente ejemplo.

     

    using System.Data.SqlTypes;
    using System.Xml;
    using System.IO;
    
    namespace Samples
    {
        public partial class XsltAssembly
        {
            [Microsoft.SqlServer.Server.SqlProcedure]
            public static void p_XsltTransformToFile(SqlXml source_xml,
                SqlXml source_xslt,
                out SqlXml result)
            {
                result = new SqlXml();
                if (!source_xml.IsNull &&
                    !source_xslt.IsNull
                    )
                {
                    result = Transform(source_xml, source_xslt);
                   
                }
            }
        };
    }
    


    De esa forma tu puedes llamar a tu store procedure y obtener el xml a traves del parametro result y de esa forma que sea  una app .net la responsable de guardar el archivo, donde más guste.

    Saludos,


    phurtado
    viernes, 02 de septiembre de 2011 8:26
  • revisa la explciacion aportada por el articulo

    valida con que nivel de acceso se incluye

    Building my First SQL Server 2005 CLR

    veras en el link que hay temas de seguridad cuando se usa el PERMISSION_SET, esto peude afectar el tema de escribir un archivo

    quizas aclara algo mas el problema


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    viernes, 02 de septiembre de 2011 15:06

Todas las respuestas

  • hola

    -veo que defines output_file.Value, pero ahs probado cambiar la ruta a la cual envias a grabar el archivo ? solo para validar si es un tema de esa ruta en si o es mas general

    -has probado a la ruta definirle la segurdad de acceso "everyone" de control total sobre la carpeta ? solo para ver si esto permite escribir

     

    - veo que usas el atributo [Microsoft.SqlServer.Server.SqlProcedure], de casualidad se trata de un stored procedure con el CLR integrado para suar .net dentro del SP ?

    si es asi deberias mencionarlo desde el principio, porque puede que los niveles de permiso al integrarse con el Sql Server sean diferentes a los suados cuando desarrollas

    valdia con que nivel de acceso se incluye

    Building my First SQL Server 2005 CLR

    veras en el link que hay temas de seguridad cuando se usa el PERMISSION_SET, esto peude afectar el tema de escribir un archivo

     

    saludos

     

     


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    viernes, 02 de septiembre de 2011 6:24
  • Hola Geovanny.

    Por lo que veo, el problema se produce en la escritura del fichero.

    Deberías comprobar:

    • En qué carpeta se está intentando escribir el fichero
    • Permisos en esa carpeta
    • ¿El fichero está vacío?

     

    En principio guardándolo en la carpeta adecuada o dando permisos a la carpeta en la que quieres escribir, debería ser suficiente para que funcionara correctamente.


    "En los momentos de crisis, sólo la imaginación es más importante que el conocimiento"
    viernes, 02 de septiembre de 2011 8:01
  • Hola Geovanny,

    Lo primero es comentarte que leas  CREATE ASSEMBLY la parte de PERMISION SET, como puedes ver, excepto que tu lo especifiques la instrucción asigna SAFE, nivel más restrictivo  y jamas te recomendaría que usases otro. 

    Por lo que veo en la definición eso no permite acceder a Archivos y por tu código veo que el tercer parámetro es una ruta física donde quieres guardar el resultado de aplicar la transformación xslt, para ello tendrias que haber asignado al crear el Assembly en PERMISION SET EXTERNAL_ACCESS, cosa que como te he comentado antes no te lo recomiendo.

    Te propongo la siguiente alternativa y es que en vez de pasar la ruta pases una variable del tipo SqlXml y la declares como output tal y como te muestro en el siguiente ejemplo.

     

    using System.Data.SqlTypes;
    using System.Xml;
    using System.IO;
    
    namespace Samples
    {
        public partial class XsltAssembly
        {
            [Microsoft.SqlServer.Server.SqlProcedure]
            public static void p_XsltTransformToFile(SqlXml source_xml,
                SqlXml source_xslt,
                out SqlXml result)
            {
                result = new SqlXml();
                if (!source_xml.IsNull &&
                    !source_xslt.IsNull
                    )
                {
                    result = Transform(source_xml, source_xslt);
                   
                }
            }
        };
    }
    


    De esa forma tu puedes llamar a tu store procedure y obtener el xml a traves del parametro result y de esa forma que sea  una app .net la responsable de guardar el archivo, donde más guste.

    Saludos,


    phurtado
    viernes, 02 de septiembre de 2011 8:26
  • Gracias Pedro por la explicación sobre el tema de seguridad, quedan descartados los temas de las rutas y permisos en las carpetas, el punto que señala Pedro me parece claro y conciso, actualmente ejecuto las pruebas desde SQL Server (pero tambien genere un script de prueba dentro del proyecto en VS 2010) entenderia que haciendo este cambio que señalas (result = Transform(source_xml, source_xslt) el resultado llegaria a la ventana de resultados de SQL Server?  Por asuntos de disponibilidad del equipo hare las pruebas del caso hoy por la noche, pero en cuanto tengo los resultados las posteare en el correo y cerrare el hilo.

    Muchas gracias colegas x su apoyo.

    viernes, 02 de septiembre de 2011 15:03
  • revisa la explciacion aportada por el articulo

    valida con que nivel de acceso se incluye

    Building my First SQL Server 2005 CLR

    veras en el link que hay temas de seguridad cuando se usa el PERMISSION_SET, esto peude afectar el tema de escribir un archivo

    quizas aclara algo mas el problema


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    viernes, 02 de septiembre de 2011 15:06
  • Gracias Leandro, revisare el articulo y hare las respectivas del caso, por lo pronto gracias.
    viernes, 02 de septiembre de 2011 15:57
  • Ya hice la revisión, el error se producia x un tema de permisos, realmente el Assembly debia tener el atributo PERMISION SET EXTERNAL_ACCESS como mencionaba Pedro, y en el articulo que posteo Leandro se confirmo este punto, pero haciendo una valoración sobre los riesgos modifique el código y al final creo en su lugar una funcion que devuelve el XML transformado, a partir de ese punto tengo la libertad de transferirlo a un aplicativo .Net para que se encargue de crear el archivo, sin comprometer la seguridad de mi servidor, asi que solo me resta agradecer su valioso apoyo.
    viernes, 02 de septiembre de 2011 21:43