set WWW-Authenticate header on authentication failure

pull/2978/head
Markus Kahl 10 years ago
parent 27868f5c75
commit 28d3dfd827
  1. 29
      lib/api/root.rb
  2. 10
      lib/open_project/authentication.rb
  3. 4
      spec/requests/api/v3/authentication_spec.rb

@ -65,6 +65,27 @@ module API
use OpenProject::Authentication::Manager
##
# We need this to be able to use `Grape::Middleware::Error#error_response`
# outside of the Grape context. We use it outside of the Grape context because
# OpenProject authentication happens in a middleware upstream of Grape.
class GrapeError < Grape::Middleware::Error
def initialize(env)
@env = env
@options = {}
end
end
##
# Return JSON error response on authentication failure.
OpenProject::Authentication.handle_failure(scope: API_V3) do |warden, _opts|
e = GrapeError.new warden.env
representer = ::API::V3::Errors::ErrorRepresenter.new ::API::Errors::Unauthenticated.new
warden.env['api.format'] = 'hal+json'
e.error_response(status: 401, message: representer.to_json, headers: warden.headers)
end
helpers do
def current_user
User.current
@ -155,6 +176,14 @@ module API
error_response(status: api_error.code, message: representer.to_json)
end
# Make sure the WWW-Authenticate header is set upon 401.
rescue_from ::API::Errors::Unauthenticated do |e|
headers = { 'WWW-Authenticate' => %(Basic realm="#{OpenProject::Authentication::Realm.realm}") }
representer = ::API::V3::Errors::ErrorRepresenter.new(e)
env['api.format'] = 'hal+json'
error_response(status: e.code, message: representer.to_json, headers: headers)
end
rescue_from ::API::Errors::ErrorBase, rescue_subclasses: true do |e|
representer = ::API::V3::Errors::ErrorRepresenter.new(e)
env['api.format'] = 'hal+json'

@ -60,5 +60,15 @@ module OpenProject
end
end
end
module Realm
module_function
def realm
'OpenProject'
end
end
end
end
Warden::Strategies::BasicAuth.include OpenProject::Authentication::Realm

@ -62,6 +62,10 @@ describe API::V3, type: :request do
it 'should return the correct JSON response' do
expect(JSON.parse(response.body)).to eq response_401
end
it 'should return the WWW-Authenticate header' do
expect(response.header['WWW-Authenticate']).to include 'Basic realm="OpenProject"'
end
end
context 'with invalid credentials' do

Loading…
Cancel
Save