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.
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.
/Users
GET /um/Users/VVNFUjowODM2Mjg5MGE4ZTQ0YTA3YTRlOWIzNjhhYmM5ZGNhYg HTTP/1.1 Host: login.example.com Authorization: Bearer 21b652ed-5906-451a-a2a2-681bf099dba7 Accept: application/scim+json
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" }
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.
.search
Example of a search query towards the .search endpoint
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
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:
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" } } ] }
It is also possible to search for users and attributes matching certain criterias.
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.
attributes
userName
emails.value
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" } ] },
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".
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.
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"] }
After having configured a device data source on your user management profile, the /Devices endpoint will be made available under your user management endpoint.
/Devices
GET /um/Devices HTTP/1.1 Host: login.example.com Authorization: Bearer 21b652ed-5906-451a-a2a2-681bf099dba7 Accept: application/scim+json
{ "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" ] } ]
After having configured a token data source on your user management profile, the /Delegations endpoint will be made available under your user management endpoint.
/Delegations
Important
If enabled, it is highly recommended to configure the same token data source as the one used by the referenced OAuth profile.
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.
GET /um/Delegations HTTP/1.1 Host: login.example.com Authorization: Bearer 21b652ed-5906-451a-a2a2-681bf099dba7 Accept: application/scim+json
{ "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.
filter
/um/Delegations?filter=status eq "revoked" /um/Delegations?filter=scope co "openid" /um/Delegations?filter=not(scope eq "write") and userName sw "my-company"
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:
externalId
delegationId
/um/Delegations?filter=externalId eq "15dd2133-44e8-4e2f-a789-5f54d1ea28d9"
Custom claims that are added to a token will be represented by the customClaims object.
customClaims
{ "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" } ] }
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.
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).
sortBy
/um/Users?filter=userName sw "abc"&sortBy=userName&sortOrder=ascending /um/Users?filter=userName sw "abc"&sortBy=meta.created