0x02 如何将Gitlab私有仓库对接内部Oauth2服务实现统一登录认证
前言简述
看过最近一段时间作者发布的文章的看友应该了解,最近笔者将企业中部署的业务系统(例如,Moodle、zyplayer-doc、Grafana)都对接到企业内部开发的OAuth2服务上,实现了企业内部多个业务、应用系统统一登录认证,并以此实现单点登陆(PS: SSO,SingleSignOn 通常包含在认证中),通常情况下统一身份认证服务平台一般包含以下几个部分:
• 账号管理:常见有 AD/LDAP 或者使用关系型数据库 MySQL/PostgreSQL 等
• 认证管理:常见有 OAuth,OpenID Connect,SAML,CAS 等
• 授权管理:通常包含 RBAC(基于角色的访问控制)、ABAC(基于属性的访问控制)等。
• 审计监控:通常包含审计日志、监控告警等。
- GitLab 是一个全球知名的一体化 DevOps 平台,国内许多企业都通过私有化部署 GitLab 来进行源代码托管,其分为社区版和商业版,社区版是完全开源免费的,商业版则在社区版的基础上增加了更多的企业级特性。
Gitlab 支持多种身份验证方式,包括 SAML、LDAP(Active Directory, Apple Open Directory, Open LDAP, and 389 Server)、OAuth2(Google、Github、Microsoft Azure、自开发提供商)、JWT等。它是通过 OmniAuth 提供这种认证的 Rack 框架, 配置后登录页面会显示额外的登录选项,GitLab 支持以下表中的 OmniAuth 提供者。
| Provider documentation | OmniAuth provider name |
|---|---|
| AliCloud | alicloud |
| Atlassian | atlassian_oauth2 |
| Auth0 | auth0 |
| AWS Cognito | cognito |
| Azure v2 | azure_activedirectory_v2 |
| Bitbucket Cloud | bitbucket |
| Generic OAuth 2.0 | oauth2_generic |
| GitHub | github |
| GitLab.com | gitlab |
google_oauth2 |
|
| JWT | jwt |
| Kerberos | kerberos |
| OpenID Connect | openid_connect |
| Salesforce | salesforce |
| SAML | saml |
| Shibboleth | shibboleth |
后续将以 oauth2_generic 为例进行对接内部使用 Golang 开发的 OAuth2 认证授权服务,OAuth 是一种开放标准协议,允许用户提供一个网站或应用程序访问另一个在其上托管数据的网站的权限,而无需将用户名和密码提供给第三方。例如,用户在登录一个网站时,可以使用 Google、Facebook 或其他 OAuth 提供者的帐户进行身份验证,然后允许授权服务器在资源所有者或最终用户的批准下向第三方客户端颁发访问令牌。
温馨提示:对于有相同环境、需求的读者,可以参考这两篇文章。
- • Moodle | 开源学习管理系统 OAuth2 服务对接配置• Grafana | 如何对接内部 OAuth2 身份验证服务,实现单点登录(SSO)
好了,废话不多说,直接进入今天的主题。
实践操作
步骤 01.作者将以前面部署的 GitLab 17.8 版本为进行实践,如何安装 GitLab 就不赘述了,可参考《GitLab | 企业私有代码仓库介绍与快速安装部署》文章。
特别注意:Gitlab 版本迭代较快,目前最新已经是 v19.1,由于不同版本之间配置有些许差异,所以请根据实际情况选择对应版本的文档进行参考操作,当下 v17.8 版本的文档进行归档了,对于已经归档的版本需访问 Offline archives 下载 Docker 离线档案进行本地部署,之后访问 http://docker部署的IP地址及端口/17.8/ee/administration/auth/ 进行查阅。
GITLAB_ARCHIVES = "17.8"
docker run -it --rm -p 4000:4000 registry.gitlab.com/gitlab-org/gitlab-docs/archives:${GITLAB_ARCHIVES}
步骤 02.在配置 OmniAuth 提供商 oauth2_generic 之前,请先配置所有提供商通用的设置。
• enabled: 是否启用 OmniAuth 提供商。(必须)
• allow_bypass_two_factor: 是否允许用户使用指定的提供商登录,而无需进行双因素身份验证 (2FA)。(可选)
• allow_single_sign_on: 是否在使用 OmniAuth 登录时启用账户的自动创建功能。(必须)
• auto_link_user: 允许通过 OmniAuth 提供商进行身份验证的用户,如果其电子邮件匹配,则会自动关联到当前的 GitLab 用户。(推荐)
• auto_link_ldap_user:为通过 OmniAuth 提供商创建的用户在 GitLab 中创建 LDAP 身份,但必须使用 LDAP 集成。
• auto_link_saml_user:如果用户的电子邮件匹配,允许通过 SAML 提供商进行身份验证的用户将自动关联到当前的 GitLab 用户。
• auto_sign_in_with_provider:允许用户使用单个提供商名称自动登录,例如:oauth2_generic,(必须)
• block_auto_created_users:是否系统会将自动创建的用户置于待批准状态(无法登录),直至管理员批准。(必须)
• providers: 提供程序名称在支持的提供程序表中可用。(必须)
• external_providers: 允许您定义要作为外部的OmniAuth提供程序,以便所有创建帐户或通过这些提供程序登录的用户都无法访问内部项目。(可选)
• sync_profile_attributes: 是否在用户首次登录时同步提供商的配置文件属性。(可选)
• sync_profile_from_provider: GitLab应自动同步配置文件信息的提供者名称列表。(可选)
然后编辑 /etc/gitlab/gitlab.rb 文件,添加以下配置,其中 omniauth_ 拼接的参数就是上面提到的通用设置。
gitlab_rails['omniauth_enable'] = true
gitlab_rails['omniauth_allow_single_sign_on'] = ['saml', 'google_oauth2']
gitlab_rails['omniauth_auto_link_ldap_user'] = true
gitlab_rails['omniauth_block_auto_created_users'] = true
# oauth2_generic 作为单点登录提供商配置示例
gitlab_rails['omniauth_providers'] = [
{
name: "oauth2_generic",
label: "Provider name", # optional label for login button, defaults to "Oauth2 Generic"
app_id: "<your_app_client_id>",
app_secret: "<your_app_client_secret>",
args: {
client_options: {
site: "<your_auth_server_url>",
user_info_url: "/oauth2/v1/userinfo",
authorize_url: "/oauth2/v1/authorize",
token_url: "/oauth2/v1/token"
},
user_response_structure: {
root_path: [],
id_path: ["sub"],
attributes: {
email: "email",
name: "name"
}
},
authorize_params: {
scope: "openid profile email"
},
strategy_class: "OmniAuth::Strategies::OAuth2Generic"
}
}
]
步骤 03.在内部 OAuth2 服务管理平台中为 Gitlab 创建客户端,注册应用程序时提供的重定向 URI 应为 http://your-gitlab.host.com/users/auth/oauth2_generic/callback,最后并获取 client_id 和 client_secret。
温馨提示:若需要使用 Golang 开发企业内部的 OAuth2 服务认证代码的读者可加入到作者知识星球中获取哟。
步骤 04.登陆 Gitlab 服务器,根据实际情况添加修改 omniauth 相关配置,保存文件并重新配置 GitLab。
$ vim /etc/gitlab/gitlab.rb
.....
# 启用第三方认证
gitlab_rails['omniauth_enabled'] = true
# 允许通过 oauth2_generic 登录
gitlab_rails['omniauth_allow_single_sign_on'] = ["oauth2_generic"]
# 允许自动创建用户但是需要管理员审核后才可以使用
gitlab_rails['omniauth_block_auto_created_users'] = true
# 允许自动关联用户
gitlab_rails['omniauth_auto_link_user'] = ["oauth2_generic"]
gitlab_rails['omniauth_providers'] = [
{
name: "oauth2_generic", # 指定提供商名称,此处为 oauth2_generic
label: "统一登陆认证平台", # 登录按钮显示的名称
app_id: "019e6ca6-ab*****2c4e97d5b23", # 申请的客户端ID
app_secret: "a4dfaaa9*****e8dad836e89b4", # 申请的客户端密钥
args: {
client_options: {
site: "https://auth.weiyigeek.top", # 认证服务域名
user_info_url: "/api/v2/general/userinfo", # 认证服务获取用户信息的接口地址,此处为自定义的接口路径
authorize_url: "/oauth/authorize", # 认证服务授权地址
token_url: "/oauth/token", # 认证服务获取 Token 的接口地址
auth_scheme: "request_body"# 默认为 header 中包含 Token,此处改为request_body
},
user_response_structure: {
root_path: [], # 用户信息的根路径,此处为空数组
id_path: ["sub"], # 用户信息的唯一标识路径,此处为 sub 字段
attributes: {
email: "email", # 用户信息的邮箱字段映射
name: "name", # 用户信息的名称字段映射
nickname: "user"# 用户信息的登陆用户名字段映射
}
},
authorize_params: {
scope: "openid profile email"# 授权范围参数,此处为 openid profile email
},
strategy_class: "OmniAuth::Strategies::OAuth2Generic"# 指定使用的 OmniAuth 策略类
}
}
]
# 保存后,重新配置 GitLab
sudo gitlab-ctl reconfigure
温馨提示:若要是自定义设置icon图标,可以使用 base64 -w 0 <logo.png> 命令将图片转换为单行 base64 编码,然后将其赋值给 icon 字段。
gitlab_rails['omniauth_providers'] = [
{
name: '...'
icon: 'data:image/png;base64,<base64-data>'
...
}
...
]
步骤 05. 配置完成后,在 GitLab 登录页面上应该会出现一个新的登录按钮。
步骤 06.点击该按钮后,将重定向到认证服务进行身份验证,成功后会请求获取 Token 以及 用户端点信息,该用户信息端点需要返回的json 参数格式如下所示。
lastname, firstname := util.SplitChineseName(uu.Name)
c.JSON(http.StatusOK, gin.H{
"sub": uu.Id,
"user_id": uu.Number,
"user": uu.UserName,
"name": uu.Name,
"given_name": firstname,
"family_name": lastname,
"phone_number": uu.Mobile,
"email": uu.Email,
"group": uu.GroupId,
})
步骤 07.然后自动关联或创建用户并登录 GitLab 平台中,例如:从用户信息接口返回的邮箱信息已经在 Gitlab 平台中存在,则会直接关联。
步骤 08.若需要取消 OAuth2 身份认证,管理员可在设置>>通用>>登陆限制中,【启用 OAuth 身份验证源】取消勾选统一登陆认证平台,并且设置退出页面URL,例如 https://auth.weiyigeek.top/logout?redirect_uri=https://git.weiyigeek.top,以清除OAuth 缓存的会话信息。
至此,作者完成 Gitlab 私有仓库多种登陆认证介绍方式和通用 OAuth 提供商的设置,并解决了在对接内部 OAuth 认证服务登录过程中遇到的常见问题,ok 就分享到这里,希望对你有所帮助,希望大家能多多支持我,谢谢!
入坑出坑
问题1.使用 OAuth2Generic 登录时,提示 "client authentication failed" 错误
错误信息:
Could not authenticate you from OAuth2Generic because "Invalid client: client authentication failed {"error":"invalid client","error description":"client authentication failed"} ".
解决思路:请检认证服务是否正常,其次验证 client_id 和 client_secret 是否正确填写,最后根据 Token 方式的不同,可能需要调整 auth_scheme 参数。
client_options: {
......
auth_scheme: "request_body"# 默认为 header 中包含 Token,由于我是 body 返回的则 改为 request_body
},
问题2.使用 OAuth2Generic 登录时,提示 "pre-existing account in git.weiyigeek.top is not allowed." 错误
错误信息:
Signing in using your 统一登陆认证平台 account without a pre-existing account in git.weiyigeek.top is not allowed.
解决思路:设置允许通过 oauth2_generic 提供商自动登录。
gitlab_rails['omniauth_allow_single_sign_on'] = ["oauth2_generic"]
问题3.使用 OAuth2Generic 登录时,提示 Your account is pending approval from your GitLab administrator and hence blocked
Your account is pending approval from your GitLab administrator and hence blocked. Please contact your GitLab administrator if you think this is an error.
问题原因:由于 gitlab_rails['omniauth_block_auto_created_users'] 设置为 true,所以当未关联到用户时,用户会被自动创建并被阻塞。
解决办法:在管理员界面手动审核批注通过。
参考来源:
- • https://docs.gitlab.com/19.0/integration/omniauth/• https://zhuanlan.zhihu.com/p/691887010
温馨提示:若文章代码块中存在乱码或不能复制,请联系作者,也可通过文末的阅读原文链接,加入知识星球中阅读。
275