Mock a SCIM Provider
Mock a SCIM 2.0 Provider
MockServer can stand in for a SCIM 2.0 identity provider, so you can test System for Cross-domain Identity Management (SCIM) clients — user provisioning, deprovisioning, group membership sync — without a real IdP. A single control-plane call generates a fully functional provider that serves CRUD over Users and Groups plus the SCIM discovery documents, with the data held in memory.
Resources are stored and returned in SCIM shapes: every resource carries schemas, an id, and a meta object; lists are wrapped in a SCIM ListResponse envelope; errors use the SCIM Error envelope; and all responses use the application/scim+json media type.
Create a SCIM Provider
Send an empty PUT /mockserver/scim to create a provider with the default base path /scim/v2:
curl -v -X PUT "http://localhost:1080/mockserver/scim"
Or supply a configuration body to customise the base path, seed initial data, choose the id strategy, or require a bearer token:
{
"basePath": "/scim/v2",
"idStrategy": "UUID",
"requireBearerToken": true,
"expectedBearerToken": "my-test-token",
"enforceFilter": true,
"enforcePatch": true,
"initialUsers": [
{ "id": "u1", "userName": "bjensen@example.com", "active": true }
],
"initialGroups": [
{ "id": "g1", "displayName": "Admins", "members": [] }
]
}
Configuration Options
| Field | Default | Description |
|---|---|---|
| basePath | /scim/v2 | Path prefix the SCIM endpoints are served under. Must start with / and must not overlap /mockserver. |
| idStrategy | UUID | How server-assigned ids are generated: UUID or AUTO_INCREMENT. |
| initialUsers | [] | Users to seed the store with. |
| initialGroups | [] | Groups to seed the store with. |
| enforceFilter | true | When true, the filter query parameter is applied; when false, a filtered list returns 501 Not Implemented. |
| enforcePatch | true | When false, PATCH returns 501 Not Implemented. |
| requireBearerToken | false | When true, resource endpoints require an Authorization: Bearer … header (discovery endpoints stay open). |
| expectedBearerToken | null | The exact token required; null accepts any non-empty bearer token. |
Generated Endpoints
| Method & Path | Behaviour |
|---|---|
| GET {basePath}/Users | List users (supports ?filter, ?startIndex, ?count) — returns a ListResponse. |
| POST {basePath}/Users | Create a user (userName required) — 201 with a Location header. |
| GET {basePath}/Users/{id} | Get a user — 200 or 404 error envelope. |
| PUT {basePath}/Users/{id} | Replace a user (preserves id and meta.created). |
| PATCH {basePath}/Users/{id} | Apply a SCIM PatchOp. |
| DELETE {basePath}/Users/{id} | Delete a user — 204 or 404. |
| The same six endpoints exist for {basePath}/Groups (displayName required on create). | |
| GET {basePath}/ServiceProviderConfig | Discovery — advertises supported features (patch/filter reflect the config; bulk/sort/etag are false; OAuth bearer-token auth scheme). |
| GET {basePath}/ResourceTypes | Discovery — a ListResponse of the User and Group resource types. |
| GET {basePath}/Schemas | Discovery — a ListResponse of the core User and Group schema definitions. |
Java Client
// default provider at /scim/v2
mockServerClient.mockScimProvider();
// or with configuration
mockServerClient.mockScimProvider(
new ScimProviderConfiguration()
.setBasePath("/scim/v2")
.setRequireBearerToken(true)
.setExpectedBearerToken("my-test-token")
);
ListResponse Envelope
{
"schemas": [ "urn:ietf:params:scim:api:messages:2.0:ListResponse" ],
"totalResults": 2,
"startIndex": 1,
"itemsPerPage": 2,
"Resources": [ /* shaped User or Group resources */ ]
}
Error Envelope
{
"schemas": [ "urn:ietf:params:scim:api:messages:2.0:Error" ],
"scimType": "invalidValue",
"detail": "userName is required",
"status": "400"
}
Supported Filters
A single attr op "value" comparison over a top-level attribute is supported: eq (equals), co (contains), sw (starts with), and the presence operator pr. For example ?filter=userName eq "bjensen@example.com". A filter referencing an unknown attribute matches nothing. Compound expressions (and/or/not), value-paths, and the ordered operators (gt/ge/lt/le) are not yet supported.
Supported PATCH Operations
A SCIM PatchOp body (urn:ietf:params:scim:api:messages:2.0:PatchOp) with an Operations array is supported over a top-level attribute (emails) or a one-level sub-attribute (name.familyName):
- replace with a path — set the attribute.
- replace without a path — shallow-merge the value object.
- add with a path — set a scalar, or append to an array attribute (e.g. emails, members).
- add without a path — shallow-merge the value object.
- remove with a path — delete the attribute or sub-attribute.
A malformed PatchOp returns a 400 error envelope with scimType: "invalidSyntax".