Use MM as oauth2 provider for GitLab

I am trying to use MM as an oauth2 provider for gitlab to authenticate against.

Here is my setup so far:

gitlab_rails['omniauth_providers'] = [
   {
     "name" => "oauth2_generic",
     "app_id" => "xxx",
     "app_secret" => "xxx",
     "args" => {
       client_options: {
          'site' => 'https://meeting.swsz.org',
          'user_info_url' => '/api/v4/users/me'
       },
       user_response_structure: {
        root_path: [],
        attributes: { nickname: 'username' }
       },
       name: 'Mattermost',
       strategy_class: "OmniAuth::Strategies::OAuth2Generic"
}   }

When I try to login through Mattermost I see the following message on GitLab:
Could not authenticate you from Mattermost because ā€œā€.

The docker logs of the MM web container say the following;
172.18.0.9 - - [10/Mar/2018:13:48:00 +0100] ā€œGET /oauth/authorize?client_id=xxx&redirect_uri=https%3A%2F%2Fgit.swsz.org%2Fusers%2Fauth%2FMattermost%2Fcallback&response_type=code&state=466e6474e18304b3be133be2a3b1a26289c07e0f8890df30 HTTP/1.1ā€ 302 191 ā€œhttps://git.swsz.org/ā€ ā€œMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36ā€ ā€œ46.95.76.208ā€
172.18.0.9 - - [10/Mar/2018:13:48:00 +0100] ā€œPOST /oauth/token HTTP/1.1ā€ 405 0 ā€œ-ā€ ā€œFaraday v0.12.2ā€ ā€œ172.18.0.1ā€

Any help with this would be highly appreciated.

I only found topics on here who tried to do it the other way arround (having gitlab as the oauth2 provider)

It looks like youā€™re off to a great start! I had hoped to replicate your setup and assist with testing, but it looks like I have to custom compile Gitlab to even get the https://gitlab.com/satorix/omniauth-oauth2-generic gem installed. If you have any suggestions on ways to bootstrap that process Iā€™d be happy to help further!

At this point, Iā€™d be curious to see if the call to /api/v4/users/me gets invoked without error. It might also be useful to intercept the network requests using your browserā€™s developer console and examine the payload for further clues.

Iā€™ve set it up in a docker environment. Using: https://hub.docker.com/r/gitlab/gitlab-ce/

Iā€™ll try the browser tools this evening (GMT). From what I see in the logs it failed when trying to retrieve the oauth token (405 error) ā€¦ so it doesnā€™t even get thus far as to get the user info via API.

image

What exactly are we looking for? I really would love to get this off the ground and add other applications to this setup. :slight_smile:

In that console tab, can you consecutively click on the top four network requests and post the Form Data from the bottom of the Headers tab, and the entire contents of the Response tab? (Shouldnā€™t be anything to redact from that text, but may want to just peruse before posting publicly.)

Here are the requested screens: (can only post one image per post)
image

Iā€™ve now deauthorized the app, just that the oauth tokens posted here canā€™t be reused.
Kind of strange that the response tab is always empty.

image

image

image

image

image

image

image

Good news is that Iā€™ve been able to reproduce the problem youā€™re observing above. Bad news is that itā€™s still unclear why this doesnā€™t work. To document, hereā€™s my changes to /etc/gitlab/gitlab.rb in the GitLab Ominbus image based on your changes above:

gitlab_rails['omniauth_enabled'] = true
gitlab_rails['omniauth_allow_single_sign_on'] = ['oauth2_generic']
gitlab_rails['omniauth_block_auto_created_users'] = false
gitlab_rails['omniauth_auto_link_saml_user'] = true

gitlab_rails['omniauth_providers'] = [
  {
    'name' => 'oauth2_generic',
    'app_id' => '<app_id>',
    'app_secret' => '<app_secret>',
    'args' => {
      client_options: {
        'site' => 'http://<mattermost_host>:8065/', # including port if necessary
        'user_info_url' => '/api/v4/users/me'
      },
      user_response_structure: {
        root_path: [], # i.e. if attributes are returned in JsonAPI format (in a 'user' node nested under a 'data' node)
        attributes: { nickname: 'username' } # if the nickname attribute of a user is called 'username'
      },
      # optionally, you can add the following two lines to "white label" the display name
      # of this strategy (appears in urls and Gitlab login buttons)
      # If you do this, you must also replace oauth2_generic, everywhere it appears above, with the new name.
      name: 'Mattermost', # display name for this strategy
      strategy_class: "OmniAuth::Strategies::OAuth2Generic" # Devise-specific config option Gitlab uses to find renamed strategy
    }
  }
]

and the configuration of the OAuth2 application in Mattermost:

Is Trusted: No
Client ID: <client_id>
Client Secret: ***************
Callback URLs: http://<gitlab_host>/users/auth/Mattermost/callback
Created by test on Wednesday, March 21, 2018

Here are the Gitlab logs associated with an attempt to authorize:

==> /var/log/gitlab/gitlab-rails/production.log <==
Started POST "/users/auth/Mattermost" for 172.17.0.1 at 2018-03-21 12:44:57 +0000
Processing by Gitlab::RequestForgeryProtection::Controller#index as HTML
  Parameters: {"authenticity_token"=>"[FILTERED]"}
Completed 200 OK in 1ms (ActiveRecord: 0.0ms)

==> /var/log/gitlab/gitlab-rails/production_json.log <==
{"method":"POST","path":"/users/auth/Mattermost","format":"html","controller":"Gitlab::RequestForgeryProtection::Controller","action":"index","status":200,"duration":2.31,"view":0.0,"db":0.0,"time":"2018-03-21T12:44:57.739Z","params":{"_method":"post","authenticity_token":"[FILTERED]"},"remote_ip":null,"user_id":null,"username":null}

==> /var/log/gitlab/gitlab-rails/production.log <==
Started GET "/users/auth/Mattermost/callback?code=[FILTERED]&state=3e78b546e6874487c18207845bc68158e6fbcff86085b49f" for 172.17.0.1 at 2018-03-21 12:44:57 +0000
Processing by OmniauthCallbacksController#failure as HTML
  Parameters: {"code"=>"[FILTERED]", "state"=>"3e78b546e6874487c18207845bc68158e6fbcff86085b49f"}
Redirected to http://localhost:9090/users/sign_in
Completed 302 Found in 5ms (ActiveRecord: 0.0ms)

==> /var/log/gitlab/unicorn/unicorn_stdout.log <==
I, [2018-03-21T12:47:29.527107 #841]  INFO -- omniauth: (Mattermost) Callback phase initiated.
E, [2018-03-21T12:47:29.532019 #841] ERROR -- omniauth: (Mattermost) Authentication failure! invalid_credentials: OAuth2::Error,

==> /var/log/gitlab/gitlab-rails/production_json.log <==
{"method":"GET","path":"/users/auth/Mattermost/callback","format":"html","controller":"OmniauthCallbacksController","action":"failure","status":302,"duration":6.67,"view":0.0,"db":0.0,"location":"http://localhost:9090/users/sign_in","time":"2018-03-21T12:44:57.769Z","params":{"code":"[FILTERED]","state":"3e78b546e6874487c18207845bc68158e6fbcff86085b49f"},"remote_ip":"172.17.0.1","user_id":null,"username":null}

I do note that Gitlab never reaches out to Mattermost on the user_info_url but decides that the authentication failed from the sole interaction against /oauth/authorize. Nothing in the response from Mattermost suggests the authentication failed, so Iā€™m guessing GitLab is expecting something that Mattermost isnā€™t sending.

I might suggest reaching out to GitLab at this point for assistance, though thereā€™s a few more things Iā€™d like to try myself as well.

Have you been able to solve the problem or gather more information? Iā€™m experiencing the same problem.

Nothing new from my side. Problem is still the same. I am cosidering GitLab as main auth provider as it is better for connecting aditional apps like Jenkins with it. (Plugins for group lookup and stuff).

The non-profit that I am working for is probably going to switch to google apps for non-profits and Iā€™ll use these accounts on the gitlab oauth backend. So for my Mattermost users the flow will be:

MM -> GitLab -> Google G-Suite

Hoping that it will work as I plan it. :slight_smile:

Finally got it to work. Here is my solution:

### OmniAuth Settings
###! Docs: https://docs.gitlab.com/ce/integration/omniauth.html
gitlab_rails['omniauth_enabled'] = true
gitlab_rails['omniauth_allow_single_sign_on'] = ['oauth2_generic']
# gitlab_rails['omniauth_sync_email_from_provider'] = 'saml'
# gitlab_rails['omniauth_sync_profile_from_provider'] = ['saml']
# gitlab_rails['omniauth_sync_profile_attributes'] = ['email']
# gitlab_rails['omniauth_auto_sign_in_with_provider'] = 'saml'
gitlab_rails['omniauth_block_auto_created_users'] = false
gitlab_rails['omniauth_auto_link_ldap_user'] = false
# gitlab_rails['omniauth_auto_link_saml_user'] = false
# gitlab_rails['omniauth_external_providers'] = ['twitter', 'google_oauth2']
gitlab_rails['omniauth_providers'] = [
   {
     "name" => "oauth2_generic",
     "app_id" => "XXX",
     "app_secret" => "XXX",
     "args" => {
       client_options: {
          'site' => 'https://meeting.swsz.org',
          'authorize_url' => '/oauth/authorize',
          'token_url' => '/oauth/access_token',
          'user_info_url' => '/api/v4/users/me'
       },
       user_response_structure: {
        root_path: [],
        attributes: { name: 'first_name'+'last_name',
                      first_name: 'first_name',
                      last_name: 'last_name',
                      nickname: 'username',
                      email: 'email'
                       }
       },
       name: 'oauth2_generic',
       strategy_class: "OmniAuth::Strategies::OAuth2Generic"
}   }
 ]

I didnā€™t get it to work with name: ā€˜Mattermostā€™ as the URL mapping doesnā€™t seem to work, I always get a 404 at the callback url.

Also note that it doesnā€™t work if the mattermost username exists as a local user already. It doesnā€™t seem to sync.

Another problem that needs to be addressed is the profile editing in GitLabā€¦ the name and email should be readonly and synced from the oauth provider.

But all in all not to bad for a first start. :slight_smile:

1 Like