Score:1

Apache: จำกัดการแสดงภาพให้กับผู้ใช้ที่ผ่านการรับรองความถูกต้อง

ธง cn
Bob

ฉันกำลังพยายามหาวิธีจำกัดการเข้าถึงโฟลเดอร์มีเดียในการกำหนดค่า 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

Score:1
ธง ve

นี่คือสิ่งที่ get_wsgi_application กำลังทำอยู่:

def get_wsgi_application():
    django.setup(set_prefix=False) # สิ่งนี้จะนำไปสู่ ​​"apps_ready=true"
    ส่งคืน WSGIHandler()

กำลังตั้งค่าสภาพแวดล้อม django ก่อนส่งคืนตัวจัดการ

สิ่งต่อไปนี้ควรทำเคล็ดลับใน wsgi.py ของคุณ:

แอปพลิเคชัน = get_wsgi_application()
จาก django.contrib.auth.handlers.modwsgi นำเข้า check_password
#ลำดับก็สำคัญ!!

ในความเป็นจริงปัญหาคือบรรทัดแรกใน modwsgi.py:

UserModel = auth.get_user_model()

เพราะ get_user_model() จะตรวจสอบ apps_ready และทั้งหมดที่ทำในตอนที่ python ดำเนินการนำเข้าไฟล์!

วิธีที่ดีกว่าคือสร้าง auth.py แยกต่างหากและตรวจสอบก่อนว่า Apache เรียกจริงๆ หรือไม่ด้วยการพิมพ์อย่างง่ายที่จะไปที่ error.log ของ Apache:

def check_password (สภาพแวดล้อม, ชื่อผู้ใช้, รหัสผ่าน):
    พิมพ์ ("********** check_password() ถูกเรียกแล้ว ********")
    กลับทรู

คุณสามารถแทนที่ด้วยคำสั่ง import และใช้ djangos check_password()

จาก django.contrib.auth.handlers.modwsgi นำเข้า check_password

จากนั้นสิ่งต่อไปนี้ใน httpd-vhosts.conf:

<VirtualHost *:80>

   ....

   <Directory path_to_server_root/secret>
        AuthType Basic
        AuthName "Top Secret"
        AuthBasicProvider wsgi
        WSGIAuthUserScript path_to_wsgi/wsgi.py
        Require valid-user
   </Directory>

</VirtualHost>
cn flag
Bob
ขอบคุณ! มีสิ่งแปลกประหลาดสองอย่างเกิดขึ้นหลังจากใช้การเปลี่ยนแปลงที่คุณแนะนำ 1. ฉันได้รับการแจ้งเตือนจากเบราว์เซอร์ให้ตรวจสอบสิทธิ์ (เฉพาะในครั้งแรก แต่ฉันคิดว่าควรจัดการโดยมุมมองการเข้าสู่ระบบของฉัน) 2. ไม่มีรูปภาพแสดงจากโฟลเดอร์ลับ â ไซต์โหลด แต่คำขอ img ส่งคืนข้อผิดพลาด 500 ("เฟสการตรวจสอบสิทธิ์ 'ตรวจสอบผู้ใช้' ให้สถานะ 500" ในไฟล์บันทึก) ฉันไม่รู้ว่ามันหมายถึงอะไร & google ไม่มีประโยชน์
Razenstein avatar
ve flag
ฉันเปลี่ยนคำตอบด้านบน: สร้างไฟล์แยกต่างหาก "auth.py" (ซึ่งเป็นสิ่งที่ควรทำและไม่ผสมกับ wsgi.py มาตรฐาน - ฉันแค่ต้องการให้มันง่ายในคำตอบแรก) และใส่ ทดสอบฟังก์ชันใน - จากนั้นคุณสามารถดูได้ว่า Apache กำลังเรียกใช้ฟังก์ชัน "check_password" ของคุณหรือไม่
Razenstein avatar
ve flag
หากคุณต้องการแสดงเช่น รูปภาพภายในหน้าเพียงใช้ XSendfile ตามที่คุณพูดถึงเป็นโซลูชัน (1) - ใช้งานได้ ในฟังก์ชัน/มุมมองที่ให้บริการ XSendfile url คุณสามารถจำกัดการเข้าถึงได้เช่นเดียวกับที่คุณจำกัดการเข้าถึงไปยังมุมมองอื่นๆ และด้วยการเปิดใช้งาน XSendFile ใน Apache การเข้าถึงไดเรกทอรีที่เกี่ยวข้องจะถูกส่งไปยังแอป django ของคุณ
cn flag
Bob
และเมื่อ apache ไม่เรียกใช้ฟังก์ชันใน auth.py จะทำอย่างไร ฉันจำเป็นต้องนำเข้าหรือไม่? หรืออ้างอิงในการกำหนดค่า apache อย่างใด บันทึกข้อผิดพลาดเหมือนกับการตอบกลับครั้งแรก
Razenstein avatar
ve flag
ตรวจสอบว่าคำสั่ง "WSGIAuthUserScript path_to_auth_script/auth.py" ถูกต้องหรือไม่ โพสต์ httpd-vhost.conf และ auth.py ของคุณ
cn flag
Bob
โพสต์ในการแก้ไข
cn flag
Bob
ณ ตอนนี้ โฟลเดอร์ส่วนตัวถูกซ่อนจากผู้ใช้ที่ไม่ได้ตรวจสอบสิทธิ์ แต่ผู้ใช้ต้องตรวจสอบสิทธิ์ผ่านพรอมต์จากเบราว์เซอร์หลังจากลงชื่อเข้าใช้เว็บไซต์ผ่านมุมมอง django auth ปกติแล้ว Apache ไม่เรียกสคริปต์ auth.py ของฉัน ดังนั้นฉันคิดว่าการทำให้มันใช้งานได้จะช่วยแก้ปัญหาการเข้าสู่ระบบเพิ่มเติม

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา