2013-05-16 1 views
1

Я создал собственное промежуточное программное обеспечение для рельсов, которое перехватит все запросы и убедитесь, что оно исходит от авторизованного IP-адреса, в противном случае он должен запросить базовый пароль пользователя/имени пользователя.Trigger basic HTTP auth изнутри промежуточного программного обеспечения

Это в настоящее время, как он выглядит:

require 'net/http' 

class AuthorizeEnvironment 
    def initialize(app) 
    @app = app 
    end 

    def call(env) 
    if AppConstants.approved_doximity_ips.include?(env["REMOTE_ADDR"]) 
     @app.call(env) 
    elsif authorized?(env) 
     @app.call(env) 
    else 
     [403, {"Content-Type" => "text/html"}, ["Not Authorized on this environment."]] 
    end 
    end 

    def authorized?(env) 
    @auth ||= Rack::Auth::Basic::Request.new(env) 
    @auth.provided? && @auth.basic? && @auth.credentials && @auth.credentials == ['username', 'password'] 
    end 
end 

Проблема с этим кодом, что я не могу показаться, чтобы найти способ, чтобы вызвать окно HTTP аутентификации в браузере. Я рассмотрел this и не видел никаких явных признаков того, как это делается.

Не могли бы вы указать мне в правильном направлении?

ответ

1

Я не тестировал ваш код, но похоже, что вы отвечаете на вопрос 403, что означает «запрещено». I.e., у текущего зарегистрированного пользователя нет разрешений для доступа к этому ресурсу.

Из RFC (http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html)

Сервер понял запрос, но отказывается выполнять его. Авторизация не поможет, и запрос НЕ ДОЛЖЕН повториться. Если метод запроса не был HEAD, и сервер хочет сообщить, почему запрос не был выполнен, ему ДОЛЖЕН описать причину отказа в сущности. Если сервер не хочет предоставлять эту информацию клиенту, вместо этого может использоваться код состояния 404 (Not Found).

Вместо этого вам нужно использовать 401 и отвечать только с 403 ТОЛЬКО, если текущий пользователь не может получить доступ к ресурсу.

2

Я использую Rack::Auth::Basic непосредственно и сохраняет себя часть проверки:

class BasicAuth 
    def initialize(app) 
    @app = app 
    end 

    def call(env) 
    if env["PATH_INFO"] == '/supersecret' # Any condition here 
     auth = Rack::Auth::Basic.new(@app) do |u, p| 
     u == username && p == password 
     end 
     auth.call env 
    else 
     @app.call env 
    end 
    end 

    def username 
    ENV["username"] 
    end 

    def password 
    ENV["password"] 
    end 
end 

`` `

1

Вы должны предоставить WWW-Authenticate заголовок. See.

Я полагаю, в вашем else, вы могли бы сделать:

[401, {'WWW-Authenticate' => 'Basic realm="Application"', "Content-Type" => "text/html"}, ["Not Authorized on this environment."]] 

 Смежные вопросы

  • Нет связанных вопросов^_^