2012-06-17 8 views
12

He buscado en Google y StackOverflow la respuesta a esta pregunta, pero el hecho de que no sé mucho sobre .htaccess no me ayuda a decidir cuáles son las respuestas correctas para mi situación, así que estoy preguntando aquí..htaccess RewriteCond donde URI no contiene el dominio

Mi situación es que tengo varios sitios que usan el mismo directorio físico que su raíz en el servidor.

Todo funciona bien pero quería asegurarme de que cada sitio no pueda acceder a las imágenes de los demás, etc. desde el navegador a menos que estén en el dominio correcto.

Actualmente tengo una estructura de archivos como esto:

/resources/{resource}/{full_domain_name} 

Así, por ejemplo www.domain.co.uk tendría una estructura como esta:

http://www.domain.co.uk/resources/images/www.domain.co.uk/some_image.jpg 

Pero si www.domain_2.co.uk existe usando el mismo directorio físico para el sitio raíz, entonces pueden ver los recursos de otros dominios desde su propio dominio, como este:

http://www.domain_2.co.uk/resources/images/www.domain.co.uk/some_image.jpg 

Esto no es realmente un problema importante ya que no hay absolutamente ninguna información sensible almacenada en estos directorios, pero es más una molestia y preferiría que los usuarios no pudieran hacerlo (no es que alguien lo haya hecho hasta ahora).

He intentado poner un archivo .htaccess en el directorio/recursos, pero tengo que cargar con las expresiones regulares, etc.

Básicamente quiero para asegurarse de que el URI contiene el nombre de dominio actual de lo contrario redirigir a un 403 página de error

Esto es lo que ocurrió:

RewriteCond %{REQUEST_URI} !^(/resources/[^/]*/%{HTTP_HOST})(.*)$ 
RewriteRule ^(.*)$ /error/403.php 

La razón por la que puse en el bit [^/] es porque hay varias carpetas, por ejemplo:

/resources/images/{full_domain_name} 
/resources/scripts/{full_domain_name} 
/resources/stylesheets/{full_domain_name} 

Podría alguien ayudarme con estos condiciones?

Cualquier ayuda sería apreciada.

+0

¿Cuál es el resultado de su regla actual? Parece que funcionaría, excepto que no necesita ningún '()' alrededor de '/ resources/[^ /] * /% {HTTP_HOST}. *' –

+0

@Michael Actualmente, si estoy en www.domain.co .uk y vaya a www.domain.co.uk/resources/stylesheets/www.domain.co.uk/style.css, por ejemplo, siempre me redirecciona al archivo /error/403.php. Cuando elimino la regla .htaccess, encuentra el archivo como debería hacerlo normalmente. –

+0

En realidad, no necesita todo el '% {REQUEST_URI}' representado en la expresión regular. Simplemente puede hacer coincidir el http_host 'RewriteCond% {REQUEST_URI}! ^. +% {HTTP_HOST}' –

Respuesta

10

Esta es una excelente pregunta y si pudiera, habría votado 10 veces. Estoy publicando mi respuesta a pesar de que tiene una respuesta aceptada aquí ya que tuve que buscar en todos mis recursos de Apache para encontrar la respuesta. Esta es la regla que se necesita para este problema:

Options +FollowSymLinks -MultiViews 
# Turn mod_rewrite on 
RewriteEngine On 
RewriteBase/

RewriteCond %{HTTP_HOST}:%{REQUEST_URI} !^([^:]+):/resources/[^/]+/\1/.+ [NC] 
RewriteRule ^resources/[^/]+/[^/]+/.+ - [F,NC,NE] 

PD: Ya que no podemos utilizar % variables sobre RHS como copia de referencia, estoy usando expresiones regulares especial contrapresión variable referencia en el \1RewriteCond aquí.

+1

Normalmente no hago esto, pero en este caso creo que voy a cambiar mi respuesta aceptada, ya que esto proporciona una solución perfecta para el problema. Gracias por publicar tu respuesta anubhava, ¡es muy apreciada! –

+0

Eres bienvenido y gracias por publicar un problema tan interesante que me hizo aprender nuevos trucos mod_rewrite también :). – anubhava

3

Esta condición es insuficiente:

RewriteCond %{REQUEUST_URI} !^(/resources/[^/]*/%{HTTP_HOST})(.*)$ 

Porque si solicito nada que no se inicia con /resources/, voy a la página 403.php error. Lo que realmente quiere es algo como esto:

RewriteCond %{REQUEST_URI} ^/resources/[^/]+/([^/]+)/ 
RewriteCond %{HTTP_HOST} !%1 

O

RewriteCond %{REQUEST_URI} ^/resources/[^/]+/([^/]+)/ 
RewriteCond %{REQUEST_URI} !^/resources/[^/]+/%{HTTP_HOST}/ 

Cuando la primera condición es la comprobación de que la solicitud es para un recurso, entonces la segunda comprobación del anfitrión. SIN EMBARGO, ninguno de estos funcionará porque la directiva RewriteCond de mod_rewrite no permite % variables o referencias en el lado derecho de la condición, solo a la izquierda.Del mismo modo, no se puede hacer esto ya sea:

RewriteCond %{REQUEST_URI} ^/resources/[^/]+/([^/]+)/ 
RewriteRule !^/resources/[^/]+/%{HTTP_HOST}/ /error/403.php 

Dado que la expresión de la RewriteRule no puede tener variables en ella, ya que es una expresión regular, y literalmente espera una %{HTTP_HOST} en lugar de reemplazarla con el equipo dado en la solicitud. Entonces, para concluir, no, no puedes hacer esto con las condiciones de mod_rewrite de esta manera.

Algo que puedes probar si tienes acceso a la configuración del servidor o vhost config es crear un RewriteMap y pasar el %{REQUEST_URI} y el %{HTTP_HOST}. Así que si su mapa se llama check_host entonces su regla puede ser algo como esto:

RewriteRule ^resources/[^/]+/([^/]+)/ ${check_host:%{HTTP_HOST}_%{REQUEST_URI}} 

Y la secuencia de comandos sólo tendrá que analizar la entrada, dividido desde el primer _, analizar el URI de la solicitud y asegurarse de que el anfitrión es lo mismo que HTTP_HOST. Si es igual, muestre el mismo URI de solicitud, de lo contrario genere el URI de error. Si no tiene acceso a la configuración de servidor o vhost, creo que no tiene suerte. RewriteMap no se puede definir en el archivo htaccess.

+0

Gracias por esta respuesta Jon Lin. No sabía que no podía poner las variables% o referencias atrás en el lado derecho de RewriteCond. He optado por probar RewriteMap, pero si por alguna razón no puedo hacer eso, estoy seguro de que encontraré otra forma fuera de mod_rewrite :) –

Cuestiones relacionadas