Pregunta

¿Alguien sabe una buena práctica de asegurar los medios para asp.net?

Necesito alojar una variedad de medios que requieren permiso para ver una imagen / video específico. es decir, un usuario específico puede o no tener permiso para ver un archivo multimedia, y este hecho puede cambiar sobre la marcha.

No me importa si pueden descargar un archivo multimedia al que tienen acceso, simplemente no quiero que estén al tanto de los elementos a los que no deberían tener acceso.

Ya he considerado la ofuscación de URL, esto me parece bastante lamentable.

Tengo usuarios autenticados (y no estoy dispuesto a cambiar esto).

Me gustaría mantener la estructura de la carpeta de archivos multimedia no relacionada con los permisos.

¿Fue útil?

Solución

Cree un HttpHandler a través del cual se debe acceder a todos los medios. Luego, antes de recuperar el archivo y enviarlo al usuario, puede realizar las validaciones que desee. Mantenga todos sus medios fuera de la ruta principal de wwwroot, o denegue el acceso a esa carpeta usando permisos.

Más información sobre este tema aquí:

http://www.15seconds.com/Issue/020417.htm

Otros consejos

Utilizo un archivo xml como este para establecer qué usuarios / grupos tienen acceso a un archivo

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root[
    <!ELEMENT file ANY>
    <!ATTLIST file name ID #REQUIRED>
]>
<root>
    <file name="file.doc" users="155,321" groups="grp5" />
    <file name="file2.doc" users="321" groups="" />
</root>

los archivos se almacenan por encima de la raíz http, por lo que no se puede acceder por URL.

Cuando un usuario intenta acceder a GetFile.aspx? file = file.doc, cargo el XML y obtengo la línea con

XmlNode xnFile= XML.GetElementById(wantedFile);

, entonces llamo a una función

 HasAccess(Context.User, xnFile); 

Que comprueba si el usuario ha iniciado sesión y compara los permisos, y si está bien que este usuario tenga el archivo, leo los archivos del disco y los escribo con

FileInfo thisFile = new FileInfo(secretLocation + wantedFile);
Response.Clear();
Response.Buffer = false;
Response.BufferOutput = false;
Response.ClearContent();
Response.ClearHeaders();
Response.AddHeader("Content-Length", thisFile.Length.ToString());
Response.AddHeader("Content-disposition", "filename=" + thisFile.Name);
Response.ContentType = "application/none";
Response.WriteFile(secretLocation + wantedFile);
Response.Close();
Response.End();
Response.ClearContent();
Response.ClearHeaders();

En realidad ahora tengo más de mil archivos, y pienso en escribir los datos del archivo en la base de datos ya que el XML se corrompió dos veces en 5 años, probablemente debido a bloqueos o uso simultáneo.

De tu comentario en la respuesta de Spikolynn

  

Estoy desconcertado: ¿en qué se diferencia esto de la ofuscación? ¿Un usuario autenticado podría compartir una imagen (para la cual está autorizado) con otro usuario autenticado pero no autorizado?

Supongo que intenta evitar el intercambio no autorizado de medios .

Esto es algo que muchas compañías (Microsoft, Apple, IBM, etc.) han puesto una cantidad considerable de dinero para resolver. La solución era DRM , y ahora la están eliminando, porque falló .

Entonces, mi respuesta es que no puede evitar compartir si el usuario está dispuesto a hacer un esfuerzo para evitarlo.

Puede simplemente mantener a la gente honesta honesta aplicando algunas técnicas como Spikolynn o Lusid explican en sus respuestas.

Sugeriría una tabla que contenga los archivos a los que tiene acceso cada usuario:

UserID int
FileID varchar

luego una tabla para sus archivos:

FileID    UniqueIdentifier
FileType  char(4)  <- so you know which extension to use.
etc...

En el disco duro, asigne al archivo el ID de archivo (UniqueIdentifier) ??y el FileType (la extensión, por ejemplo, .jpg). El ID de archivo en la tabla de permisos contendrá el UniqueIdentifier generado en la otra tabla.

Puede pasar esto a través de la URL sabiendo con relativa seguridad que el usuario no podrá adivinar el nombre de ningún otro archivo.

Actualización: esto es, por cierto, mucho más simple que escribir un HttpHandler o tratar con permisos de archivos. Sin embargo, si bien las posibilidades de que alguien adivine otro nombre de archivo son infinitesimales, no es una seguridad hermética, ya que un usuario puede otorgarle a otro acceso al archivo.

brownpaperpackage.aspx? id = {guid}

En el evento Load de media.aspx, verifica que el usuario esté autenticado, luego verifica que el usuario tiene derecho a ver los medios, y si lo hacen, cargue los medios como una secuencia y envíelos a la Respuesta de la página como Spikolynn demostró.

¿Por qué hacerlo de esta manera? Es simple de codificar y obtiene todos los beneficios de los servicios de autenticación de ASP.NET e IIS, desde los cuales puede encontrar al usuario que solicita los medios. Es trivial asignar ese usuario a una lista de acceso para sus objetos multimedia. Y la página tiene el objeto de solicitud allí mismo. También está ocultando el nombre de los medios, por lo que no puede saber qué sucede desde la URL.

¿Cómo evita que las personas accedan a sus medios directamente? Sus archivos multimedia no se pueden almacenar en el directorio virtual de IIS. Si es así, existe la posibilidad de que se puedan descargar directamente. Puede almacenarlos en una base de datos como una matriz de bytes (blob) o almacenarlos en un disco fuera del directorio virtual web. Los usuarios deben pasar por ASP.NET para acceder a los archivos

¿Cómo realiza un seguimiento de qué usuarios tienen acceso a qué medios? Usted realiza un seguimiento de sus usuarios a través de la membresía asp.net. Eso significa que cada usuario tiene una ID en la tabla aspnet_users. Cree una tabla para sus medios con una identificación y un nombre de archivo (o un blob que contenga los medios reales). Entonces solo necesita crear una tercera tabla que conecte los dos. Esta tabla contendría una identificación de usuario y una identificación de medios, lo que significa que este usuario puede ver estos medios. Con la identificación de usuario (de la membresía asp.net) y la identificación de medios (de la URL) solo necesita

select count(*) from UserMedia where UserId = @UserGuid and MediaId = @MediaIdFromUrl

y si el recuento > 0 el usuario puede ver los medios.

Un ejemplo de cómo usaría la URL:

<asp:image 
  runat="server" 
  ImageUrl="brownpaperpackage.aspx?id=53a2ea4(snip)76ca8b" />
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top