2012-09-12 3 views
8

Tôi có một ứng dụng Django nhỏ với chế độ xem mà tôi muốn hạn chế đối với một số người dùng nhất định. Bất kỳ ai từ một mạng cụ thể đều có thể xem chế độ xem đó mà không cần xác thực thêm, chỉ dựa trên địa chỉ IP. Bất kỳ ai khác từ bên ngoài dải IP này sẽ được yêu cầu nhập mật khẩu và được xác thực dựa trên quản lý người dùng Django mặc định.Xác thực bằng địa chỉ IP ở Django

Tôi giả sử tôi phải viết một phần phụ trợ xác thực tùy chỉnh cho điều đó, nhưng tài liệu này làm tôi bối rối vì chức năng authenticate() dường như mong đợi kết hợp tên người dùng/mật khẩu hoặc mã thông báo. Nó không phải là rõ ràng với tôi làm thế nào để xác thực bằng cách sử dụng địa chỉ IP ở đây.

Cách thích hợp để triển khai xác thực dựa trên địa chỉ IP ở Django là gì? Tôi muốn sử dụng càng nhiều hàm thư viện hiện có càng tốt cho mã liên quan đến bảo mật thay vì tự viết tất cả.

Trả lời

3

Không cần phải viết phần phụ trợ xác thực cho trường hợp sử dụng bạn đã viết. Viết bộ điều phối dựa trên IP trong lớp phần mềm trung gian có thể sẽ đủ

Nếu url của ứng dụng của bạn được/khớp, process_request sẽ kiểm tra người dùng django đã xác thực và kết hợp người dùng đó với danh sách cho phép.

6

Bạn cũng có thể viết một trang trí nhỏ cho mục đích này:

def login_by_ip(view_func): 
    def authorize(request, *args, **kwargs): 
     user_ip = request.META['REMOTE_ADDR'] 
     for ip in allowedIps.allowedIps: 
      authenticated_by_ip = re.compile(ip).match(user_ip) 
      if authenticated_by_ip: 
       return view_func(request, authenticated_by_ip, *args, **kwargs) 
     return HttpResponseRedirect('/redirect/path/') 
    return authorize 

allowedIps là trong trường hợp của tôi một tập tin (allowedIps.py) mà các cửa hàng regexes cho IP cho phép trong một tuple như thế này:

allowedIps = ('^XXX\.XXX\..+\..+$','^XXX\.XXX\.XXX\..+$', '^XXX\.XXX\.XXX\.XXX$') 

Hy vọng điều này có thể giúp hoặc đưa ra ý tưởng. Lưu ý: nếu bạn trả lại authenticated_by_ip cho chế độ xem được trang trí, chế độ xem của bạn sẽ phải chấp nhận thông số đó, bạn cũng có thể chỉ cần sử dụng nó, nếu bạn không cần nó. Bạn cũng có thể xác định các regex chính xác hơn để chỉ chấp nhận các chữ số lên đến ba.

1
def login_by_id(request): 
    ip = request.META['REMOTE_ADDR'] 
    try: UserProfile.objects.get(allow_ip=id) 
    except UserProfile.DoesNotExist: return HttpResponseRedirect('././') 
    else: 
     # auth here 

Bạn cần allow_ip trong bạn mô hình UserProfile, mà tiết kiệm về đăng ký hoặc thay đổi nào trên chỉnh sửa trang sử dụng

9

Có hai phương pháp thích hợp cho rằng loại xác thực:

  • Như Decorator: nếu một số chế độ xem (nhưng không nhiều trong số đó) yêu cầu séc này, thì tốt hơn bạn nên viết trang trí cho điều đó (chẳng hạn như @Jingo đã viết)
  • Là Middleware: nếu kiểm tra đó cần phải được thực hiện bởi tất cả (hoặc nhiều) lượt xem, thay vì sử dụng một trang trí, viết một middleware là một giải pháp tốt hơn.

Một middleware mẫu có thể được cái gì đó như:

ALLOWED_IP_BLOCKS = [......] 

class NeedToLoginMiddleware(object): 
    def process_request(self, request): 
     ip = request.META['REMOTE_ADDR'] 
     if not ip in ALLOWED_IP_BLOCKS: #ip check 
      if not request.user.is_authenticated(): #if ip check failed, make authentication check 
       return HttpResponseRedirect(...) 
    return None 
  • Bạn có thể thực hiện kiểm tra ip sử dụng một danh sách, hoặc một regex như @Jingo đề cập.
  • Nếu bạn đang sử dụng xác thực django và REMOTE_ADDR không có trong danh sách ALLOWED_IP_BLOCKS, thì bạn có thể sử dụng is_authenticated để kiểm tra xem người dùng có liên quan đã đăng nhập hay không.Nhưng để sử dụng is_autheticated trong phần mềm trung gian tùy chỉnh, phần mềm trung gian tùy chỉnh của bạn phải được đặt sauAuthenticationMiddleware, vì request.user được đặt ở cấp đó.

    MIDDLEWARE_CLASSES = (
        ... 
        'django.contrib.auth.middleware.AuthenticationMiddleware', 
        'path.to.my.NeedToLoginMiddleware', 
        ... 
    ) 
    
    • Nếu một vài quan điểm không yêu cầu chứng thực này, sau đó bạn có thể làm cho một danh sách các url đặc biệt và nhận được yêu cầu từ url request.path và kiểm tra xem địa chỉ yêu cầu đòi hỏi ip kiểm tra/xác thực.

Thông tin thêm về custom middleware classes

+1

Đưa 'ALLOWED_IP_BLOCKS' vào * settings.py *, và truy cập nó với 'settings.ALLOWED_IP_BLOCKS' (cần' từ settings' django.conf nhập khẩu) sẽ cho phép một đẹp hơn cấu hình, – luckydonald

1

IMO, giải quyết này với Django là tốt nếu đó là một tổ chức phi hiệu suất trang web quan trọng nhỏ.

Tốt hơn nên giữ cho người dùng trái phép hoàn toàn không sử dụng dịch vụ Apache hoặc Nginx của bạn. Ví dụ, trong Nginx tôi có những dòng này trong cấu hình trang web của tôi:

include allowed_ips.conf; 
deny all; 
error_page 403 forbidden.html; 

allowed_ips.conf là trong/etc/nginx và ngoại hình (cái gì đó) như thế này:

allow 110.222.333.222; # J Bloggs (sys admin) 
allow 777.222.0.0/16; # Government owned 
... 

Tôi tin rằng đây là tốt hơn bởi vì các quá trình Django tương đối chậm không bao giờ bị xúc động bởi các IP bị chặn. Điều này là quan trọng nếu bạn đang chặn bot hoặc phạm vi địa chỉ quốc gia khác vì lý do hiệu suất hoặc bảo mật.

3

Bạn có thể dùng thử trang trí này. Tôi đã thử nghiệm nó làm việc tốt:

allowedIps = ['129.0.0.1', '127.0.0.1'] 
def allow_by_ip(view_func): 
    def authorize(request, *args, **kwargs): 
     user_ip = request.META['REMOTE_ADDR'] 
     for ip in allowedIps: 
      if ip==user_ip: 
       return view_func(request, *args, **kwargs) 
     return HttpResponse('Invalid Ip Access!') 
    return authorize