Saltar al contenido

Wordpress – ¿Cómo restringir la descarga de archivos adjuntos a un usuario específico?

Investigamos por distintos sitios y así regalarte la solución a tu duda, si tienes alguna duda puedes dejar la pregunta y te respondemos sin falta.

Solución:

Lo que tiene que suceder es que necesita las solicitudes de descarga de proxy para los tipos de archivo que desea a través de WordPress. Supongamos que va a restringir el acceso a los archivos “.doc”.

1. Defina una variable de consulta que indique el archivo solicitado

function add_get_file_query_var( $vars ) 
    $vars[] = 'get_file';
    return $vars;

add_filter( 'query_vars', 'add_get_file_query_var' );

2. Actualice .htaccess para reenviar solicitudes de archivos restringidos a WordPress

Esto capturará las solicitudes a los archivos que desea restringir y las enviará de regreso a WordPress usando la variable de consulta personalizada anterior. Inserte la siguiente regla antes del RewriteCond líneas.

RewriteRule ^wp-content/uploads/(.*.docx)$ /index.php?get_file=$1

3. Capture el nombre del archivo solicitado en la variable de consulta personalizada; y verificar el acceso al archivo:

function intercept_file_request( $wp ) 
add_action( 'wp', 'intercept_file_request' );

nótese bien Esta solución funciona para instalaciones de un solo sitio solamente! Esto se debe a que WordPress MU ya reenvía las solicitudes de archivos cargados en subsitios a través de wp-includes/ms-files.php. También hay una solución para WordPress MU, pero es un poco más complicada.

Recientemente tuve un problema relacionado y escribí este artículo al respecto.

Asumiré que las descargas se cargan a través del manejo de medios de WordPress, o de lo contrario, tiene un ID de archivo adjunto para la descarga.

Esquema de la solución

  • Hacer que el directorio de subidas sea ‘seguro’ (en este sentido solo uso mezquino .htaccess para bloquear cualquier intento de acceder directamente a los archivos en el directorio de cargas (o un subdirectorio del mismo), por ejemplo, a través de mysite.com/wp-content/uploads/conf/2012/09/myconfidentialfile.pdf)
  • Cree un enlace de descarga que incluya el ID del archivo adjunto: esto pasa por WordPress para verificar el permiso del usuario para ver el archivo adjunto permite / deniega el acceso.

Advertencias

  • Esto hace uso de .htaccess para brindar seguridad. Si esto no está disponible / activado (servidores nginx, por ejemplo), entonces no obtendrá mucha seguridad. Puede evitar que el usuario hojeada el directorio uplods. Pero el acceso directo funcionará.
  • Como arriba. Esto no debe usarse en distribución si requiere seguridad absoluta. Está bien si su configuración específica funciona, pero en general, no se puede garantizar. Mi artículo vinculado en parte está tratando de abordar esto.
  • Perderás miniaturas. Si bloquea el acceso directo a una carpeta o subcarpeta, no se podrán ver las miniaturas de los archivos de esa carpeta. Mi artículo vinculado en parte intenta abordar esto.

Bloquear el acceso directo

Para hacer esto en su carpeta de cargas (o una subcarpeta – todo el material confidencial debe residir, a cualquier profundidad, dentro de esta carpeta). Coloque un .htaccess archivo con lo siguiente:

Order Deny,Allow
Deny from all

A continuación, supongo que adjuntará material confidencial al tipo de publicación “cliente”. Cualquier medio cargado en la página de edición del cliente se almacenará en el uploads/conf/ carpeta

La función para configurar el directorio de cargas protegido

function wpse26342_setup_uploads_dir()

    $wp_upload_dir = wp_upload_dir();
    $protected_folder = trailingslashit($wp_upload_dir['basedir']) . 'conf';    

    // Do not allow direct access to files in protected folder
    // Add rules to /uploads/conf/.htacess
    $rules = "Order Deny,Allown";
    $rules .= "Deny from all";

    if( ! @file_get_contents( trailingslashit($protected_folder).'.htaccess' ) ) 
            //Protected directory doesn't exist - create it.
        wp_mkdir_p( $protected_folder);
    
    @file_put_contents( trailingslashit($protected_folder).'.htaccess', $rules );

     //Optional add blank index.php file to each sub-folder of protected folder.

Subiendo material confidencial

   /**
    * Checks if content is being uploaded on the client edit-page
    * Calls a function to ensure the protected file has the .htaccess rules
    * Filters the upload destination to the protected file
    */
    add_action('admin_init', 'wpse26342_maybe_change_uploads_dir', 999);
    function wpse26342_maybe_change_uploads_dir() 

Una vez hecho esto, el contenido subido debe estar dentro uploads/conf e intentar acceder a él directamente usando su navegador no debería funcionar.

Descarga de contenido

Esto es facil. La URL de descarga puede ser algo www.site.com?wpse26342download=5 (donde 5 es el ID de archivo adjunto del contenido cargado). Usamos esto para identificar el archivo adjunto, verificar los permisos del usuario actual y permitirles descargar.

Primero, configure la variable de consulta

/**
 * Adds wpse26342download to the public query variables
 * This is used for the public download url
 */
add_action('query_vars','wpse26342_add_download_qv');
function wpse26342_add_download_qv( $qv )
    $qv[] = 'wpse26342download';
    return $qv;
}

Ahora configure un oyente para (tal vez) activar la descarga …

add_action('request','wpse26342_trigger_download');
function wpse26342_trigger_download( $query_vars )

        //Only continue if the query variable set and user is logged in...
    if( !empty($query_vars['wpse26342download']) && is_user_logged_in() )

        //Get attachment download path
        $attachment = (int) $query_vars['wpse26342download'];
        $file = get_attached_file($attachment);

        if( !$file )
             return;

        //Check if user has permission to download. If not abort.       
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename='.basename($file));
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Pragma: public');
        header('Content-Length: ' . filesize($file));

        ob_clean();
        flush();
        readfile($file);
        exit();
    
    return $query_vars;

Comentarios finales

El código anterior puede contener errores / errores de sintaxis y no está probado, y lo usa bajo su propio riesgo :).

La URL de descarga se puede “embellecer” mediante reescrituras. Como se indica en los comentarios, puede agregar un espacio en blanco index.php dentro de cada hijo de la carpeta protegida para evitar la navegación, pero esto debe evitarse mediante el .htaccess reglas de todos modos.

Un método más seguro sería almacenar los archivos públicos fuera de un directorio público. O en un servicio externo como Amazon S3. Para este último, deberá generar una URL válida para obtener el archivo de Amazon (usando su key). Ambos requieren un cierto nivel de confianza en su Anfitrión / servicio de terceros.

Sería cauteloso con el uso de complementos que sugieran que ofrecen “descargas protegidas”. No he encontrado ninguno que ofrezca una seguridad lo suficientemente buena. Por favor, no haga las advertencias de esta solución también, y agradecería cualquier sugerencia o crítica.

Aquí puedes ver las comentarios y valoraciones de los lectores

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *