Add login using remote_user HTTP header for gitlab10.x

The structure of the project is like this:

The client accesses the back-end gitlab through Apache (the version of gitlab is 10.4, the simplified Chinese version installed manually from the source code), and Apache is used as the reverse proxy server of gitlab

Apache has a built-in CAS client. Users who are not logged in will be redirected to CAS to log in. After logging in, they will jump to gitlab and bring an http header named remote_user to identify the user.

gitlab needs to receive this header and let the user log in. If the user does not exist in the system, gitlab needs to get the user's information from ldap, create the user, and then let the user log in

Implemented method:

There is no ready-made configuration for gitlab to achieve this requirement. Solutions such as omniauth-http-header are feasible in principle, but in the actual operation process, it is difficult to integrate into gitlab (because the Gemfile needs to be modified)

Therefore, in the process of doing this, I adopted the following method: Refer to the code of omniauth-http-header, implement an omniauth provider by myself, and add it to gitlab (without using the gem package)

First, in the /home/git/gitlab/lib folder, create a new http_header.rb, and modify the attribution of the file to the git user, as follows:

require 'omniauth'

module OmniAuth
  module Strategies
    class HttpHeader
      include OmniAuth::Strategy

      option :name, 'http_header'

      option :authorization_uri, nil
      option :uid_header, 'remote_user'
      option :info_headers, {}
      option :remote_ip, nil

      def request_phase
        redirect callback_url
      end

      def callback_phase
        if options.remote_ip && !Array(options.remote_ip).include?(request.ip)
          raise ::OmniAuth::Error, "Callback from unauthorized IP #{request.ip}"
        end

        super
      end

      uid do
        fetch_header options.uid_header
      end

      info do
        options.info_headers.each_with_object({}) do |(attribute, header), info|
          info[attribute] = fetch_header header
        end
      end

      private

      def fetch_header(header)
        print request.env
    request.env.fetch "HTTP_#{header.upcase.gsub('-', '_')}"
      end
    end
  end
end

Require and load this file in the omniauth initialization file (/home/git/gitlab/config/initializers/omniauth.rb):

Added require on the first line

require '/home/git/gitlab/lib/http_header.rb'

and the last

Rails.application.config.middleware.use OmniAuth::Builder do
        provider :http_header,
        uid_header: 'remote_user'   
end

The entire file is as follows:

require '/home/git/gitlab/lib/http_header.rb'
if Gitlab::LDAP::Config.enabled?
  module OmniAuth::Strategies
    Gitlab::LDAP::Config.available_servers.each do |server|
      # do not redeclare LDAP
      next if server['provider_name'] == 'ldap'

      const_set(server['provider_class'], Class.new(LDAP))
    end
  end
end

OmniAuth.config.full_host = Settings.gitlab['base_url']
OmniAuth.config.allowed_request_methods = [:post]
# In case of auto sign-in, the GET method is used (users don't get to click on a button)
OmniAuth.config.allowed_request_methods << :get if Gitlab.config.omniauth.auto_sign_in_with_provider.present?
OmniAuth.config.before_request_phase do |env|
  Gitlab::RequestForgeryProtection.call(env)
end

if Gitlab.config.omniauth.enabled
  provider_names = Gitlab.config.omniauth.providers.map(&:name)
  require 'omniauth-kerberos' if provider_names.include?('kerberos')
end

module OmniAuth
  module Strategies
    autoload :Bitbucket, Rails.root.join('lib', 'omni_auth', 'strategies', 'bitbucket')
  end
end

Rails.application.config.middleware.use OmniAuth::Builder do
    provider :http_header,
    uid_header: 'remote_user'   
end

3. Configure the provider of ldap and omniauth in the gitlab.yml file, and get the information that is not available from ldap

The relevant configuration is as follows (ldap configuration has nothing to do with the theme and is omitted):

omniauth:
    enabled: true
    auto_sign_in_with_provider: http_header
    auto_link_ldap_user: true
    providers:
       - { name: 'http_header',
           label: 'http_header',
           args: {
                   uid_header: 'remote_user'
                 } }
    

4. By default, nginx will remove the underlined header. Therefore, the remote_user is killed when passing through nginx. This command needs to be configured under the server node of nginx:

underscores_in_headers on;

Regarding the issue of single-point exit: let apache intercept the exit address of gitlab and redirect it to the exit address of cas. When cas exits, clear the sessioncookie _gitlab_session set by gitlab to achieve single-point exit

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325222033&siteId=291194637