Como proteger um diretório no Apache usando uma sessão PHP

8

Eu tenho um site que usa sessão PHP para autenticação. Há um diretório que eu gostaria de restringir o acesso que não usa PHP, é apenas cheio de conteúdo estático.

Só não sei como restringir o acesso sem que todas as solicitações passem por um script PHP. Existe alguma maneira de o Apache verificar as credenciais da sessão e restringir o acesso como a autenticação básica?

Cogsy
fonte

Respostas:

5

A menos que você tenha alterado as configurações, os dados da sessão do PHP são armazenados em uma variação em seu próprio formato serialize () em um diretório temporário, e não é fácil obter isso sem usar o próprio PHP.

infelizmente, você parece querer a velocidade dos arquivos estáticos servidos enquanto autoriza dinamicamente cada solicitação, que não são realmente metas compatíveis. Você pode comprometer-se por ter um script PHP super leve que, em seguida, usa mod_rewrite para reescrever solicitações de arquivos nele, o que passa por coisas boas. Exemplo super simples:

.htaccess:

 RewriteEngine On
 RewriteMap auth prg:auth.php
 RewriteRule (.*) ${auth:$1}

auth.php:

#!/usr/bin/php
 <?PHP
 set_time_limit(0); # This program needs to run forever. 
 $stdin = fopen("php://stdin","r"); # Keeps reading from standard in
 while (true) {
        $line = trim(fgets($stdin));
        if (isset($_SESSION['USER_LOGGED_IN'])) {
                echo $line\n";
        } else {
                echo "authfailed.html\n";
        }
 }

notavelmente, esse script PHP está em execução para sempre, então você precisará reiniciar o apache se o alterar, eu acho.

Tudo isso não foi testado, mas é mais ou menos a direção que acho que você deve seguir.

Referências:

Aquarion
fonte
Eu gosto dessa abordagem, mas estou me perguntando se um script RewriteMap tem acesso a algo diferente de stdin? Tem o contexto de cookies etc?
Cogsy
Na verdade, sim, você tem razão. Você pode enviar o valor dos cookies usando a sintaxe das variáveis ​​de ambiente de mod_rewrite (então eu acho que a sintaxe se tornaria algo como $ {auth: $ 1 $ COOKIES} e você teria que dividir a linha de stdin por argumentos, usando este método pegar o conteúdo da sessão.
Aquarion 25/03
E se você definir um cookie efetuando login com um ID de autenticação constante (muito comprimento de bit) e verificá-lo por acesso ao diretório? Não a melhor solução, mas pode trabalhar em páginas de administração ... (por páginas de compartilhamento de arquivos que não funciona porque os usuários podem compartilhar o cookie ...)
inf3rno
1

Se você tinha um cookie em particular, pode esperar a sua ausência com mod_rewrite e dar 403 403 Proibido.

RewriteCond %{HTTP_COOKIE} !LoggedIn=true
RewriteRule .* - [F,L]

Porém, se alguém soubesse que precisava de um conjunto de cookies com "LoggedIn = true", poderia facilmente contornar sua "proteção".

Uma sessão PHP é específica para PHP. O Apache não tem como usar nenhuma informação em uma sessão PHP. Você precisaria ter algum módulo de autenticação especificamente para fazer a verificação da sessão.

O que eu vi a maioria das pessoas fazer é ter um script PHP manipular a veiculação do conteúdo estático, pois ele recebe a solicitação, verifica a sessão, lê o arquivo e envia o conteúdo com as informações MIME apropriadas.

Rugmonster
fonte
Ou você pode modificar o arquivo .htaccess a cada login, logout e gc ...
inf3rno
1

A solução convencional para esse problema é redirecionar todas as chamadas nessa pasta para um arquivo php, que verifica as permissões do usuário e, depois disso, lê o arquivo e envia-o para o fluxo de saída ou redireciona o usuário para a "sem permissão" local. Por exemplo...

Outra maneira complicada de proteger seus arquivos é gerar um token a partir do session_id e um salt estático (e opcionalmente a partir do caminho estático do arquivo), e verificá-lo acessando o arquivo. Então você precisa regenerar esse token no seu arquivo htaccess. Não sei se é possível apenas com .htaccess, ou você precisa usar php para isso. Encontrei uma solução semelhante aqui. Estou 99% convencido de que o MD5 não é um recurso incorporado de reescrita de mod.

inf3rno
fonte
11
Adoro a idéia do link Blogspot para usar RewriteMapem um prg://…recurso de script de shell que faz toda a criptografia e verificação MD5 reais. Preciso testar isso e garantir que funcione na minha configuração, mas parece que deve funcionar com o Apache + baunilha, o módulo mod_rewrite.
Terceira
1

Meu plano para resolver esse problema agora é

  1. Redirecionar a solicitação para PHP

    RewriteEngine on
    RewriteRule ([0-9a-z-_]+)$ authenticateUser.php?&file=$1 [L]
    
  2. Autentique o usuário no PHP (todos os outros métodos de autenticação talvez sejam muito fracos ou exijam a gravação em arquivos o tempo todo)

    if ( User::hasPermission() && isSane( $filePath ) ) {
        // 
        header( 'X-Sendfile: ' . $filePath );
    }
    
  3. Use o Apache mod_xsendfile( docs , github )

Rainer Rillke
fonte