SCIM Endpoint

Advanced-UI

The SCIM Endpoint plugin is an API for managing users and the groups in CELUM. The plugin implements version 2.0 of the SCIM protocol.

Properties

To be configured in {home}/appserver/conf/custom.properties

scimEndpoint.license

type: String, required: yes, default: -

The license key for the plugin (product: scimEndpoint), provided by brix.

scimEndpoint.tokenVerifier

type: bean name, required: yes, default: -

Determines which Authentication method is applied (scimStaticTokenVerifier or scimJsonWebTokenVerifier).

scimEndpoint.staticToken

type: String, required: yes (if applied), default: -

Simple static token for scimStaticTokenVerifier.

scimEndpoint.jwtSecretKey

type: String, required: yes (if applied), default: -

The secret key for scimJsonWebTokenVerifier (at least 256 bits!)

scimEndpoint.delete

type: boolean, required: no, default: false

Determines whether a user is deleted or deactivated in case of a DELETE request.

scimEndpoint.notVisibleUser

type: List of long (comma-separated), required: no, default: -

A list of users who will be excluded from CRUD operations.

scimEndpoint.notDeletableUser

type: List of long (comma-separated), required: no, default: -

A list of users who are not deletable.

scimEndpoint.userKindDefault

type: String, required: no, default: readonly

Sets the userKind if no userType is transmitted.

scimEndpoint.notVisibleGroup

type: List of long (comma-separated), required: no, default: -

A list of groups who will be excluded from CRUD operations.

scimEndpoint.notDeletableGroup

type: List of long (comma-separated), required: no, default: -

A list of groups who are not deletable.

Request Header

To access the SCIM API a Bearer Token is required. The API token must be included via an Authentication/Authorization header** with a type of Bearer when calling any of the SCIM methods. Alternatively, a static token can be provided in the token parameter.

The http Content-Type header has to be set to application/scim+json.

SCIM Resource Endpoints

The base URL for all calls to the SCIM API is https://example.com/scim/v2. All SCIM methods are branches of this base URL.

The following Endpoints are available:

Service Provider Configuration Endpoints

GET /ServiceProviderConfig

  • Returns the SCIM specification features.

GET /ResourceTypes

  • Returns the types of resources available.

GET /Schemas

  • Returns information about resource schemas.

User

GET POST PUT PATCH DELETE /Users

  • For GET requests a standard set of query parameters is available ( see Query Resources).
    • Since the ID is of type string, sorting to this attribute is limited.
  • Since Celum does not have a lastModified date for users, the created date is returned in meta.lastModified.

User attributes

The following table maps SCIM attributes to CELUM User attributes.

CELUM SCIM Remarks
ID id required
External ID externalId
Username userName required
Password password
Last name name.familyName
First name name.givenName
Middle name name.middleName
Deactivated active Default value for POST is active.
Userkind userType Valid values are readonly, editor or readwrite. Defaul value is readonly and can be configured.
E-mail emails[value][primary][type=work]
Phone phoneNumbers[value][type=work] type is required
Mobile phoneNumbers[value][type=mobile] type is required
Fax phoneNumbers[value][type=fax] type is required
Street addresses[streetAddress][primary][type=work]
Zip addresses[postalCode][primary][type=work]
City addresses[locality][primary][type=work]
Country addresses[country][primary][type=work]
User Groups groups Group membership changes MUST be applied via the "Group" Resource
Created meta.created

GET /Schemas/urn:ietf:params:scim:schemas:core:2.0:User returns all user attributes and their characteristics that describe their type and handling.

All attributes must be transmitted in a PUT request. Not required attributes that are missing or empty are usually deleted in Celum. Exceptions:

  • Password: will not be deleted
  • Deactivated and Userkind: no changes

If multiple emails/addresses are transmitted, one must be marked as primary. Otherwise, no one will be stored in Celum in a POST request and no updated is done in a PUT request.

Example for GET

Full User Representation

