Using Rails 3.2.
I have half a dozen controllers, and want to protect some (but not all) of them with http_basic_authenticate_with
.
I don't want to manually add http_basic_authenticate_with
to each controller (I could add another controller in the future and forget to protect it!). It seems the answer is to put it in application_controller.rb
with an :except
arg which would list the controllers that should not be protected. The problem is, the :except clause wants method names rather than external controller module names, e.g.:
http_basic_authenticate_with :name => 'xxx', :password => 'yyy', :except => :foo, :bar
So then I thought "Wait, since I already have the protected controllers grouped in routes.rb
, let's put it there." So I tried this in my routes:
scope "/billing" do
http_basic_authenticate_with :name ...
resources :foo, :bar ...
end
But now I get
undefined method `http_basic_authenticate_with'
What's the best way to approach this?
Security of basic authentication As the user ID and password are passed over the network as clear text (it is base64 encoded, but base64 is a reversible encoding), the basic authentication scheme is not secure. HTTPS/TLS should be used with basic authentication.
Basic authentication is the simplest form of web authentication. It's a stateless protocol that doesn't require cookies, session identifiers, or login pages (like most other forms of web authentication today).
auth_basic. auth_basic_user_file. The ngx_http_auth_basic_module module allows limiting access to resources by validating the user name and password using the “HTTP Basic Authentication” protocol. Access can also be limited by address, by the result of subrequest, or by JWT.
Do it the way Rails does it.
# rails/actionpack/lib/action_controller/metal/http_authentication.rb
def http_basic_authenticate_with(options = {})
before_action(options.except(:name, :password, :realm)) do
authenticate_or_request_with_http_basic(options[:realm] || "Application") do |name, password|
name == options[:name] && password == options[:password]
end
end
end
All that http_basic_authenticate_with
does is add a before_action
. You can just as easily do the same yourself:
# application_controller.rb
before_action :http_basic_authenticate
def http_basic_authenticate
authenticate_or_request_with_http_basic do |name, password|
name == 'xxx' && password == 'yyy'
end
end
which means you can use skip_before_action
in controllers where this behavior isn't desired:
# unprotected_controller.rb
skip_before_action :http_basic_authenticate
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With