Điểm:1

Apache: hạn chế phân phối hình ảnh cho người dùng được xác thực

lá cờ cn
Bob

Tôi đang cố gắng tìm ra cách hạn chế quyền truy cập vào thư mục phương tiện trong cấu hình apache của mình. Thư mục tải lên từ một trang web Django và tải lên hình ảnh/pdf được hiển thị trong trang web cho người dùng được xác thực. Vấn đề là, bất kỳ schmo không được xác thực nào cũng có thể điều hướng đến mysite.com/media/images/pic1.jpg. Điều này không thể xảy ra; Tôi đã thử một số cách để hạn chế hành vi này, nhưng tôi nghĩ rằng tôi cần một hoặc hai gợi ý.

lần thử đầu tiên: XSendfile

Xsendfile dường như hoạt động, nhưng nó (như tên gợi ý) gửi tệp để tải xuống, sau đó trang của tôi được cho là hiển thị hình ảnh không tải. Vì vậy, có vẻ như đây không phải là thứ tôi cần cho ca sử dụng của mình.

lần thử thứ hai: viết lại quy tắc

Tôi đã thêm một số quy tắc viết lại vào cấu hình apache:

RewriteCond "%{HTTP_REFERER}" "!^$"
RewriteCond "%{HTTP_REFERER}" "!mysite.com/priv/" [NC]
RewriteRule "\.(gif|jpg|png|pdf)$" "-" [F,NC]

Tất cả các phần của trang web yêu cầu xác thực đều nằm sau /riêng tư/ đường dẫn, vì vậy ý ​​tưởng của tôi là nếu điều này hoạt động thì điều hướng đến /media/hình ảnh/pic1.jpg sẽ được viết lại. Nhưng điều này cũng không làm việc mysite.com/media/images/pic1.jpg vẫn hiển thị hình ảnh.

thử thứ ba: môi trường

Tôi đã thử một cái gì đó tương tự với môi trường bên trong máy chủ ảo:

<VirtualHost *:80>
    ...
    SetEnvIf Referer "mysite\.com\/priv" localreferer
    SetEnvIf Referer ^$ localreferer
    <FilesMatch "\.(jpg|png|gif|pdf)$">
        Require env localreferer
    </FilesMatch>
    ...
</VirtualHost>

Nhưng điều này cũng không hiệu quả; Tôi vẫn có thể điều hướng trực tiếp đến hình ảnh.

lần thử thứ tư: Yêu cầu người dùng hợp lệ

