SCIM 2.0

The User Management Service is based on the SCIM 2.0 protocol which is a RESTful protocol for user and resource management.

Up to three resource types are currently exposed by Curity, depending on how the user management profile has been configured. Every resource is represented with a unique ID, and retrieving a resource is a simple GET operation.

Users

After having configured a user account data source on your user management profile, the /Users endpoint will be made available under your user management endpoint.

Retrieving a user with GET

Listing 166 Getting a user by ID
GET /um/Users/VVNFUjowODM2Mjg5MGE4ZTQ0YTA3YTRlOWIzNjhhYmM5ZGNhYg HTTP/1.1
Host: login.example.com
Authorization: Bearer 21b652ed-5906-451a-a2a2-681bf099dba7
Accept: application/scim+json
Listing 167 Response from SCIM with a single User resource
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
    "active": true,
    "userName": "teddie",
    "phoneNumbers": [
        {
            "value": "456-555-555",
            "primary": true
        }
    ],
    "emails": [
        {
            "value": "teddie@example.com",
            "primary": true
        }
    ],
    "meta": {
        "resourceType": "User",
        "created": "1970-01-01T00:02:03Z",
        "lastModified": "1970-01-01T00:20:34Z",
        "location": "https://login.example.com/um/Users/VVNFUjowODM2Mjg5MGE4ZTQ0YTA3YTRlOWIzNjhhYmM5ZGNhYg"
    },
    "schemas": [
        "urn:ietf:params:scim:schemas:core:2.0:User"
    ],
    "name": {
        "familyName": "Bear",
        "givenName": "Ted"
    },
    "id": "VVNFUjowODM2Mjg5MGE4ZTQ0YTA3YTRlOWIzNjhhYmM5ZGNhYg"
}

Searching for a user

Each resource has a server assigned ID. For a user this is not necessarily the same ID as the username. Therefore, it may be required to search for the user instead of performing a GET directly. In SCIM 2.0, a search can be done directly on the Users endpoint as a query, or if sensitive data is sent as search parameters, the query can be posted to the .search endpoint under users.

Example of a search query towards the .search endpoint

Listing 168 Finding a user by username using GET
GET /um/Users?filter=userName+eq+\"teddie\" HTTP/1.1
Host: login.example.com
Accept: application/scim+json
Authorization: Bearer 6e6c3a1b-a12f-4451-b065-2441808c6cec

The same query can be done using a POST

Listing 169 Finding a user by username using POST
POST /um/Users/.search HTTP/1.1
Host: login.example.com
Accept: application/scim+json
Authorization: Bearer ec2979e4-f766-4c79-85f9-58f6c72e224f
Content-Type: application/scim+json

{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:SearchRequest"],
    "filter": "userName eq \"teddie\""
}

Both queries will render a responds on the form:

Listing 170 Response of a filter request
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
{
    "totalResults": 1,
    "startIndex": 1,
    "itemsPerPage": 50,

    "schemas": [
        "urn:ietf:params:scim:api:messages:2.0:ListResponse"
    ],
    "Resources": [
        {
            "id": "VVNFUjowODM2Mjg5MGE4ZTQ0YTA3YTRlOWIzNjhhYmM5ZGNhYg",
            "userName": "teddie",
            "schemas": [
                "urn:ietf:params:scim:schemas:core:2.0:User"
            ],
            "name": {
                "familyName": "Bear",
                "givenName": "Ted"
            },
            "emails": [
                {
                    "value": "teddie@example.com",
                    "primary": true
                }
            ],
            "phoneNumbers": [
                {
                    "value": "456-555-555",
                    "primary": true
                }
            ],
            "active": true,
            "meta": {
                "resourceType": "User",
                "created": "1970-01-01T00:02:03Z",
                "lastModified": "1970-01-01T00:20:34Z",
                "location": "https://login.example.com/um/Users/VVNFUjowODM2Mjg5MGE4ZTQ0YTA3YTRlOWIzNjhhYmM5ZGNhYg"
            }
        }
    ]
}

Searching for users matching criteria

It is also possible to search for users and attributes matching certain criterias.

Listing 171 Finding all active users
POST /um/Users/.search HTTP/1.1
Host: login.example.com
Accept: application/scim+json
Authorization: Bearer ec2979e4-f766-4c79-85f9-58f6c72e224f
Content-Type: application/scim+json

