Skip to content

Commit

Permalink
[webui] Implement kerberos authentication in webui
Browse files Browse the repository at this point in the history
* Handle login via kerberos in webui (require_login filter)
* Disable sign up ui when kerberos mode is enabled
  • Loading branch information
bgeuken committed Apr 19, 2017
1 parent f82e5f4 commit 77644b3
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 24 deletions.
60 changes: 48 additions & 12 deletions src/api/app/controllers/webui/webui_controller.rb
@@ -1,6 +1,8 @@
# Filters added to this controller will be run for all controllers in the application.
# Likewise, all the methods added will be available for all controllers.

require_dependency 'authenticator'

class Webui::WebuiController < ActionController::Base
helper_method :valid_xml_id

Expand Down Expand Up @@ -102,19 +104,23 @@ def valid_xml_id(rawid)
protected

def require_login
if User.current.nil? || User.current.is_nobody?
render(text: 'Please login') && (return false) if request.xhr?

flash[:error] = 'Please login to access the requested page.'
mode = CONFIG['proxy_auth_mode'] || :off
if mode == :off
redirect_to controller: :user, action: :login
else
redirect_to controller: :main
if CONFIG['kerberos_service_principal']
kerberos_auth
else
if User.current.nil? || User.current.is_nobody?
render(text: 'Please login') && (return false) if request.xhr?

flash[:error] = 'Please login to access the requested page.'
mode = CONFIG['proxy_auth_mode'] || :off
if mode == :off
redirect_to controller: :user, action: :login
else
redirect_to controller: :main
end
return false
end
return false
true
end
true
end

def required_parameters(*parameters)
Expand Down Expand Up @@ -154,10 +160,40 @@ def lockout_spiders
false
end

def authenticator
@authenticator ||= Authenticator.new(request, session, response)
end

def kerberos_auth
return true unless CONFIG['kerberos_service_principal'] && (User.current.nil? || User.current.is_nobody?)

authorization = authenticator.authorization_infos || []
if authorization[0].to_s != "Negotiate"
# Demand kerberos negotiation
response.headers["WWW-Authenticate"] = 'Negotiate'
render :login, status: 401
return
else
begin
authenticator.extract_user
rescue Authenticator::AuthenticationRequiredError => e
logger.info "Authentication via kerberos failed '#{e.message}'"
flash[:error] = "Authentication failed: '#{e.message}'"
redirect_back(fallback_location: root_path)
return
end
if User.current
logger.info "User '#{User.current}' has logged in via kerberos"
session[:login] = User.current.login
redirect_back(fallback_location: root_path)
return true
end
end
end

def check_user
check_spiders
User.current = nil # reset old users hanging around

if CONFIG['proxy_auth_mode'] == :on
logger.debug "Authenticating with proxy auth mode"
user_login = request.env['HTTP_X_USERNAME']
Expand Down
1 change: 1 addition & 0 deletions src/api/app/helpers/webui/webui_helper.rb
Expand Up @@ -379,6 +379,7 @@ def possibly_empty_ul(html_opts, &block)
end

def can_register
return false if CONFIG['kerberos_service_principal']
return true if User.current.try(:is_admin?)

begin
Expand Down
8 changes: 8 additions & 0 deletions src/api/app/views/webui/user/login.html.haml
Expand Up @@ -6,6 +6,14 @@
%input{name: "proxypath", type: "hidden", value: "reverse"}/
%input{name: "message", type: "hidden", value: "Please log In"}/
= render partial: 'login_form'
- elsif CONFIG['kerberos_mode']
%h2
Kerberos authentication required
%div
%p
You are seeing this page, because you are not authenticated in the kerberos realm ('#{CONFIG['kerberos_realm']}').
%p
Please ensure you have a valid ticket and try again.
- else
= form_tag controller: :user, action: :do_login, method: :post do
= render partial: 'login_form'
24 changes: 12 additions & 12 deletions src/api/lib/authenticator.rb
Expand Up @@ -87,6 +87,18 @@ def require_admin
true
end

def authorization_infos
# 1. try to get it where mod_rewrite might have put it
# 2. for Apache/mod_fastcgi with -pass-header Authorization
# 3. regular location
%w(X-HTTP_AUTHORIZATION Authorization HTTP_AUTHORIZATION).each do |header|
if request.env.has_key? header
return request.env[header].to_s.split
end
end
return
end

private

def initialize_krb_session
Expand Down Expand Up @@ -206,18 +218,6 @@ def extract_auth_user
end
end

def authorization_infos
# 1. try to get it where mod_rewrite might have put it
# 2. for Apace/mod_fastcgi with -pass-header Authorization
# 3. regular location
%w(X-HTTP_AUTHORIZATION Authorization HTTP_AUTHORIZATION).each do |header|
if request.env.has_key? header
return request.env[header].to_s.split
end
end
return
end

def check_extracted_user
unless @http_user
if @login.blank?
Expand Down

0 comments on commit 77644b3

Please sign in to comment.