Debian – gitlab authentication using HTTP_REMOTE_USER environment variable

apache-2.2debiangitlabruby-on-rails

we have discovered gitlab, and I would like to integrate it in our global authentication process, which relies on apache HTTP_REMOTE_USER environment variable.

I have seen very little documentation on it, so I am looking desperately for any help on how to do this. I would like to retrieve from the gitlab application the HTTP_REMOTE_USER variable and use it to authenticate my users.

I have tried to use omniauth and omniauth-ldap, but this returns only in Errors 500 in my server and seems to be a little bit overkill to only retrieve Apache HTTP_REMOTE_USER variable. What i am looking for is if such a feature simply exists, or if i am going to a wrong direction; if someone has some links to doc on it!

Many thanks


Many thanks for your answer!
I had already add the RequestHeader in the apache configuration file (I am using as you apache as unicorn reverse proxy instead of nginx, and needed to forward the HTTP_REMOTE_USER to unicorn in the apache header). Then, I have applied the patch available here.

Unlike you, I am not using a ldap username/password authentication, but a kerberos authentication with ldap for autorisations. When I reach the gitlab web page, I can see on the logs that my authentification is granted, and gitlab retrieve from ldap my user attributes (email address). It even creates my account (as per allow_single_sign_on: true on /home/git/gitlab/config/gitlab.yml file). But then, it displays an error 500, with log message "error stack too deep".

I have then changed the file vendor/bundle/ruby/2.0.0/activesupport-3.2.13/lib/active_support/callbacks.rb to puts on a dummy file what is going on: (line 413)

def __reset_runner(symbol)
  f = File::open('/tmp/blah', 'a')
  f.write(caller(1,10))
  f.close()

I then see that it recurses on a few functions (functions calling each others in an infinite loop). (Here is a period in /home/git/gitlab; first line repeats after last one):

vendor/bundle/ruby/2.0.0/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:436:in `block in __update_callbacks'
vendor/bundle/ruby/2.0.0/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:433:in `each'
vendor/bundle/ruby/2.0.0/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:433:in `__update_callbacks'
vendor/bundle/ruby/2.0.0/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:502:in `set_callback'
vendor/bundle/ruby/2.0.0/gems/activemodel-3.2.13/lib/active_model/callbacks.rb:110:in `before_save'
vendor/bundle/ruby/2.0.0/gems/activerecord-3.2.13/lib/active_record/autosave_association.rb:189:in `add_autosave_association_callbacks'
vendor/bundle/ruby/2.0.0/gems/activerecord-3.2.13/lib/active_record/autosave_association.rb:140:in `build'
vendor/bundle/ruby/2.0.0/gems/activerecord-3.2.13/lib/active_record/associations/builder/has_many.rb:10:in `build'
vendor/bundle/ruby/2.0.0/gems/activerecord-3.2.13/lib/active_record/associations/builder/collection_association.rb:13:in `build'
vendor/bundle/ruby/2.0.0/gems/activerecord-3.2.13/lib/active_record/associations.rb:1198:in `has_many'

At this step, I really don't know how to fix this; it s far away from my RoR (none) and Ruby (few) knowledge. :/ Any help would be appreciated here!

Best Answer

I've recently been butting my head up against the very same problem, but I've managed to get it to work. This is a very hacky solution so you may want to refine it yourself. I make use of LDAP to provide the email address and user account information, gaining the user name from the HTTP_REMOTE_USER variable which is populated by kerberos via apache.

The following works off a clean install of gitlab with apache running as the webserver. LDAP omniauth should be enabled and properly configured.

First off, we have to make the header available to ruby so, in the virtual host (httpd.conf) add the line:

RequestHeader set REMOTE-USER %{REMOTE_USER}s

After that, I modified a few files to make this work, first up /home/git/gitlab/vendor/bundle/ruby/2.0.0/gems/gitlab_omniauth-ldap-1.0.3/lib/omniauth/strategies/ldap.rb

I modified lines 43-49 to read:

# Dont allow blank password for ldap auth
      #if request['username'].nil? || request['username'].empty? || request['password'].nil? || request['password'].empty?
      #  raise MissingCredentialsError.new(env.to_a)#"Missing login credentials")
      #end

      @ldap_user_info = @adaptor.bind_as(:filter => Net::LDAP::Filter.eq(@adaptor.uid, @options[:name_proc].call(request.env['HTTP_REMOTE_USER'].split('@')[0])),:size => 1, :username => "__ldap-user__", :password => "__User-Password__")
      return fail!(:invalid_credentials) if !@ldap_user_info

Replacing __ldap-user__ and __user-Password__ with the credentials for a gitlab user I made for ldap.

We then need to allow the bind_as function to take a username. I modified lines 86-86 of /home/git/gitlab/vendor/bundle/ruby/2.0.0/gems/gitlab_omniauth-ldap-1.0.3/lib/omniauth-ldap/adaptor.rb to read:

  def bind_as(args = {})
    result = false
    @connection.open do |me|
      rs = me.search args
      if rs and rs.first and dn = rs.first.dn
        password = args[:password]
        username = args[:username]
        method = args[:method] || @method
        password = password.call if password.respond_to?(:call)
        if method == 'sasl'
        result = rs.first if me.bind(sasl_auths({:username => username, :password => password}).first)
        else
        result = rs.first if me.bind(:method => :simple, :username => username,
                            :password => password)
        end
      end
    end
    result
  end

and finally I modified the ldap login dialogue to direct the page straight to the callback by deleting everything in /home/git/gitlab/app/views/devise/sessions/_new_ldap.html.haml and adding

%script
  window.location.href = '/users/auth/ldap/callback'

I hope this helps!

Warning: if the mail attribute is not set in the user's LDAP entry, the script will loop.

Related Topic