{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:SearchRequest"],
    "filter": "active eq true",
    "attributes" : ["userName", "emails.value"]
}

The query searched for all active users but added the attributes filter, asking for only userName and emails.value in the response.

Listing 172 Search response
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
{
    "totalResults": 7,
    "startIndex": 1,
    "itemsPerPage": 50,
    "schemas": [
        "urn:ietf:params:scim:api:messages:2.0:ListResponse"
    ],
    "Resources": [
        {
            "id": "VVNFUjowODM2Mjg5MGE4ZTQ0YTA3YTRlOWIzNjhhYmM5ZGNhYg",
            "userName": "teddie",
            "schemas": [
                "urn:ietf:params:scim:schemas:core:2.0:User"
            ],
            "emails": [
                {
                    "value": "teddie@example.com"
                }
            ]
        },
        {
            "id": "VVNFUjozMGZlNDk5NzJmZDg0MDc2YjEzNWUxYjNkNjEzNTI4Ng",
            "userName": "larsdoe",
            "schemas": [
                "urn:ietf:params:scim:schemas:core:2.0:User"
            ],
            "emails": [
                {
                    "value": "lars.doe@example.com"
                }
            ]
        },

Creating a user

Passwords

A user resource may contain a password. As shown this can be set when creating a new user, or updated when performing a PATCH on a user resource. However, it is not possible to retrieve a password back once it has been set. This is by design; all password parameters will be excluded in the response even if asked for.

To use passwords for authentication, the .search endpoint can be used with a filter query. When passing in a password to the filter, the server will use the configured credential manager, to validate the password. This means that appropriate hashing will be applied to the password.

It is not possible to perform advanced queries at the same time as the password parameter is presented in the filter statement. The filter is expected to ask for things like userName eq "teddie" and password eq "Password1".

This should be used when the SCIM server is used as backend for other services to authenticate user credentials.

Listing 173 Verifying a password for a user
POST /um/Users/.search HTTP/1.1
Host: login.example.com
Accept: application/scim+json
Authorization: Bearer ec2979e4-f766-4c79-85f9-58f6c72e224f
Content-Type: application/scim+json

{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:SearchRequest"],
    "filter": "userName eq 'teddie' and password eq 'Password1'",
    "attributes" : ["userName", "emails.value"]
}

Devices

After having configured a device data source on your user management profile, the /Devices endpoint will be made available under your user management endpoint.

Listing devices

Listing 174 Example request to list all devices
GET /um/Devices HTTP/1.1
Host: login.example.com
Authorization: Bearer 21b652ed-5906-451a-a2a2-681bf099dba7
Accept: application/scim+json
Listing 175 Example response listing all devices
{
    "totalResults": 5,
    "startIndex": 1,
    "itemsPerPage": 50,
    "schemas": [
        "urn:ietf:params:scim:api:messages:2.0:ListResponse"
    ],
    "Resources": [
        {
            "id": "REVWSUNFOjE",
            "deviceId": "device1",
            "accountId": "VVNFUjo2RENDOTRDRTQ1NkE3MDEzRTA1MzAyMDAxMkFDNTM0NCAgICA",
            "externalId": "12345",
            "alias": "My tablet",
            "formFactor": "ff1",
            "deviceType": "tab",
            "owner": "VVNFUjpqb2huZG9l",
            "expiresAt": "2022-01-01T00:00:05Z",
            "meta": {
                "resourceType": "Device",
                "created": "1999-11-30T18:22:30Z",
                "lastModified": "1970-01-01T00:00:01Z",
                "location": "https://login.example.com/um/Devices/REVWSUNFOjE"
            },
            "schemas": [
                "urn:se:curity:scim:2.0:Devices"
            ]
        }
    ]

Delegations

After having configured a token data source on your user management profile, the /Delegations endpoint will be made available under your user management endpoint.

Important

If enabled, it is highly recommended to configure the same token data source as the one used by the referenced OAuth profile.

Listing and searching delegations

Depending on the authorization policies configured on the user management endpoint, an access token will either grant admin access or user access, the former listing all issued delegations and the latter those that belong to the subject present in the access token.

Listing 176 Example request to list all delegations
GET /um/Delegations HTTP/1.1
Host: login.example.com
Authorization: Bearer 21b652ed-5906-451a-a2a2-681bf099dba7
Accept: application/scim+json
Listing 177 Example response listing all delegations
{
    "totalResults": 7,
    "startIndex": 1,
    "itemsPerPage": 50,
    "schemas": [
        "urn:ietf:params:scim:api:messages:2.0:ListResponse"
    ],
    "Resources": [
        {
            "sub": "johndoe",
            "clientId": "client-one",
            "active": true,
            "externalId": "15dd2133-44e8-4e2f-a789-5f54d1ea28d9",
            "userName": "johndoe",
            "meta": {
                "resourceType": "Delegation",
                "created": "2018-06-04T11:27:11Z",
                "lastModified": "2018-06-04T11:27:11Z"
            },
            "scope": "openid",
            "schemas": [
                "urn:se:curity:scim:2.0:Delegation"
            ],
            "claims": {
                "subject": {
                    "accountId": "6DCC94CE456A7013E053020012AC5344",
                    "userName": "johndoe",
                    "subject": "johndoe"
                },
                "context": {
                    "auth_time": 1528111631
                }
            },
            "id": "REVMRUdBVElPTjoxNWRkMjEzMy00NGU4LTRlMmYtYTc4OS01ZjU0ZDFlYTI4ZDk",
            "exp": 1528115231,
            "iat": 1528111631,
            "status": "issued"
        }
    ]
}

For searching/filtering specific delegations the SCIM filter parameter may be used.

Listing 178 Example requests with SCIM filters applied
/um/Delegations?filter=status eq "revoked"
/um/Delegations?filter=scope co "openid"
/um/Delegations?filter=not(scope eq "write") and userName sw "my-company"

External ID

externalId maps to the internal delegationId. delegationId is in tokens, so to find out what delegation a token stems from, find the delegationId claim, and use this filter:

Listing 179 Find delegation by delegationId
/um/Delegations?filter=externalId eq "15dd2133-44e8-4e2f-a789-5f54d1ea28d9"

Custom claims

Custom claims that are added to a token will be represented by the customClaims object.

Listing 180 Example response with custom claims
{
    "totalResults": 1,
    "startIndex": 1,
    "itemsPerPage": 50,
    "schemas": [
        "urn:ietf:params:scim:api:messages:2.0:ListResponse"
    ],
    "Resources": [
        {
            "sub": "johndoe",
            "clientId": "client-one",
            "active": true,
            "externalId": "15dd2133-44e8-4e2f-a789-5f54d1ea28d9",
            "userName": "johndoe",
            "meta": {
                "resourceType": "Delegation",
                "created": "2018-06-04T11:27:11Z",
                "lastModified": "2018-06-04T11:27:11Z"
            },
            "scope": "openid",
            "schemas": [
                "urn:se:curity:scim:2.0:Delegation"
            ],
            "claims": {
                "subject": {
                    "accountId": "6DCC94CE456A7013E053020012AC5344",
                    "userName": "johndoe",
                    "subject": "johndoe"
                },
                "context": {
                    "auth_time": 1528111631
                }
            },
            "customClaims": {
                "email": "john@doe.com",
                "employeeNumber": 54321
            },
            "id": "REVMRUdBVElPTjoxNWRkMjEzMy00NGU4LTRlMmYtYTc4OS01ZjU0ZDFlYTI4ZDk",
            "exp": 1528115231,
            "iat": 1528111631,
            "status": "issued"
        }
    ]
}

Important

It is highly recommended to configure a scopes authorization manager when using the SCIM server to limit access to the API to clients with certain scopes enabled.

Sorting

Since Curity version 9.3.0, SCIM 2.0 Sorting parameters are supported. When using a JDBC Data Source, only attributes that are indexed by the Data Source can be used for sorting. Other Data Sources may have other limitations, or even not support sorting at all. For example, DynamoDB only supports sorting accounts by userName (any other sortBy values are ignored).

Listing 181 Example request with SCIM sorting parameters applied
/um/Users?filter=userName sw "abc"&sortBy=userName&sortOrder=ascending
/um/Users?filter=userName sw "abc"&sortBy=meta.created