2 votes

Comment puis-je forcer mod_rewrite à envoyer le composant d'information sur l'utilisateur d'un URI ?

Un collègue m'a recommandé de transférer ce message de StackOverflow à ServerFault :

Ça m'a rendu fou. J'ai une application web qui est servie par le serveur web Apache. Le serveur de base de données qui soutient l'application est Apache CouchDB, qui expose une API HTTP pour récupérer les documents et les pièces jointes.

J'ai sécurisé la base de données CouchDB en fournissant un objet de sécurité qui ne permet qu'à certains utilisateurs d'accéder aux données de la base et qui renvoie 401 pour les requêtes anonymes aux points de terminaison HTTP.

Je veux pouvoir faire correspondre des URL publiques à des pièces jointes de documents stockées dans cette base de données. J'ai donc essayé de créer une règle de réécriture dans mon fichier .htaccess qui renvoie les requêtes de certaines URL directement vers CouchDB, tout en codant en dur les informations d'identification de l'utilisateur, comme suit :

## DOWNLOAD STREAM:
RewriteCond %{HTTP_HOST} ^example.com$
RewriteRule download/(.*) http://user:pass@127.0.0.1:5984/database/$1 [P]

Dans un monde idéal, l'exemple ci-dessus prendrait l'URL suivante :

http://example.com/download/UUID/attachment.ext

Et le proxy à :

http://user:pass@127.0.0.1:5984/database/UUID/attachment.ext

Cette méthode transmet effectivement la demande à CouchDB, mais omet le composant userinfo du schéma URI. La demande est donc traitée comme anonyme et je reçois une erreur 401. La pièce jointe n'est diffusée que si je supprime la sécurité de la base de données.

J'ai passé quelques heures à me documenter sur la configuration d'Apache et à faire des expériences, mais en vain. Les recherches sur le web sont infructueuses en raison de toutes les requêtes connexes avec des mots-clés similaires.

Comment puis-je m'assurer que mod_rewrite inclut le nom d'utilisateur et le mot de passe fournis dans la règle de réécriture lorsqu'il se connecte à CouchDB ?

2voto

StickByAtlas Points 141

J'ai trouvé ! Plutôt que d'inclure le nom d'utilisateur et le mot de passe dans le schéma URI, l'en-tête d'autorisation doit être défini indépendamment. La solution suivante fonctionne entièrement dans un .htaccess ce qui est important car OS X détruit périodiquement les paramètres des sites VirtualHost :

SetEnvIf Request_URI ^/download/* ADD_COUCH_BASIC_AUTH
RequestHeader set Authorization "Basic XXXXXXXXXXXX" env=ADD_COUCH_BASIC_AUTH

## DOWNLOAD STREAM
RewriteCond %{HTTP_HOST} ^example.com$
RewriteRule download/(.*) http://127.0.0.1:5984/database/$1 [P]

La façon dont cela fonctionne : nous utilisons SetEnvIf pour vérifier si le chemin de la requête correspond au chemin que nous voulons utiliser comme proxy, et si c'est le cas, définir une variable d'environnement arbitraire ADD_COUCH_BASIC_AUTH

Sur la ligne suivante, nous ajoutons un en-tête Basic Auth à la requête sortante, seulement si la variable d'environnement que nous avons définie existe. Ainsi, l'en-tête d'authentification de base ne sera ajouté que lors de la demande d'une ressource par l'intermédiaire de /download/ et envoie ainsi les informations d'authentification à CouchDB.

Note : vous devrez coder en base64 votre nom d'utilisateur et votre mot de passe, et remplacer le mot de passe par le mot de passe. XXXXXXXXXXX avec la valeur codée. Une façon simple de le faire, sur un Mac :

echo -n 'user:pass' | openssl base64

J'espère que cela aidera quelqu'un d'autre que moi !

0voto

Rüdiger Stevens Points 5381

Comme alternative à la réponse de @StickByAtlas, vous pouvez définir la variable d'environnement par le biais de la commande RewriteRule lui-même. Voici un exemple de la façon dont je l'utilise pour charger des fichiers depuis un stockage externe s'ils n'existent pas localement ( .htaccess est à l'intérieur de la /download dossier) :

RewriteEngine on
# rewrite to external source if local file does not exist
RequestHeader set Authorization "Basic XXXXXXXXXXXX" env=EXTERNAL_SOURCE
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ https://external.example.com/download/$1 [P,E=EXTERNAL_SOURCE]

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X