mirror of
https://github.com/goauthentik/authentik.git
synced 2026-06-17 19:09:11 +03:00
providers/scim: Add GitLab compatibility mode (#22906)
* providers/scim: Add GitLab compatibility mode Add a GitLab SCIM compatibility mode that skips ServiceProviderConfig probing and document when to use it. Also wrap non-JSON SCIM responses so providers that return HTML redirects fall back through the existing ServiceProviderConfig default path. Agent-thread: https://sdko.org/internal/thr/per/019ea36a-92dd-7651-8a2d-0d838e724a7d A7k-product: product A7k-product-repo: 1 Co-authored-by: Agent <agent@svc.sdko.net> * providers/scim: Fold GitLab mode into existing migration Agent-thread: https://sdko.org/internal/thr/ak/019ea7bd-ce63-77a2-90d6-5dcc25d4402d A7k-product: product A7k-product-repo: 2 Co-authored-by: Agent <agent@svc.sdko.net> --------- Co-authored-by: Agent <agent@svc.sdko.net>
This commit is contained in:
@@ -5,7 +5,7 @@ from typing import TYPE_CHECKING
|
||||
from django.core.cache import cache
|
||||
from django.http import HttpResponseBadRequest, HttpResponseNotFound
|
||||
from pydantic import ValidationError
|
||||
from requests import RequestException, Session
|
||||
from requests import JSONDecodeError, RequestException, Session
|
||||
|
||||
from authentik.lib.sync.outgoing import (
|
||||
HTTP_CONFLICT,
|
||||
@@ -84,7 +84,10 @@ class SCIMClient[TModel: "Model", TConnection: "Model", TSchema: "BaseModel"](
|
||||
raise SCIMRequestException(response)
|
||||
if response.status_code == HTTP_NO_CONTENT:
|
||||
return {}
|
||||
try:
|
||||
return response.json()
|
||||
except JSONDecodeError as exc:
|
||||
raise SCIMRequestException(message="Failed to decode SCIM response") from exc
|
||||
|
||||
def get_service_provider_config(self):
|
||||
"""Get Service provider config"""
|
||||
@@ -97,7 +100,10 @@ class SCIMClient[TModel: "Model", TConnection: "Model", TSchema: "BaseModel"](
|
||||
if cached_config is not None:
|
||||
return cached_config
|
||||
|
||||
if self.provider.compatibility_mode == SCIMCompatibilityMode.VCENTER:
|
||||
if self.provider.compatibility_mode in [
|
||||
SCIMCompatibilityMode.GITLAB,
|
||||
SCIMCompatibilityMode.VCENTER,
|
||||
]:
|
||||
return default_config
|
||||
|
||||
# Attempt to fetch from remote
|
||||
|
||||
@@ -93,6 +93,7 @@ class Migration(migrations.Migration):
|
||||
("aws", "AWS"),
|
||||
("slack", "Slack"),
|
||||
("sfdc", "Salesforce"),
|
||||
("gitlab", "GitLab"),
|
||||
("webex", "Webex"),
|
||||
("vcenter", "vCenter"),
|
||||
],
|
||||
|
||||
@@ -83,6 +83,7 @@ class SCIMCompatibilityMode(models.TextChoices):
|
||||
AWS = "aws", _("AWS")
|
||||
SLACK = "slack", _("Slack")
|
||||
SALESFORCE = "sfdc", _("Salesforce")
|
||||
GITLAB = "gitlab", _("GitLab")
|
||||
WEBEX = "webex", _("Webex")
|
||||
VCENTER = "vcenter", _("vCenter")
|
||||
|
||||
|
||||
@@ -88,6 +88,18 @@ class SCIMClientTests(TestCase):
|
||||
self.assertEqual(mock.call_count, 1)
|
||||
self.assertEqual(mock.request_history[0].method, "GET")
|
||||
|
||||
def test_config_non_json_response(self):
|
||||
"""Test non-JSON config response falls back to defaults"""
|
||||
with Mocker() as mock:
|
||||
mock.get(
|
||||
"https://localhost/ServiceProviderConfig",
|
||||
text="<html></html>",
|
||||
headers={"Content-Type": "text/html"},
|
||||
)
|
||||
SCIMClient(self.provider)
|
||||
self.assertEqual(mock.call_count, 1)
|
||||
self.assertEqual(mock.request_history[0].method, "GET")
|
||||
|
||||
def test_scim_sync(self):
|
||||
"""test scim_sync task"""
|
||||
scim_sync.send(self.provider.pk).get_result()
|
||||
|
||||
@@ -11226,6 +11226,7 @@
|
||||
"aws",
|
||||
"slack",
|
||||
"sfdc",
|
||||
"gitlab",
|
||||
"webex",
|
||||
"vcenter"
|
||||
],
|
||||
|
||||
@@ -21,6 +21,7 @@ export const CompatibilityModeEnum = {
|
||||
Aws: "aws",
|
||||
Slack: "slack",
|
||||
Sfdc: "sfdc",
|
||||
Gitlab: "gitlab",
|
||||
Webex: "webex",
|
||||
Vcenter: "vcenter",
|
||||
UnknownDefaultOpenApi: "11184809",
|
||||
|
||||
@@ -36608,6 +36608,7 @@ components:
|
||||
- aws
|
||||
- slack
|
||||
- sfdc
|
||||
- gitlab
|
||||
- webex
|
||||
- vcenter
|
||||
type: string
|
||||
|
||||
@@ -121,6 +121,7 @@ Available compatibility modes are:
|
||||
- **AWS**: Disables PATCH operations for AWS Identity Center compatibility
|
||||
- **Slack**: Enables filtering support for Slack's SCIM implementation
|
||||
- **Salesforce**: Uses the non-standard `/ServiceProviderConfigs` endpoint
|
||||
- **GitLab**: Skips the `ServiceProviderConfig` endpoint because GitLab's SCIM implementation does not expose it
|
||||
- **Webex**: Uses the vendor-specific behavior required for Webex SCIM
|
||||
- **vCenter**: Skips the `ServiceProviderConfig` endpoint, which is not implemented in VMware vCenter
|
||||
|
||||
|
||||
@@ -161,3 +161,27 @@ For further GitLab provider arguments, check the [GitLab docs](https://docs.gitl
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## SCIM provisioning _(optional)_
|
||||
|
||||
GitLab self-managed instances expose SCIM endpoints for user and group provisioning when SCIM is enabled in GitLab. Use the SCIM API endpoint URL and token shown in GitLab's SCIM configuration.
|
||||
|
||||
### Create a SCIM provider
|
||||
|
||||
1. Log in to authentik as an administrator and open the authentik Admin interface.
|
||||
2. Navigate to **Applications** > **Providers** and click **Create**.
|
||||
3. Select **SCIM Provider** as the provider type and click **Next**.
|
||||
4. Enter the following values:
|
||||
- **Name**: Choose a descriptive name.
|
||||
- **URL**: Paste the SCIM API endpoint URL from GitLab.
|
||||
- **Token**: Paste the SCIM token from GitLab.
|
||||
- **Compatibility Mode**: Select **GitLab**.
|
||||
5. Click **Finish** to save the provider.
|
||||
|
||||
### Add the SCIM provider to your application
|
||||
|
||||
1. Log in to authentik as an administrator and open the authentik Admin interface.
|
||||
2. Navigate to **Applications** > **Applications** and select your GitLab application.
|
||||
3. Click **Edit**.
|
||||
4. In the **Backchannel Providers** field, select the SCIM provider you created.
|
||||
5. Click **Update** to save the application.
|
||||
|
||||
Reference in New Issue
Block a user