前几天我把科协的 Git9 从自编译的 11.1.1 一路升级到 16.8.0, 中途遇到了一些问题, 找了不少资料也解决不了, 因此放在这里.

Days ago, I upgraded Gitlab CE of SAST from 11.1.1 along the Upgrade Pathway to version 16.8.0, the latest version. I encountered some problems, which I cannot solve even after searching New Bing, Google and the official docs. Finally I got it working by debugging our OAuth server and the oauth2-generic gem. I’ll list my findings here.

A few years ago, my seniors wrote a custom gem to complete the OAuth steps with Accounts9, our OAuth identity provider. Due to this, they had to use a self-compiled version of Gitlab. Upgrading that version of Gitlab requires manual upgrades to Ruby, Postgresql, and so on, thus making the instance unmaintainable.

To upgrade it to the latest version, I thought of one way much simpler: I made a full backup, set up a virtual machine with Ubuntu 22.04 LTS and installed Gitlab 11.1.1 (exactly the same version!) there. After restoring the backup, I am able to upgrade it to 16.8.0, step by step.

Now that I have a usable Gitlab instance, it’s time to migrate the OAuth authorization method.

Using Omnibus Gitlab, there isn’t a way to install a custom OAuth method. However, I do find two possible ways:

Patching gem directly

OAuth gems are located at /opt/gitlab/embedded/lib/ruby/gems/3.1.0/gems/omniauth-*. You can choose one (preferably, omniauth-oauth2-generic) and replace it with your own gem.

However I really DO NOT THINK THIS WAY IS RECOMMENDED.

Using omniauth-oauth2-generic

omniauth-oauth2-generic is a generic OAuth2 strategy provider, but its feature is pretty unclear.

By default (starting from approximately Gitlab 15.4.6), omniauth-oauth2-generic passes client_id and client_secret in Authorizaiton header.

1
Authorization: Basic base64_encode(client_id:client_secret)

And passes auth_token in Authorization header:

1
Authorization: Bearer auth_token

So, if you encounter the following error or something like that, remember to check if your OAuth provider supports passing client_id and client_secret via basic auth:

snakyhash::stringkeyed error=’no client secret’

To solve this, check client.rb of oauth2 and its changelog. In short, add conf:

1
auth_scheme = "request_body"

Alternatively, if modifying your OAuth provider is more of convenience (just like what I did, ) add a line to decode client_id and client_secret from basic auth.


And a most confusing step: If your OAuth provider do not support passing auth_token by bearer, Gitlab WILL NOT WARN YOU about the auth failure. Instead, it just shows a 422 page, saying “User e-mail cannot be blank”.

To move it back to header, I traced to access_token.rb and there is a setting to move it to body or query, but I didn’t test how exactly it works.