ฉันกำลังพยายามหาวิธีจำกัดการเข้าถึงโฟลเดอร์มีเดียในการกำหนดค่า apache ของฉัน โฟลเดอร์รับการอัปโหลดจากไซต์ Django และการอัปโหลดรูปภาพ/pdf จะแสดงในไซต์แก่ผู้ใช้ที่ผ่านการรับรองความถูกต้อง ปัญหาคือ schmo ที่ไม่ผ่านการรับรองความถูกต้องสามารถนำทางไปได้ mysite.com/media/images/pic1.jpg
. สิ่งนี้ไม่น่าจะเป็นไปได้ ฉันได้ลองทำบางสิ่งเพื่อจำกัดพฤติกรรมนี้ แต่ฉันคิดว่าฉันต้องการตัวชี้หนึ่งหรือสองตัว
ลองครั้งแรก: XSendfile
Xsendfile ดูเหมือนจะใช้งานได้ แต่ (ตามชื่อที่แนะนำ) ส่งไฟล์เพื่อดาวน์โหลด จากนั้นหน้าของฉันที่ควรแสดงรูปภาพไม่โหลด ดูเหมือนว่านี่ไม่ใช่สิ่งที่ฉันต้องการสำหรับกรณีการใช้งานของฉัน
ลองครั้งที่สอง: เขียนกฎใหม่
ฉันเพิ่มกฎการเขียนซ้ำในการกำหนดค่า apache:
RewriteCond "%{HTTP_REFERER}" "!^$"
RewriteCond "%{HTTP_REFERER}" "!mysite.com/priv/" [NC]
RewriteRule "\.(gif|jpg|png|pdf)$" "-" [F,NC]
ส่วนทั้งหมดของไซต์ที่ต้องมีการรับรองความถูกต้องอยู่เบื้องหลัง /priv/
เส้นทางดังนั้นความคิดของฉันคือว่าถ้าใช้งานได้แล้วให้ไปที่ /media/images/pic1.jpg
จะถูกเขียนใหม่ แต่สิ่งนี้ไม่ได้ผลเช่นกัน mysite.com/media/images/pic1.jpg
ยังคงแสดงภาพ
ความพยายามครั้งที่สาม: สภาพแวดล้อม
ฉันลองสิ่งที่คล้ายกันกับสภาพแวดล้อมภายใน virtualhost:
<VirtualHost *:80>
...
SetEnvIf Referer "mysite\.com\/priv" localreferer
SetEnvIf Referer ^$ localreferer
<FilesMatch "\.(jpg|png|gif|pdf)$">
Require env localreferer
</FilesMatch>
...
</VirtualHost>
แต่ก็ไม่ได้ผลเช่นกัน ฉันยังสามารถนำทางไปยังรูปภาพได้โดยตรง
ความพยายามครั้งที่สี่ : ต้องการผู้ใช้ที่ถูกต้อง
ฉันเพิ่ม ต้องการผู้ใช้ที่ถูกต้อง
ไปยัง v-host แต่ฉันไม่สามารถหาวิธีตรวจสอบกับรุ่นผู้ใช้ Django ได้ หลังจากการเปลี่ยนแปลงนี้ ฉันจะได้รับแจ้งให้ลงชื่อเข้าใช้ทุกครั้งที่ฉันโหลดหน้าเว็บที่แสดงรูปภาพ (แต่ไม่มี htaccess ฯลฯ ไม่มีอะไรให้ตรวจสอบสิทธิ์และไม่มีรูปภาพแสดงบนเว็บไซต์
ฉันพยายามใช้สิ่งที่อธิบายไว้ที่นี่ (https://docs.djangoproject.com/en/3.2/howto/deployment/wsgi/apache-auth/) แต่โครงการ django ของฉันไม่ชอบ WSGIHandler
(ตรงข้ามกับค่าเริ่มต้น get_wsgi_application()
). ฉันได้รับ เพิ่ม AppRegistryNotReady("ยังไม่ได้โหลดแอป")
ข้อผิดพลาด. ดูเหมือนว่านี่อาจเป็นวิธีที่สมเหตุสมผลที่สุด แต่ฉันไม่รู้ว่าจะทำอย่างไร WSGIHandler
การทำงานหรือแนวทางการทำงานกับ get_wsgi_application()
.
ฉันทราบดีว่าฉันสามารถตั้งชื่อไฟล์ที่ดูเหมือน uuid ที่ยากต่อการคาดเดาได้ แต่ดูเหมือนว่าจะเป็นวิธีแก้ปัญหาแบบครึ่งๆ กลางๆ ดังนั้น อะไรคือกลยุทธ์ที่ดีที่สุดของฉันในการจำกัดการเข้าถึงโฟลเดอร์มีเดีย เพื่อให้รูปภาพเหล่านี้เชื่อมโยงเฉพาะในส่วนของไซต์ที่ผู้ใช้ได้รับการตรวจสอบสิทธิ์
อูบุนตู 20.04, อาปาเช่ 2.4
| แก้ไขตามคำแนะนำ |
auth.py
def check_password (สภาพแวดล้อม, ชื่อผู้ใช้, รหัสผ่าน):
พิมพ์("---->>>---->>>---->>>---->>>---->>> check_password() ถูกเรียก <<<--- -<<<----<<<----<<<----<<<----")
กลับทรู
#จาก django.contrib.auth.handlers.modwsgi นำเข้า check_password
บันทึก Apache แสดงว่ามีการโหลดสคริปต์นี้ แต่ดูเหมือนว่าฟังก์ชันจะไม่ถูกเรียกใช้งานเนื่องจากคำสั่งพิมพ์ไม่ปรากฏขึ้นในบันทึก ฉันใส่คำสั่ง stray print ในไฟล์นี้และในไฟล์ wsgi.py เพื่อให้แน่ใจว่ากลยุทธ์นี้ส่งไปยังบันทึก เฉพาะคำสั่งที่อยู่ในไฟล์ wsgi.py เท่านั้นที่สร้างไปยังบันทึก
vhost:
<VirtualHost *:80>
ServerName mysite.com
ServerAlias mysite.com
DocumentRoot /path/to/docroot/
Alias /static/ /path/to/docroot/static/
# Not sure if I need this
Alias /media/ /path/to/docroot/media/
<Directory /path/to/docroot/static/>
Require all granted
</Directory>
<Directory /path/to/docroot/media/>
Require all granted
</Directory>
# this is my restricted access directory
<Directory /path/to/docroot/media/priv/>
AuthType Basic
AuthName "Top Secret"
AuthBasicProvider wsgi
WSGIAuthUserScript /path/to/docroot/mysite/auth.py
Require valid-user
</Directory>
<Directory /path/to/docroot/mysite/>
<Files "wsgi.py">
Require all granted
</Files>
</Directory>
WSGIDaemonProcess open-ancestry-web python-home=/path/to/ENV/ python-path=/path/to/docroot/ processes=10 threads=10
WSGIProcessGroup mysite-pgroup
WSGIScriptAlias / /path/to/docroot/mysite/wsgi.py
LogLevel trace8
ErrorLog "|/bin/rotatelogs -l /path/to/logs/%Y%m%d-%H%M%S_443errors.log 30"
CustomLog "|/bin/rotatelogs -l /path/to/logs/%Y%m%d-%H%M%S_443access.log 30" combined
</VirtualHost>
|แก้ไขอีกครั้ง |
ฉันยอมรับคำตอบเพราะทุกอย่างใช้งานได้แล้ว มีชิ้นส่วนที่เคลื่อนไหวจำนวนมากซึ่งทำให้เกิดปัญหาเบื้องต้นกับคำตอบ
(1) ฟังก์ชัน test_password ไม่แสดงในบันทึก apache ... มันปรากฏขึ้นที่ /var/log/apache2/error.log
แทนบันทึกแบบกำหนดเองที่ตั้งค่าไว้ ไม่แน่ใจว่าทำไม แต่ก็โอเค...
(2) venv ของฉันเปิดใช้งานไม่ถูกต้อง และฉันไม่ได้สังเกตเห็นสิ่งนี้จริง ๆ เพราะ django ถูกติดตั้งบนระบบ Python เช่นกัน ฉันคัดลอก activate_this.py
สคริปต์จาก virtualenv และเพิ่มลงใน venv ของฉันและเพิ่ม sth แบบนี้ลงในไฟล์ wsgi ของฉัน
activate_this = '/path/to/ENV/bin/activate_this.py'
ด้วยการเปิด (activate_this) เป็น f:
ผู้บริหาร (f.read (), {'__file__': activate_this})
เมื่อแก้ไขสิ่งเหล่านี้แล้ว ฟังก์ชัน check_password จะทำงานเมื่อเรียกจากไฟล์ wsgi.py "ใช้งานได้" ที่นี่หมายความว่าจำกัดการเข้าถึงโฟลเดอร์ที่ผู้ใช้ที่ไม่ได้รับอนุญาตไม่ควรเข้าถึง ผู้ใช้ยังคงต้องระบุข้อมูลรับรองสองครั้ง – หนึ่งครั้งในมุมมอง django ปกติ และอีกครั้งในพรอมต์ของเบราว์เซอร์ มันน่ารำคาญ แต่จริงๆ แล้วคำถามของฉันเกี่ยวกับการจำกัดการเข้าถึง ดังนั้นฉันจะปล่อยไว้วันอื่น
คำแนะนำของคำตอบในการเรียก check_password จาก auth.py ไม่ร่วมมือกับโครงการของฉัน ฉันได้รับข้อผิดพลาดที่แนะนำให้เรียกก่อน wsgi.py â ดูเหมือนว่าไม่ได้โหลด venv หรือไม่ได้โหลดการตั้งค่าในขณะที่เรียกใช้ check_password