Reputation: 1183
I have created a custom middleware for rails which will intercept all requests and make sure it's coming from an authorized IP, otherwise it should prompt for a basic http auth user/name password.
This is currently what it looks like:
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
The issue with this code is that I can't seem to find a way to trigger the http auth window on the browser. I reviewed this and didn't see any obvious indication of how this is done.
Could you please point me in the right direction?
Upvotes: 1
Views: 2225
Reputation: 1327
You need to provide a WWW-Authenticate
header. See.
I assume, in your else
, you would do:
[401, {'WWW-Authenticate' => 'Basic realm="Application"', "Content-Type" => "text/html"}, ["Not Authorized on this environment."]]
Upvotes: 1
Reputation: 3390
I'm using Rack::Auth::Basic
directly and saves myself the validation part:
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
```
Upvotes: 6
Reputation: 864
I haven't tested your code, but it looks like your replying with a 403 which means "forbidden". I.e., the currently logged in user does not have permissions to access this resource.
From the RFC (http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html)
The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal in the entity. If the server does not wish to make this information available to the client, the status code 404 (Not Found) can be used instead.
Instead, you need to use a 401, and only reply with a 403 ONLY if the currently logged in user cannot access the resource.
Upvotes: 1