Skip to content

Commit

Permalink
Merge pull request #488 from himdel/fix-basic-401
Browse files Browse the repository at this point in the history
Don't request HTTP Basic authenticaion when using a token
  • Loading branch information
bdunne authored Oct 11, 2018
2 parents da83918 + 55c8cd9 commit c50b0ab
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 29 deletions.
55 changes: 33 additions & 22 deletions app/controllers/api/base_controller/authentication.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,34 @@ class BaseController
module Authentication
SYSTEM_TOKEN_TTL = 30.seconds

def auth_mechanism
if request.headers[HttpHeaders::MIQ_TOKEN]
:system
elsif request.headers[HttpHeaders::AUTH_TOKEN]
:token
elsif request.headers["HTTP_AUTHORIZATION"]
:basic
else
# no attempt at authentication, usually falls back to :basic
nil
end
end

#
# REST APIs Authenticator and Redirector
#
def require_api_user_or_token
if request.headers[HttpHeaders::MIQ_TOKEN]
case auth_mechanism
when :system
authenticate_with_system_token(request.headers[HttpHeaders::MIQ_TOKEN])
elsif request.headers[HttpHeaders::AUTH_TOKEN]
when :token
authenticate_with_user_token(request.headers[HttpHeaders::AUTH_TOKEN])
else
when :basic, nil
success = authenticate_with_http_basic do |u, p|
begin
timeout = ::Settings.api.authentication_timeout.to_i_with_method
user = User.authenticate(u, p, request, :require_user => true, :timeout => timeout)
auth_user_obj = userid_to_userobj(user.userid)
authorize_user_group(auth_user_obj)
validate_user_identity(auth_user_obj)
User.current_user = auth_user_obj
auth_user(user.userid)
rescue MiqException::MiqEVMLoginError => e
raise AuthenticationError, e.message
end
Expand All @@ -30,7 +41,12 @@ def require_api_user_or_token
rescue AuthenticationError => e
api_log_error("AuthenticationError: #{e.message}")
response.headers["Content-Type"] = "application/json"
request_http_basic_authentication("Application", ErrorSerializer.new(:unauthorized, e).serialize.to_json)
case auth_mechanism
when :system, :token
render :status => 401, :json => ErrorSerializer.new(:unauthorized, e).serialize.to_json
when :basic, nil
request_http_basic_authentication("Application", ErrorSerializer.new(:unauthorized, e).serialize.to_json)
end
log_api_response
end

Expand All @@ -41,10 +57,6 @@ def user_settings
}.merge(User.current_user.settings)
end

def userid_to_userobj(userid)
User.lookup_by_identity(userid)
end

def authorize_user_group(user_obj)
group_name = request.headers[HttpHeaders::MIQ_GROUP]
if group_name.present?
Expand All @@ -68,22 +80,25 @@ def api_token_mgr
Environment.user_token_service.token_mgr('api')
end

def auth_user(userid)
auth_user_obj = User.lookup_by_identity(userid)
authorize_user_group(auth_user_obj)
validate_user_identity(auth_user_obj)
User.current_user = auth_user_obj
end

def authenticate_with_user_token(auth_token)
if !api_token_mgr.token_valid?(auth_token)
raise AuthenticationError, "Invalid Authentication Token #{auth_token} specified"
else
userid = api_token_mgr.token_get_info(auth_token, :userid)
raise AuthenticationError, "Invalid Authentication Token #{auth_token} specified" unless userid

auth_user_obj = userid_to_userobj(userid)

unless request.headers['X-Auth-Skip-Token-Renewal'] == 'true'
api_token_mgr.reset_token(auth_token)
end

authorize_user_group(auth_user_obj)
validate_user_identity(auth_user_obj)
User.current_user = auth_user_obj
auth_user(userid)
end
end

Expand All @@ -95,11 +110,7 @@ def authenticate_with_system_token(x_miq_token)

User.authorize_user(@miq_token_hash[:userid])

auth_user_obj = userid_to_userobj(@miq_token_hash[:userid])

authorize_user_group(auth_user_obj)
validate_user_identity(auth_user_obj)
User.current_user = auth_user_obj
auth_user(@miq_token_hash[:userid])
rescue => err
api_log_error("Authentication Failed with System Token\nX-MIQ-Token: #{x_miq_token}\nError: #{err}")
raise AuthenticationError, "Invalid System Authentication Token specified"
Expand Down
5 changes: 1 addition & 4 deletions app/controllers/api/base_controller/logger.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,9 @@ def log_request_initiated
def log_api_auth
return unless api_log_info?
if @miq_token_hash
auth_type = "system"
log_request("System Auth", {:x_miq_token => request.headers[HttpHeaders::MIQ_TOKEN]}.merge(@miq_token_hash))
else
auth_type = request.headers[HttpHeaders::AUTH_TOKEN].blank? ? "basic" : "token"
end
log_request("Authentication", :type => auth_type,
log_request("Authentication", :type => auth_mechanism.to_s,
:token => request.headers[HttpHeaders::AUTH_TOKEN],
:x_miq_group => request.headers[HttpHeaders::MIQ_GROUP],
:user => User.current_user.userid)
Expand Down
4 changes: 1 addition & 3 deletions app/controllers/api/container_deployments_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ def options
private

def authentication_requested?
[HttpHeaders::MIQ_TOKEN, HttpHeaders::AUTH_TOKEN, "HTTP_AUTHORIZATION"].any? do |header|
request.headers.include?(header)
end
!!auth_mechanism
end
end
end
6 changes: 6 additions & 0 deletions spec/requests/authentication_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,12 @@
expect(response).to have_http_status(:unauthorized)
end

it "authentication using a bad token doesn't fallback to HTTP Basic" do
get api_entrypoint_url, :headers => {Api::HttpHeaders::AUTH_TOKEN => "badtoken"}

expect(response.headers.keys).not_to include('WWW-Authenticate')
end

it "authentication using a valid token" do
api_basic_authorize

Expand Down

0 comments on commit c50b0ab

Please sign in to comment.