Tôi đã thêm Yêu cầu người dùng hợp lệ đến v-host, nhưng tôi không thể tìm ra cách kiểm tra nó dựa trên mô hình người dùng Django. Điều này sau thay đổi này, tôi sẽ nhận được lời nhắc đăng nhập mỗi khi tôi tải một trang hiển thị hình ảnh (nhưng không có htaccess, v.v., không có gì để xác thực và không có hình ảnh nào được hiển thị trên trang web.

Sau đó tôi đã cố gắng thực hiện những gì được mô tả ở đây (https://docs.djangoproject.com/en/3.2/howto/deployment/wsgi/apache-auth/), nhưng dự án django của tôi không thích Trình xử lý WSGI (ngược lại với mặc định get_wsgi_application()). tôi nhận được một nâng cao AppRegistryNotReady("Ứng dụng chưa được tải.") lỗi. Có vẻ như đây có thể là cách tiếp cận hợp lý nhất, nhưng tôi không biết cách lấy Trình xử lý WSGI làm việc, hoặc cách tiếp cận làm việc với get_wsgi_application().

Tôi biết rằng tôi có thể đặt cho các tệp một tên giống như uuid khó đoán, nhưng đây có vẻ là một giải pháp nửa vời. Vì vậy, chiến lược tốt nhất của tôi là gì để hạn chế quyền truy cập vào thư mục phương tiện để những hình ảnh này chỉ được liên kết trong một phần của trang nơi người dùng được xác thực?

Ubuntu 20.04, Apache 2.4

| Chỉnh sửa, làm theo một số lời khuyên |

auth.py

def check_password(môi trường, tên người dùng, mật khẩu):
    print("---->>>---->>>---->>>---->>>---->>> check_password() đã được gọi <<<--- -<<<----<<<----<<<----<<<----")

    trả về Đúng

#từ django.contrib.auth.handlers.modwsgi nhập check_password

Nhật ký Apache cho thấy rằng tập lệnh này đã được tải, nhưng chức năng dường như không được thực thi vì câu lệnh in không xuất hiện trong nhật ký. Tôi đặt một câu lệnh in lạc trong tệp này và trong tệp wsgi.py để đảm bảo chiến lược này được đưa vào nhật ký, chỉ chiến lược trong tệp wsgi.py mới được đưa vào nhật ký.

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>

|chỉnh sửa khác |

Tôi chấp nhận câu trả lời vì mọi thứ hiện đang hoạt động. Có rất nhiều bộ phận chuyển động, gây ra vấn đề ban đầu với câu trả lời. (1) Hàm kiểm tra check_password không hiển thị trong nhật ký apache...à nó xuất hiện lúc /var/log/Apache2/error.log thay vì nhật ký tùy chỉnh đã được thiết lập. Không chắc tại sao, nhưng ok ...

(2) Venv của tôi không được kích hoạt đúng cách và tôi thực sự không nhận thấy điều này vì django cũng được cài đặt trên hệ thống Python. tôi đã sao chép activate_this.py tập lệnh từ virtualenv và thêm nó vào venv của tôi và thêm sth như thế này vào tệp wsgi của tôi

activate_this = '/path/to/ENV/bin/activate_this.py'
với open(activ_this) như f:
    exec(f.read(), {'__file__': activate_this})

Với những điều đó đã được khắc phục, chức năng check_password hoạt động khi được gọi từ tệp wsgi.py. "hoạt động" ở đây có nghĩa là nó hạn chế quyền truy cập vào thư mục mà người dùng chưa được xác thực không có quyền truy cập. Người dùng vẫn cần cung cấp thông tin xác thực hai lần - một lần trong chế độ xem django thông thường và một lần trong lời nhắc của trình duyệt. Điều này thật khó chịu, nhưng thực ra câu hỏi của tôi là về việc hạn chế quyền truy cập, vì vậy tôi sẽ để nó vào một ngày khác.

Đề xuất của câu trả lời để gọi check_password từ auth.py không hợp tác với dự án của tôi. Tôi gặp lỗi cho thấy nó được gọi trước wsgi.py – có vẻ như venv chưa được tải hoặc cài đặt chưa được tải tại thời điểm check_password được gọi.

Điểm:1
lá cờ ve

đây là những gì get_wsgi_application đang làm:

def get_wsgi_application():
    django.setup(set_prefix=False) # điều này sẽ dẫn đến "apps_ready=true"
    trả về WSGIHandler()

nó đang thiết lập môi trường django trước khi trả lại trình xử lý.

Những điều sau đây sẽ thực hiện thủ thuật trong wsgi.py của bạn:

ứng dụng = get_wsgi_application()
từ django.contrib.auth.handlers.modwsgi nhập check_password
# trình tự là quan trọng!!

Trong thực tế, vấn đề là dòng đầu tiên trong modwsgi.py:

UserModel = auth.get_user_model()

bởi vì get_user_model() sẽ kiểm tra apps_ready và tất cả những gì được thực hiện ngay khi python thực hiện nhập tệp!

cách tốt hơn là tạo một auth.py riêng biệt và trước tiên hãy kiểm tra xem nó có thực sự được gọi bởi Apache hay không bằng một bản in đơn giản sẽ chuyển đến error.log của Apache:

def check_password(môi trường, tên người dùng, mật khẩu):
    print("*********** check_password() duoc goi la *********")
    trả về Đúng

Khi điều này đang chạy, bạn có thể thay thế nó bằng câu lệnh nhập và sử dụng djangos check_password().

từ django.contrib.auth.handlers.modwsgi nhập check_password

Sau đó, một cái gì đó giống như sau trong 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>
lá cờ cn
Bob
Cảm ơn! Hai điều kỳ lạ đang xảy ra sau khi thực hiện các thay đổi mà bạn đề xuất. 1. Tôi nhận được lời nhắc từ trình duyệt để xác thực (chỉ lần đầu tiên, nhưng tôi cho rằng nó sẽ được xử lý bởi chế độ xem đăng nhập của tôi). 2. Không có hình ảnh nào được hiển thị từ thư mục bí mật â trang web tải nhưng yêu cầu img trả về lỗi 500 ("giai đoạn xác thực 'kiểm tra người dùng' đã đưa ra trạng thái 500" trong tệp nhật ký.) Tôi không biết ý nghĩa của nó & google không hữu ích.
Razenstein avatar
lá cờ ve
Tôi thay đổi câu trả lời ở trên: tạo một tệp riêng biệt "auth.py" (dù sao đây cũng là điều đúng đắn và không trộn lẫn nó với wsgi.py tiêu chuẩn - tôi chỉ muốn giữ cho nó đơn giản trong câu trả lời đầu tiên) và đặt một chức năng kiểm tra trong - sau đó bạn có thể xem liệu Apache có đang gọi chức năng "check_password" của bạn hay không.
Razenstein avatar
lá cờ ve
nếu bạn muốn hiển thị, ví dụ: một hình ảnh bên trong một trang chỉ cần sử dụng XSendfile như bạn đề cập dưới dạng giải pháp (1) - nó hoạt động. Trong chức năng/chế độ xem phục vụ url XSendfile, bạn có thể hạn chế quyền truy cập giống như cách bạn hạn chế quyền truy cập vào bất kỳ chế độ xem nào khác. Và bằng cách kích hoạt XSendFile trong Apache, mọi quyền truy cập vào thư mục tương ứng sẽ được chuyển đến ứng dụng django của bạn.
lá cờ cn
Bob
Và khi apache không gọi hàm trong auth.py thì sao? Tôi có cần nhập nó bằng cách nào đó không? Hoặc tham chiếu nó trong cấu hình apache bằng cách nào đó? Nhật ký lỗi giống như câu trả lời đầu tiên.
Razenstein avatar
lá cờ ve
kiểm tra xem chỉ thị "WSGIauthUserScript path_to_auth_script/auth.py" có đúng không. Đăng httpd-vhost.conf và auth.py của bạn.
lá cờ cn
Bob
đăng trong bản chỉnh sửa
lá cờ cn
Bob
Hiện tại, thư mục riêng bị ẩn đối với người dùng chưa được xác thực, nhưng người dùng phải xác thực thông qua lời nhắc từ trình duyệt sau khi đã đăng nhập vào trang web thông qua chế độ xem xác thực django thông thường. Apache không gọi tập lệnh auth.py của tôi, vì vậy tôi cho rằng việc làm cho tập lệnh đó hoạt động sẽ giải quyết được việc đăng nhập bổ sung.

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.