{
  "id": "170",
  "externalId": "externalID",
  "userName": "Test_User_1",
  "name": {
    "familyName": "Mustermann",
    "givenName": "Max",
    "middleName": "D."
  },
  "active": true,
  "emails": [
    {
      "value": "m.mustermann@email.ch",
      "type": "work"
    }
  ],
  "phoneNumbers": [
    {
      "value": "061 266 66 66",
      "type": "work"
    },
    {
      "value": "079 266 66 66",
      "type": "mobile"
    },
    {
      "value": "061 266 66 11",
      "type": "fax"
    }
  ],
  "addresses": [
    {
      "streetAddress": "Musterstrasse 1",
      "locality": "Binningen",
      "postalCode": "4102",
      "country": "Schweiz",
      "type": "work"
    }
  ],
  "groups": [
    {
      "value": "149",
      "$ref": "http://localhost:8881/scim/v2/Groups/149",
      "display": "Admin_Group",
      "type": "Group"
    },
    {
      "value": "7",
      "$ref": "http://localhost:8881/scim/v2/Groups/7",
      "display": "Marketing",
      "type": "Group"
    },
    {
      "value": "126",
      "$ref": "http://localhost:8881/scim/v2/Groups/126",
      "display": "Test_Group_1",
      "type": "Group"
    }
  ],
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:User"
  ],
  "meta": {
    "resourceType": "User",
    "created": "2021-04-14T13:45:31.787Z",
    "lastModified": "2021-04-14T13:45:31.787Z",
    "location": "http://localhost:8881/scim/v2/Users/170"
  }
}

Example for POST (create new user)

Full User Representation

{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:User"
  ],
  "externalId": "externalID",
  "userName": "Test_User_1",
  "password": "123456789A!",
  "name": {
    "familyName": "Mustermann",
    "givenName": "Max",
    "middleName": "D."
  },
  "active": true,
  "userType": "editor",
  "emails": [
    {
      "value": "m.mustermann@email.ch",
      "primary": true
    },
    {
      "value": "m.muster@email.ch"
    }
  ],
  "phoneNumbers": [
    {
      "value": "061 266 66 66",
      "type": "work"
    },
    {
      "value": "061 266 66 11",
      "type": "fax"
    },
    {
      "value": "079 266 66 66",
      "type": "mobile"
    }
  ],
  "addresses": [
    {
      "streetAddress": "Musterstrasse 1",
      "locality": "Binningen",
      "postalCode": "4102",
      "country": "Schweiz",
      "primary": true
    },
    {
      "streetAddress": "Musterstrasse 2",
      "locality": "Binningen",
      "postalCode": "4102",
      "country": "Schweiz"
    }
  ]
}

Minimal User Representation

{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:User"
  ],
  "userName": "Test_User_1",
  "name": {
    "familyName": "Mustermann"
  }
}

Group

GET POST PUT PATCH DELETE /Groups

  • For GET requests a standard set of query parameters is available ( see Query Resources).
    • Since the ID is of type string, sorting to this attribute is limited.
  • Since Celum does not have a created or lastModified date for groups, "1970-01-01T00:00:00.000Z" is returned in meta.created and meta.lastModified.

Group attributes

The following table maps SCIM attributes to CELUM Usergroup attributes.

CELUM SCIM Remarks
ID id reqiured
External ID externalId
Name displayName required
ID members[value]
Username/Name members[display]
Discriminator members[type]

GET /Schemas/urn:ietf:params:scim:schemas:core:2.0:Group returns all group attributes and their characteristics that describe their type and handling.

Example for GET (full usergroup representation)

{
  "id": "186",
  "externalId": "externalID",
  "displayName": "Test_Group_2",
  "members": [
    {
      "value": "40",
      "$ref": "http://localhost:8881/scim/v2/Users/40",
      "display": "editor2",
      "type": "User"
    },
    {
      "value": "43",
      "$ref": "http://localhost:8881/scim/v2/Users/43",
      "display": "editor3",
      "type": "User"
    },
    {
      "value": "44",
      "$ref": "http://localhost:8881/scim/v2/Users/44",
      "display": "readonly3",
      "type": "User"
    },
    {
      "value": "8",
      "$ref": "http://localhost:8881/scim/v2/Groups/8",
      "display": "World",
      "type": "Group"
    }
  ],
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:Group"
  ],
  "meta": {
    "resourceType": "Group",
    "created": "1970-01-01T00:00:00.000Z",
    "lastModified": "1970-01-01T00:00:00.000Z",
    "location": "http://localhost:8881/scim/v2/Groups/186"
  }
}

