Captain-P-Goldfish / scim-for-keycloak

a third party module that extends keycloak by SCIM functionality
BSD 3-Clause "New" or "Revised" License
187 stars 48 forks source link

SCIM Remote User Creation Fails with 500 error #127

Open dmitry-mightydevops opened 4 days ago

dmitry-mightydevops commented 4 days ago

When I add a new user in keycloak - it issues the following POST query to remote SCIM provider that fails with 500 error

Host: example.twingate.com
POST /api/scim/v2/Users HTTP/1.1
Content-Type: application/scim+json
Authorization: Bearer  hidden

{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:User"
  ],
  "id": "0ff2dd41-9b12-40fb-9acc-4b3f9ce88c68",
  "userName": "dmitry-test1",
  "active": true,
  "name": {
    "givenName": "Dmitry",
    "familyName": "Test1"
  },
  "emails": [
    {
      "primary": true,
      "value": "dmitry+test1@example.com"
    }
  ]
}

which fails with the following error:

2024-11-09 20:22:09,747 INFO  [de.captaingoldfish.scim.sdk.keycloak.scim_client.synchrotasks.users.ScimCreateUserTask] (executor-thread-99) Failed to create user 'dmitry-test1' at remote SCIM provider 'https://example.twingate.com/api/scim/v2//Users': {
  "schemas" : [ "urn:ietf:params:scim:api:messages:2.0:Error" ],
  "status" : "500",
  "detail" : "A server error occurred."
}

The reason it fails is that twingate SCIM API expects externalId to be passed (instead of id) https://www.twingate.com/docs/scim-provisioning-api#users

The following CURL example works fine

curl -X POST "https://example.twingate.com/api/scim/v2/Users" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/scim+json" \
-d '{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:User"
  ],
  "externalId": "0ff2dd41-9b12-40fb-9acc-4b3f9ce88c68",
  "userName": "dmitry-test1",
  "name": {
    "givenName": "Dmitry",
    "familyName": "Test1"
  },
  "emails": [
    {
      "value": "dmitry+test1@example.com",
      "primary": true
    }
  ],
  "active": true
}'

{"schemas":["urn:ietf:params:scim:schemas:core:2.0:User"],"id":"VXNlcjo6ODQwODM0","externalId":"0ff2dd41-9b12-40fb-9acc-4b3f9ce88c68","userName":"dmitry-test1","name":{"givenName":"Dmitry","familyName":"Test1","formatted":"Dmitry Test1"},"displayName":"Dmitry Test1","active":true,"meta":{"resourceType":"User","created":"2024-11-09T20:31:05.216777+00:00","lastModified":"2024-11-09T20:31:05.216832+00:00","location":"https://example.twingate.com/api/scim/v2/Users/VXNlcjo6ODQwODM0"},"emails":[{"value":"dmitry+test1@example.com","primary":true,"type":"work"}]}

It doesn't look like it's possible to map them in the schema.

From customization excluded attributes

Users schema:

these options had no effect on the outcome

image

So I guess we need something like "Send local id as externalId in requests" option. Or is it possible to map to allow POSTs to created users in the remote SCIM endpoint?

dmitry-mightydevops commented 4 days ago

@Captain-P-Goldfish for now I have solved the issue with mitmproxy that overrides the payload on the fly and replace "id" field with "externalId" by using wonderful proxy feature of your plugin and custom CA certs

image

however there is bug with GUI, even that the proxy is configured properly, next page reload sets it back to image

minhtule commented 2 days ago

When testing the SCIM Client feature, I have the similar issue: not able to send Keycloak ID as the SCIM externalId attribute. The 2 options Send local id in requests and Send externalId as id in requests don't work but also seem to contradict SCIM core schema specification in RFC 7643 section 3.1

id - A unique identifier for a SCIM resource as defined by the service.

externalId - A String that is an identifier for the resource as defined by the provisioning client.

When I use SCIM Client feature in SCIM for Keycloak, Keycloak should be the provisioning client so I think it shouldn't set the SCIM id attribute.