diff --git a/authentik/providers/scim/clients/group.py b/authentik/providers/scim/clients/group.py index ec84614c8..cd974ef4c 100644 --- a/authentik/providers/scim/clients/group.py +++ b/authentik/providers/scim/clients/group.py @@ -76,7 +76,8 @@ class SCIMGroupClient(SCIMClient[Group, SCIMGroupSchema]): scim_group = SCIMGroupSchema.parse_obj(delete_none_keys(raw_scim_group)) except ValidationError as exc: raise StopSync(exc, obj) from exc - scim_group.externalId = str(obj.pk) + if not scim_group.externalId: + scim_group.externalId = str(obj.pk) users = list(obj.users.order_by("id").values_list("id", flat=True)) connections = SCIMUser.objects.filter(provider=self.provider, user__pk__in=users) diff --git a/authentik/providers/scim/clients/user.py b/authentik/providers/scim/clients/user.py index 6fe33dadd..4f79be7e0 100644 --- a/authentik/providers/scim/clients/user.py +++ b/authentik/providers/scim/clients/user.py @@ -63,7 +63,8 @@ class SCIMUserClient(SCIMClient[User, SCIMUserSchema]): scim_user = SCIMUserSchema.parse_obj(delete_none_keys(raw_scim_user)) except ValidationError as exc: raise StopSync(exc, obj) from exc - scim_user.externalId = str(obj.uid) + if not scim_user.externalId: + scim_user.externalId = str(obj.uid) return scim_user def _create(self, user: User): diff --git a/website/docs/providers/scim/index.md b/website/docs/providers/scim/index.md index 5491ffd84..1b47f919f 100644 --- a/website/docs/providers/scim/index.md +++ b/website/docs/providers/scim/index.md @@ -42,3 +42,17 @@ SCIM defines multiple optional features, some of which are supported by the SCIM - Patch updates If the service provider supports patch updates, authentik will use patch requests to add/remove members of groups. For all other updates, such as user updates and other group updates, PUT requests are used. + +### Using in conjunction with other providers + +A lot of applications support SCIM in conjunction with another SSO protocol like OAuth/OIDC or SAML. With default settings, the unique user IDs in SCIM and other protocols are identical, which should easily allow applications to link users the are provisioned with users that are logging in. + +Applications can either match users on a unique ID sent by authentik called `externalId`, by their email or username. + +#### OAuth/OIDC + +The default provider configuration for the _Subject mode_ option of _Based on the User's hashed ID_ matches the `externalId` that's generated by default. If any other _Subjet mode_ is selected, the `externalId` attribute can be customized via SCIM mappings. + +#### SAML + +The SAML NameID policy _urn:oasis:names:tc:SAML:2.0:nameid-format:persistent_ uses the same unique user identifier as the default `externalId` value used by the SCIM provider. If a SAML application does not send a NameID request, this value is also used as fallback.