Roda Http Authorization
Add http authorization methods to Roda.
Configuration
Configure your Roda application to use this plugin:
plugin :http_auth
You can pass global options, in this context they'll be shared between all
r.http_auth
calls.
plugin :http_auth, authenticator: proc {|user, pass| [user, pass] == %w[foo bar]},
realm: 'Restricted Area', # default
schemes: %w[basic] # default
Additional Configuration
The header sent when the user is unauthorized can be configured via
unauthorized_headers
option, globally or locally:
unauthorized_headers: proc do |opts|
{'Content-Type' => 'text/plain',
'Content-Length' => '0',
'WWW-Authenticate' => ('Basic realm="%s"' % opts[:realm])}
end, # default
The unauthorized
option can receive a block to be invoked whenever the user
is unathorized:
plugin :http_auth, unauthorized: proc do |r|
logger.warn("Unathorized attempt to access #{r.path}!!")
end
Usage
Call r.http_auth
inside the routes you want to authenticate the user, it will halt
the request with 401 response code if the authenticator is false.
An additional WWW-Authenticate
header is sent as specified on rfc7235 and it's realm can be configured.
Basic Auth
Basic authorization is the default method:
r.http_auth { |user, pass| [user, pass] == %w[foo bar] }
Schemes
By default authorization schemes are whitelisted, so if you want to use one that is not basic auth you must configure it:
plugin :http_auth, schemes: %w[bearer]
You can also whitelist schemes for a specific route:
r.http_auth(schemes: %w[bearer]) { |token| token == '4t0k3n' }
Scheme: Bearer
When the Bearer
authorization is scheme is passed, if whitelisted, the token
is passed to the authenticator:
r.http_auth { |token| token == '4t0k3n' }
Formatted parameters schemes
For schemes that require formatted params authorization header, like Digest
,
the scheme and the parsed params are passed to the authenticator:
# Request
Authorization: Digest username="Mufasa",
realm="[email protected]",
uri="/dir/index.html",
algorithm=MD5,
nonce="7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v",
nc=00000001,
cnonce="f2/wE4q74E6zIJEtWaHKaf5wv/H5QzzpXusqGemxURZJ",
qop=auth,
response="8ca523f5e9506fed4657c9700eebdbec",
opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS"
r.http_auth { |s, p| [s, p['username']] == ['digest', 'Mufasa'] }
Test
bundle exec ruby test/*.rb
Warden
To avoid having your 401 responses intercepted by warden, you need to configure the unauthenticated callback that is called just before the request is halted:
plugin :http_auth, unauthorized: proc {|r| r.env['warden'].custom_failure! }
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/badosu/roda-basic-auth.
License
The gem is available as open source under the terms of the MIT License.