Example for POST (create new usergroup)

Full Usergroup Representation

{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:Group"
  ],
  "externalId": "externalID",
  "displayName": "Test_Group_2",
  "members": [
    {
      "value": "40",
      "type": "User"
    },
    {
      "value": "42",
      "type": "User"
    },
    {
      "value": "7",
      "type": "Group"
    }
  ]
}

Minimal Usergroup Representation

{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:Group"
  ],
  "displayName": "Test_Group_3"
}

Further Endpoints

POST /Bulk

  • The SCIM bulk operation enables clients to send a potentially large collection of resource operations in a single request.

POST [prefix]/.search

  • Clients MAY execute queries without passing parameters on the URL by using the HTTP POST verb combined with the " /.search" path extension.

Implementations

Azure

  1. Create an Enterprise Application: Azure Active Directory --> Enterprise applications --> Create your own application --> Non-gallery
  2. Set Admin Credentials: Application --> Provisioning --> Update credentials --> Admin Credentials
    • Provisioning Mode = Automatic
    • Tenant URL (https://example.com/scim/v2)
    • Secret Token (provided by brix)
  3. Adapt mappings: Application --> Provisioning --> Edit attribute mappings --> Mappings
    • See mapping tables below
    • Configure the settings as needed
    • Change customappsso attributes: Show advanced options --> Edit attribute list for customappsso
    • Change mappings
    • Delete all unused customappsso attributes and mappings.

The mapping must be deleted before you can edit/delete the customappsso attributes.

  1. Set Scope (if needed): Application --> Provisioning --> Add scoping filters --> Settings --> Scope
    • Sync only assigned users and groups
  2. Assign users/groups (if needed): Application --> Users and groups --> Add user/groups (groups only available in enterprise/premium azure)

User Mapping

Azure Active Directory Attribute customappsso Attribute Type Remarks
- id String primary key, required
userPrincipalName userName String required
Switch([IsSoftDeleted], , "False", "True", "True", "False") active Boolean
mail emails[type eq "work"].value String
givenName name.givenName String
surname name.familyName String
streetAddress addresses[type eq "work"].streetAddress String
city addresses[type eq "work"].locality String
telephoneNumber phoneNumbers[type eq "work"].value String
mobile phoneNumbers[type eq "mobile"].value String
facsimileTelephoneNumber phoneNumbers[type eq "fax"].value String
mailNickname externalId String
postalCode addresses[type eq "work"].postalCode String
country addresses[type eq "work"].country String

Group Mapping

No changes need to be made to the default mapping for groups.

Azure Active Directory Attribute customappsso Attribute Type Remarks
- id String primary key, required
objectId externalId String
displayName displayName String required
members members Reference urn:ietf:params:scim:schemas:core:2.0:Group
urn:ietf:params:scim:schemas:extension:enterprise:2.0:User

Known Limitations

see Link

Tenant URL
Use the flags below in the tenant URL of your application in order to change the default SCIM client behavior. <base-url>/?aadOptscim062020 (e.g. https://example.com/scim/v2/?aadOptscim062020)

Null attribute can't be provisioned
Azure AD currently can't provision null attributes. If an attribute is null on the user object, it will be skipped (Link).

Remove user from synced group
If a user is no longer in a synced group, Azure will not send a DELETE, but only a PATCH with active = false. Thus, the user is only deactivated in Celum (Link)

Delete user
When a user is deleted, Azure apparently only softDelets it first. This leads to a PATCH/PUT with active = false (Link). Here you have to delete the user permanently so that Azure sends a DELETE request.

userName softDeletion
Azure prefixes the userName with the ObjectID during softDeletion. This can lead to the userName being too long for Celum, which is why the user cannot be deactivated.

Compatibility Matrix

SCIM Endpoint CELUM (min. version)
1.0 6.4.0
1.0.3 6.4 (tested with 6.11)
1.2.2 6.4 (tested with 6.11)

Release Notes

1.0.0

Release: 2021-04-23

Initial Version

1.0.3

Release: 2022-01-28

  • default value for lastName
  • changed name.familyName to not required
  • changed member.type to not required

1.2

Release: 2024-03-07

added type 'work' to emails and addresses