### ScimService - Client Setup Source: https://context7.com/pingidentity/scim2/llms.txt Demonstrates how to initialize the ScimService for interacting with SCIM endpoints, including basic setup and OAuth2 bearer token authentication. ```APIDOC ## ScimService - Client Setup ### Description Initializes the `ScimService` which acts as the primary entry point for all SCIM operations. It can be configured with a base URL for the SCIM service provider and supports authentication mechanisms like OAuth2 bearer tokens. ### Method N/A (This is a class instantiation and configuration example) ### Endpoint N/A ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```java import com.unboundid.scim2.client.ScimService; import jakarta.ws.rs.client.Client; import jakarta.ws.rs.client.ClientBuilder; import jakarta.ws.rs.client.WebTarget; import org.glassfish.jersey.client.oauth.OAuth2ClientSupport; // Basic client setup Client client = ClientBuilder.newClient(); WebTarget target = client.target("https://example.com/scim/v2"); ScimService scimService = new ScimService(target); // With OAuth2 bearer token authentication Client authenticatedClient = ClientBuilder.newClient() .register(OAuth2ClientSupport.feature("your-bearer-token")); WebTarget authenticatedTarget = authenticatedClient.target("https://example.com/scim/v2"); ScimService authenticatedScimService = new ScimService(authenticatedTarget); ``` ### Response #### Success Response (200) N/A (This is a client setup example) #### Response Example N/A ``` -------------------------------- ### Configure ScimService Client in Java Source: https://context7.com/pingidentity/scim2/llms.txt Demonstrates how to create and configure the `ScimService` client in Java. It shows basic setup using `ClientBuilder` and `WebTarget`, as well as configuration with OAuth2 bearer token authentication. ```java import com.unboundid.scim2.client.ScimService; import jakarta.ws.rs.client.Client; import jakarta.ws.rs.client.ClientBuilder; import jakarta.ws.rs.client.WebTarget; import org.glassfish.jersey.client.oauth.OAuth2ClientSupport; // Basic client setup Client client = ClientBuilder.newClient(); WebTarget target = client.target("https://example.com/scim/v2"); ScimService scimService = new ScimService(target); // With OAuth2 bearer token authentication Client authenticatedClient = ClientBuilder.newClient() .register(OAuth2ClientSupport.feature("your-bearer-token")); WebTarget authenticatedTarget = authenticatedClient.target("https://example.com/scim/v2"); ScimService authenticatedScimService = new ScimService(authenticatedTarget); ``` -------------------------------- ### SCIM Search Filter Examples (Java) Source: https://github.com/pingidentity/scim2/wiki/Making-SCIM-requests Provides examples of constructing various search filters using the `Filter` class, adhering to RFC 7644 operators. This includes equality, presence, starts with, ends with, greater than or equal to, negation, AND logic, and complex value matching for multi-valued attributes. ```java // Equality Filter.eq("userName", "user.1") // Presence Filter.pr("userName") // Starts With Filter.sw("name.givenName", "Barb") // Ends With Filter.ew("name.familyName", "Jen") // Greater Than or Equal To Filter.gte("age", 18) // Negation Filter.not(Filter.gt("age", 18)) // AND Filter.and( Filter.eq("userName", "user.1"), Filter.eq("name.familyName", "Jensen") ) // Complex Value Matching // Same as: addresses[(type eq "home" and country eq "US")] Filter.hasComplexValue( "addresses", Filter.and( Filter.eq("type", "home"), Filter.eq("country", "US") ) ) ``` -------------------------------- ### Retrieve Service Provider Configuration Source: https://github.com/pingidentity/scim2/wiki/Making-SCIM-requests Shows how to call the /ServiceProviderConfig endpoint using ScimService to retrieve configuration details. This example specifically checks if the service provider supports PATCH operations. ```java ServiceProviderConfigResource providerConfig = scimService.getServiceProviderConfig(); if (providerConfig.getPatch().isSupported()) { // Etc. } ``` -------------------------------- ### Create SCIM Resource - Java Source: https://github.com/pingidentity/scim2/wiki/Making-SCIM-requests Creates a new SCIM resource by providing an instance of GenericScimResource or BaseScimResource to the ScimService.create method. The example demonstrates creating a UserResource with specific attributes. ```java UserResource userResource = new UserResource(); userResource.setUserName("user.1"); userResource.setPassword("secret"); Name name = new Name() .setGivenName("Joe") .setFamilyName("Public"); userResource.setName(name); Email email = new Email() .setType("home") .setPrimary(true) .setValue("joe.public@example.com"); userResource.setEmails(Collections.singletonList(email)); userResource = scimService.create("Users", userResource); ``` -------------------------------- ### Configure Basic Authentication with Apache HttpClient for SCIM 2 SDK Source: https://github.com/pingidentity/scim2/wiki/JAX-RS-Client-examples Configures basic authentication for the SCIM 2 SDK's JAX-RS client when using the Apache HttpClient transport. It requires a CredentialsProvider to be set in the client configuration. ```java // Required dependency: org.glassfish.jersey.connectors:jersey-apache-connector String baseUri = "https://example.com/scim/v2"; ApacheConnectorProvider connectorProvider = new ApacheConnectorProvider(); HttpClientConnectionManager clientConnectionManager = new PoolingHttpClientConnectionManager(); CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); Credentials credentials = new UsernamePasswordCredentials(username, password); credentialsProvider.setCredentials(AuthScope.ANY, credentials); ClientConfig config = new ClientConfig() .connectorProvider(connectorProvider) .property(ApacheClientProperties.CREDENTIALS_PROVIDER, credentialsProvider) .property(ApacheClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION, true) .property(ApacheClientProperties.CONNECTION_MANAGER, connectionManager); Client client = ClientBuilder.newClient(config); WebTarget target = client.target(new URI(baseUri)); ScimService scimService = new ScimService(target); ``` -------------------------------- ### Configure Basic Authentication with Default Client Transport for SCIM 2 SDK Source: https://github.com/pingidentity/scim2/wiki/JAX-RS-Client-examples Sets up basic authentication for the SCIM 2 SDK's JAX-RS client when using the default HTTP transport. It utilizes HttpAuthenticationFeature to provide credentials. ```java String baseUri = "https://example.com/scim/v2"; HttpAuthenticationFeature basicAuthFeature = HttpAuthenticationFeature.basicBuilder() .credentials(username, password) .build(); ClientConfig config = new ClientConfig(); config.register(basicAuthFeature); Client client = ClientBuilder.newClient(config); WebTarget target = client.target(baseUri); ScimService scimService = new ScimService(target); ``` -------------------------------- ### Configure Apache HttpClient for SCIM 2 SDK Source: https://github.com/pingidentity/scim2/wiki/JAX-RS-Client-examples Configures the JAX-RS client to use Apache HttpClient as the underlying HTTP transport mechanism by providing an ApacheConnectorProvider. This is useful for advanced connection management and pooling. ```java // Required dependency: org.glassfish.jersey.connectors:jersey-apache-connector String baseUri = "https://example.com/scim/v2"; ApacheConnectorProvider connectorProvider = new ApacheConnectorProvider(); HttpClientConnectionManager clientConnectionManager = new PoolingHttpClientConnectionManager(); ClientConfig config = new ClientConfig() .connectorProvider(connectorProvider) .property(ApacheClientProperties.CONNECTION_MANAGER, clientConnectionManager); Client client = ClientBuilder.newClient(config); WebTarget target = client.target(baseUri); ScimService scimService = new ScimService(target); ``` -------------------------------- ### Paging SCIM Search Results (Java) Source: https://github.com/pingidentity/scim2/wiki/Making-SCIM-requests Demonstrates how to paginate search results by specifying the start index and the number of resources per page using the `page(int, int)` method. This is crucial when a search filter may return a large number of resources. ```java Filter filter = Filter.eq("lastName", "Jensen"); ListResponse searchResponse = scimService.searchRequest("Users") .filter(filter.toString()) // Start at index 1 and return 10 results .page(1, 10) .invoke(UserResource.class); // The search response will include up to 10 resources. for (UserResource userResource : searchResponse) { // Etc. } ``` -------------------------------- ### Search Filter Syntax Source: https://github.com/pingidentity/scim2/wiki/Making-SCIM-requests Provides examples of constructing search filters using the Filter class, based on RFC 7644 operators. ```APIDOC ## Search Filter Construction ### Description This section details how to construct SCIM search filters programmatically using the `Filter` class, adhering to RFC 7644 specifications. ### Filter Operators - **Equality (`eq`)**: Checks if an attribute equals a specific value. ```java Filter.eq("userName", "user.1") ``` - **Presence (`pr`)**: Checks if an attribute has a value. ```java Filter.pr("userName") ``` - **Starts With (`sw`)**: Checks if an attribute value begins with a specified string. ```java Filter.sw("name.givenName", "Barb") ``` - **Ends With (`ew`)**: Checks if an attribute value ends with a specified string. ```java Filter.ew("name.familyName", "Jen") ``` - **Greater Than or Equal To (`gte`)**: Checks if an attribute value is greater than or equal to a specified value. ```java Filter.gte("age", 18) ``` - **Negation (`not`)**: Negates a given filter condition. ```java Filter.not(Filter.gt("age", 18)) ``` - **AND**: Combines multiple filter conditions, all of which must be true. ```java Filter.and( Filter.eq("userName", "user.1"), Filter.eq("name.familyName", "Jensen") ) ``` - **Complex Value Matching (`hasComplexValue`)**: Filters based on matching sub-attributes of a multi-valued attribute. ```java // Equivalent to: addresses[type eq "home" and country eq "US"] Filter.hasComplexValue( "addresses", Filter.and( Filter.eq("type", "home"), Filter.eq("country", "US") ) ) ``` ``` -------------------------------- ### Search Users - GET with Filters and Pagination Source: https://context7.com/pingidentity/scim2/llms.txt Searches for SCIM resources (users) using filters, pagination, and attribute selection. Allows for complex filtering and precise control over returned data. ```APIDOC ## GET /Users ### Description Searches for SCIM resources (users) using filters, pagination, and attribute selection. Allows for complex filtering and precise control over returned data. ### Method GET ### Endpoint `/Users` ### Parameters #### Path Parameters None #### Query Parameters - **filter** (string) - Optional - A filter expression to narrow down the search results (e.g., `name.familyName eq "Jensen"`). - **startIndex** (integer) - Optional - The starting index of the search results (1-based). - **count** (integer) - Optional - The number of search results to return. - **attributes** (string) - Optional - A comma-separated list of attribute names to include in the response. - **excludedAttributes** (string) - Optional - A comma-separated list of attribute names to exclude from the response. ### Request Example ``` GET /Users?filter=name.familyName%20eq%20%22Jensen%22&startIndex=1&count=10&attributes=userName,name,emails ``` ### Response #### Success Response (200 OK) - **totalResults** (integer) - The total number of results matching the query. - **startIndex** (integer) - The starting index of the current set of results. - **itemsPerPage** (integer) - The number of results returned in this response. - **Resources** (array of UserResource) - An array of user resources matching the search criteria. #### Response Example ```json { "totalResults": 5, "startIndex": 1, "itemsPerPage": 10, "Resources": [ { "id": "2819c223-7f76-453a-919d-413861904646", "userName": "bjensen", "name": { "givenName": "Barbara", "familyName": "Jensen" }, "emails": [ { "type": "work", "value": "bjensen@example.com" } ] } ] } ``` ``` -------------------------------- ### Demonstrate Default ObjectMapper JSON Output (Java) Source: https://github.com/pingidentity/scim2/wiki/Common-Problems-and-FAQ Illustrates how Jackson's default ObjectMapper configuration prints null values in SCIM resources, leading to undesirable JSON output. This example shows the difference compared to using the SCIM SDK's configured ObjectMapper. ```java GroupResource group = new GroupResource().setDisplayName("kendrick"); String stringValue = new ObjectMapper().valueToTree(group).toPrettyString(); System.out.println(stringValue); ``` -------------------------------- ### Configure Bearer Token Authentication with Apache HttpClient for SCIM 2 SDK Source: https://github.com/pingidentity/scim2/wiki/JAX-RS-Client-examples Sets up bearer token authentication for the SCIM 2 SDK's JAX-RS client when using the Apache HttpClient transport. It configures the client with ApacheConnectorProvider and registers the OAuth2ClientSupport feature. ```java // Required dependency: org.glassfish.jersey.security:oauth2-client // Required dependency: org.glassfish.jersey.connectors:jersey-apache-connector String baseUri = "https://example.com/scim/v2"; String bearerToken = "…"; ClientConfig config = new ClientConfig() .connectorProvider(new ApacheConnectorProvider()); Client client = ClientBuilder.newClient(config) .register(OAuth2ClientSupport.feature(bearerToken)); WebTarget target = client.target(baseUri); ScimService scimService = new ScimService(target); ``` -------------------------------- ### Search Users - GET with Filters and Pagination (Java) Source: https://context7.com/pingidentity/scim2/llms.txt Searches for SCIM resources using filters, pagination, and attribute selection. Supports filtering by attribute values, paginating results, and specifying which attributes to include or exclude. Dependencies include SCIM2 common messages and filters. ```java import com.unboundid.scim2.common.messages.ListResponse; import com.unboundid.scim2.common.filters.Filter; // Search with filter Filter filter = Filter.eq("name.familyName", "Jensen"); ListResponse results = scimService.searchRequest("Users") .filter(filter.toString()) .invoke(UserResource.class); System.out.println("Total results: " + results.getTotalResults()); for (UserResource user : results) { System.out.println("User: " + user.getUserName()); } // Search with pagination ListResponse pagedResults = scimService.searchRequest("Users") .filter(Filter.eq("active", true).toString()) .page(1, 10) // Start at index 1, return 10 results .invoke(UserResource.class); // Search with specific attributes returned ListResponse limitedResults = scimService.searchRequest("Users") .filter(Filter.sw("name.givenName", "Bar").toString()) .attributes("userName", "name", "emails") .invoke(UserResource.class); // Search excluding certain attributes ListResponse excludedResults = scimService.searchRequest("Users") .filter(Filter.pr("emails").toString()) .excludedAttributes("meta", "groups") .invoke(UserResource.class); ``` -------------------------------- ### Configure Bearer Token Authentication with Default Client Transport for SCIM 2 SDK Source: https://github.com/pingidentity/scim2/wiki/JAX-RS-Client-examples Enables bearer token authentication for the SCIM 2 SDK's JAX-RS client using the default transport. It registers the OAuth2ClientSupport feature with the provided token. ```java // Required dependency: org.glassfish.jersey.security:oauth2-client String baseUri = "https://example.com/scim/v2"; String bearerToken = "…"; Client client = ClientBuilder.newClient() .register(OAuth2ClientSupport.feature(bearerToken)); WebTarget target = client.target(baseUri); ScimService scimService = new ScimService(target); ``` -------------------------------- ### Dynamic JSON Manipulation with GenericScimResource in Java Source: https://context7.com/pingidentity/scim2/llms.txt Illustrates how to use the GenericScimResource class for flexible access and manipulation of SCIM resource attributes without a predefined schema. It covers setting, getting, adding, and removing single and multi-valued attributes, working with nested paths, and converting between GenericScimResource and other SCIM resource types. ```java import com.unboundid.scim2.common.GenericScimResource; import com.unboundid.scim2.common.Path; import com.unboundid.scim2.common.utils.JsonUtils; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; import java.util.List; // Create empty generic resource GenericScimResource resource = new GenericScimResource(); // Set single-valued attributes resource.replaceValue("userName", "newuser"); resource.replaceValue("active", true); resource.replaceValue("employeeNumber", 12345); resource.replaceValue("salary", 75000.50); // Get single-valued attributes String userName = resource.getStringValue("userName"); Boolean isActive = resource.getBooleanValue("active"); Integer empNum = resource.getIntegerValue("employeeNumber"); Double salary = resource.getDoubleValue("salary"); // Add to multi-valued attributes resource.addStringValues("schemas", "urn:ietf:params:scim:schemas:core:2.0:User"); resource.addStringValues("nickNames", "Nick1", "Nick2", "Nick3"); // Get multi-valued attributes as list List nickNames = resource.getStringValueList("nickNames"); // Work with nested paths resource.replaceValue("name.givenName", "John"); resource.replaceValue("name.familyName", "Doe"); String givenName = resource.getStringValue("name.givenName"); // Get raw JsonNode for complex manipulation JsonNode value = resource.getValue("name"); if (value.isObject()) { String formatted = value.get("formatted").asText(); } // Remove values resource.removeValues("nickNames"); // Convert UserResource to GenericScimResource and back // Assuming UserResource is a defined SCIM resource class // UserResource user = new UserResource().setUserName("test"); // GenericScimResource generic = user.asGenericScimResource(); // generic.replaceValue("displayName", "Test User"); // UserResource converted = JsonUtils.nodeToValue( // generic.getObjectNode(), UserResource.class); // Access the underlying Jackson ObjectNode ObjectNode node = resource.getObjectNode(); ``` -------------------------------- ### Build SCIM Query Filters with Java Source: https://context7.com/pingidentity/scim2/llms.txt Demonstrates how to use the Filter class to construct various SCIM 2.0 compliant filter expressions in Java. Supports equality, inequality, presence, starts with, ends with, contains, comparison, logical operators (AND, OR, NOT), and complex value filters. Also shows parsing filters from strings. ```java import com.unboundid.scim2.common.filters.Filter; // Equality filter Filter eqFilter = Filter.eq("userName", "bjensen"); // Result: userName eq "bjensen" // Not equal filter Filter neFilter = Filter.ne("active", false); // Result: active ne false // Presence filter - check if attribute exists Filter prFilter = Filter.pr("emails"); // Result: emails pr // Starts with filter Filter swFilter = Filter.sw("name.familyName", "Jen"); // Result: name.familyName sw "Jen" // Ends with filter Filter ewFilter = Filter.ew("userName", "sen"); // Result: userName ew "sen" // Contains filter Filter coFilter = Filter.co("displayName", "Jensen"); // Result: displayName co "Jensen" // Greater than / less than filters Filter gtFilter = Filter.gt("meta.lastModified", "2024-01-01T00:00:00Z"); Filter geFilter = Filter.ge("employeeNumber", 1000); Filter ltFilter = Filter.lt("employeeNumber", 5000); Filter leFilter = Filter.le("employeeNumber", 4999); // Logical AND Filter andFilter = Filter.and( Filter.eq("active", true), Filter.eq("name.familyName", "Jensen") ); // Result: (active eq true and name.familyName eq "Jensen") // Logical OR Filter orFilter = Filter.or( Filter.eq("userName", "bjensen"), Filter.eq("userName", "jsmith") ); // Result: (userName eq "bjensen" or userName eq "jsmith") // Logical NOT Filter notFilter = Filter.not(Filter.eq("active", false)); // Result: not (active eq false) // Complex value filter for multi-valued attributes Filter complexFilter = Filter.complex("emails", Filter.and( Filter.eq("type", "work"), Filter.eq("primary", true) ) ); // Result: emails[type eq "work" and primary eq true] // Parse filter from string Filter parsedFilter = Filter.fromString("userName eq \"bjensen\" and active eq true"); ``` -------------------------------- ### GET /Users/{id} - Retrieve User Source: https://context7.com/pingidentity/scim2/llms.txt Retrieves a SCIM user resource by its unique identifier using a GET request to the /Users/{id} endpoint. ```APIDOC ## GET /Users/{id} - Retrieve User ### Description Retrieves a SCIM resource (e.g., a user) by its endpoint and unique identifier using the `retrieve()` method. The resource can be retrieved as a strongly-typed object (like `UserResource`) or a generic `GenericScimResource` for flexible JSON access. It also supports retrieving the currently authenticated user via the `ScimService.ME_URI`. ### Method GET ### Endpoint `/Users/{id}` or `/Me` ### Parameters #### Path Parameters - **id** (string) - Required - The unique identifier of the resource to retrieve. #### Query Parameters None #### Request Body None ### Request Example ```java import com.unboundid.scim2.common.types.UserResource; import com.unboundid.scim2.common.GenericScimResource; // Retrieve as strongly-typed UserResource UserResource user = scimService.retrieve("Users", "2819c223-7f76-453a-919d-413861904646", UserResource.class); System.out.println("Username: " + user.getUserName()); System.out.println("Display Name: " + user.getDisplayName()); // Retrieve as GenericScimResource for flexible JSON access GenericScimResource genericUser = scimService.retrieve("Users", "2819c223-7f76-453a-919d-413861904646", GenericScimResource.class); String userName = genericUser.getStringValue("userName"); String familyName = genericUser.getStringValue("name.familyName"); // Retrieve the currently authenticated user using ME_URI UserResource currentUser = scimService.retrieve(ScimService.ME_URI, UserResource.class); ``` ### Response #### Success Response (200 OK) - **id** (string) - The unique identifier of the resource. - **userName** (string) - The username of the resource. - **displayName** (string) - The display name of the resource. - Other SCIM resource attributes as applicable. #### Response Example ```json { "id": "2819c223-7f76-453a-919d-413861904646", "userName": "bjensen", "name": { "givenName": "Barbara", "familyName": "Jensen", "formatted": "Barbara Jensen" }, "displayName": "Barbara Jensen", "emails": [ { "type": "work", "primary": true, "value": "bjensen@example.com" } ], "active": true, "meta": { "resourceType": "User", "created": "2023-10-27T10:00:00Z", "lastModified": "2023-10-27T10:00:00Z" } } ``` ``` -------------------------------- ### Initialize ScimService with JAX-RS Client Source: https://github.com/pingidentity/scim2/wiki/Making-SCIM-requests Demonstrates how to create a ScimService instance by first obtaining a JAX-RS WebTarget from a JAX-RS Client. This sets the base URI for SCIM service provider requests. ```java Client restClient = ClientBuilder.newClient(); WebTarget target = restClient.target(new URI("https://example.com/scim/v2")); ScimService scimService = new ScimService(target); ``` -------------------------------- ### ScimService Initialization Source: https://github.com/pingidentity/scim2/wiki/Making-SCIM-requests Demonstrates how to initialize the ScimService with a JAX-RS WebTarget. ```APIDOC ## ScimService Initialization ### Description Initializes the `ScimService` with a JAX-RS `WebTarget` pointing to the SCIM service provider's base URI. ### Method Constructor ### Endpoint N/A ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```java import org.glassfish.jersey.client.JerseyClientBuilder; import javax.ws.rs.client.Client; import javax.ws.rs.client.WebTarget; import java.net.URI; // ... Client restClient = ClientBuilder.newClient(); WebTarget target = restClient.target(new URI("https://example.com/scim/v2")); ScimService scimService = new ScimService(target); ``` ### Response #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Working with SCIM User Resources (POJO) in Java Source: https://context7.com/pingidentity/scim2/llms.txt Illustrates how to use the `UserResource` POJO to create and manage SCIM User resources. It covers setting core attributes, name details, multiple emails, phone numbers, and addresses, and then creating the user via the SCIM service. ```java import com.unboundid.scim2.common.types.*; import java.util.List; // Assuming scimService is an initialized SCIM service client // Create a complete user with all common attributes UserResource user = new UserResource(); // Core attributes user.setUserName("bjensen"); user.setPassword("initialPassword"); user.setDisplayName("Barbara Jensen"); user.setNickName("Babs"); user.setActive(true); user.setTitle("Senior Developer"); user.setPreferredLanguage("en-US"); user.setLocale("en-US"); user.setTimezone("America/Los_Angeles"); // Name Name name = new Name() .setFormatted("Ms. Barbara J Jensen III") .setFamilyName("Jensen") .setGivenName("Barbara") .setMiddleName("Jane") .setHonorificPrefix("Ms.") .setHonorificSuffix("III"); user.setName(name); // Multiple emails Email workEmail = new Email() .setValue("bjensen@example.com") .setType("work") .setPrimary(true) .setDisplay("bjensen@example.com"); Email homeEmail = new Email() .setValue("babs@home.example.com") .setType("home") .setPrimary(false); user.setEmails(workEmail, homeEmail); // Phone numbers PhoneNumber workPhone = new PhoneNumber() .setValue("+1-555-555-5555") .setType("work") .setPrimary(true); PhoneNumber mobilePhone = new PhoneNumber() .setValue("+1-555-555-4444") .setType("mobile"); user.setPhoneNumbers(workPhone, mobilePhone); // Addresses Address workAddress = new Address() .setFormatted("100 Universal City Plaza\nHollywood, CA 91608 USA") .setStreetAddress("100 Universal City Plaza") .setLocality("Hollywood") .setRegion("CA") .setPostalCode("91608") .setCountry("USA") .setType("work") .setPrimary(true); user.setAddresses(workAddress); // Create the user // UserResource createdUser = scimService.create("Users", user); // System.out.println("Created user: " + createdUser.getId()); ``` -------------------------------- ### Modify Outgoing Requests with ClientRequestFilter (Java) Source: https://github.com/pingidentity/scim2/wiki/JAX-RS-Client-examples Adds a 'location' query parameter to all outgoing requests using a JAX-RS ClientRequestFilter. This allows for dynamic modification of request URIs before they are sent. ```java String baseUri = "https://example.com/scim/v2"; ClientConfig config = new ClientConfig(); config.register( new ClientRequestFilter() { public void filter(ClientRequestContext requestContext) throws IOException { URI uri = requestContext.getUri(); UriBuilder uriBuilder = UriBuilder.fromUri(uri) .queryParam("location", "us-east"); requestContext.setUri(uriBuilder.build()); } } ); Client client = ClientBuilder.newClient(config); WebTarget target = client.target(baseUri); ScimService scimService = new ScimService(target); ``` -------------------------------- ### SCIM 2 SDK Client Operations in Java Source: https://github.com/pingidentity/scim2/blob/master/README.md Demonstrates how to initialize the ScimService client, create, retrieve, replace, and partially modify SCIM user resources. It also shows how to perform searches using filters and pagination. Requires the UnboundID SCIM 2 SDK and JAX-RS client dependencies. ```java import com.unboundid.scim2.client.ScimService; import com.unboundid.scim2.common.exceptions.ScimException; import com.unboundid.scim2.common.types.UserResource; import com.unboundid.scim2.common.types.Name; import com.unboundid.scim2.common.types.Email; import com.unboundid.scim2.common.GenericScimResource; import com.unboundid.scim2.common.messages.ListResponse; import com.unboundid.scim2.common.filters.Filter; import jakarta.ws.rs.client.Client; import jakarta.ws.rs.client.ClientBuilder; import jakarta.ws.rs.client.WebTarget; import org.glassfish.jersey.oauth1.feature.OAuth2ClientSupport; // Create a ScimService Client client = ClientBuilder.newClient().register(OAuth2ClientSupport.feature("..bearerToken..")); WebTarget target = client.target("https://example.com/scim/v2"); ScimService scimService = new ScimService(target); // Create a user UserResource user = new UserResource(); user.setUserName("babs"); user.setPassword("secret"); Name name = new Name() .setGivenName("Barbara") .setFamilyName("Jensen"); user.setName(name); Email email = new Email() .setType("home") .setPrimary(true) .setValue("babs@example.com"); user.setEmails(email); try { user = scimService.create("Users", user); // Retrieve the user as a UserResource and replace with a modified instance using PUT user = scimService.retrieve("Users", user.getId(), UserResource.class); user.setDisplayName("Babs"); user = scimService.replace(user); // Retrieve the user as a GenericScimResource and replace with a modified instance using PUT GenericScimResource genericUser = scimService.retrieve("Users", user.getId(), GenericScimResource.class); genericUser.replace("displayName", "Babs Jensen"); genericUser = scimService.replaceRequest(genericUser).invoke(); // Perform a partial modification of the user using PATCH scimService.modifyRequest("Users", user.getId()) .replaceValue("displayName", "Babs") .invoke(GenericScimResource.class); // Perform a password change using PATCH scimService.modifyRequest("Users", user.getId()) .replaceValue("password", "new-password") .invoke(GenericScimResource.class); // Search for users with the same last name as our user ListResponse searchResponse = scimService.searchRequest("Users") .filter(Filter.eq("name.familyName", user.getName().getFamilyName())) .page(1, 5) .attributes("name") .invoke(UserResource.class); } catch (ScimException e) { // Handle SCIM exceptions e.printStackTrace(); } catch (Exception e) { // Handle other exceptions e.printStackTrace(); } ``` -------------------------------- ### Create SCIM User Resource in Java Source: https://context7.com/pingidentity/scim2/llms.txt Illustrates how to create a new SCIM user resource using the `ScimService.create()` method. It shows the construction of a `UserResource` object with necessary details like username, password, name, and email. ```java import com.unboundid.scim2.common.types.UserResource; import com.unboundid.scim2.common.types.Name; import com.unboundid.scim2.common.types.Email; import com.unboundid.scim2.common.exceptions.ScimException; UserResource user = new UserResource(); user.setUserName("bjensen"); user.setPassword("secret123"); Name name = new Name() .setGivenName("Barbara") .setFamilyName("Jensen") .setFormatted("Barbara Jensen"); user.setName(name); Email email = new Email() .setType("work") .setPrimary(true) .setValue("bjensen@example.com"); user.setEmails(email); try { UserResource createdUser = scimService.create("Users", user); System.out.println("Created user ID: " + createdUser.getId()); // Output: Created user ID: 2819c223-7f76-453a-919d-413861904646 } catch (ScimException e) { System.err.println("Error: " + e.getMessage()); } ``` -------------------------------- ### SCIM Value Filters without Sub-attributes Source: https://github.com/pingidentity/scim2/wiki/Working-with-SCIM-Paths Illustrates using value filters to select entire complex objects from an array based on a condition, without specifying a sub-attribute. This example retrieves addresses where the city is not 'Austin'. ```java assert(scimResource.getValue("addresses[city ne \"Austin\"]").isArray()); assert(scimResource.getValue("addresses[city ne \"Austin\"]").size() == 2); ``` -------------------------------- ### Retrieving SCIM Service Provider Configuration and Schemas in Java Source: https://context7.com/pingidentity/scim2/llms.txt Shows how to retrieve metadata about the SCIM service provider, including its configuration, supported schemas, and resource types. This is essential for understanding the capabilities and structure of a SCIM service. ```java import com.unboundid.scim2.common.types.ServiceProviderConfigResource; import com.unboundid.scim2.common.types.SchemaResource; import com.unboundid.scim2.common.types.ResourceTypeResource; import com.unboundid.scim2.common.messages.ListResponse; // Assuming scimService is an initialized SCIM service client // Get service provider configuration // ServiceProviderConfigResource config = scimService.getServiceProviderConfig(); // System.out.println("PATCH supported: " + config.getPatch().isSupported()); // System.out.println("Bulk supported: " + config.getBulk().isSupported()); // System.out.println("Filter supported: " + config.getFilter().isSupported()); // System.out.println("Max results: " + config.getFilter().getMaxResults()); // Get all supported schemas // ListResponse schemas = scimService.getSchemas(); // for (SchemaResource schema : schemas) { // System.out.println("Schema: " + schema.getId() + " - " + schema.getName()); // } // Get a specific schema // SchemaResource userSchema = scimService.getSchema( // "urn:ietf:params:scim:schemas:core:2.0:User"); // System.out.println("User schema attributes: " + userSchema.getAttributes().size()); // Get all supported resource types // ListResponse resourceTypes = scimService.getResourceTypes(); // for (ResourceTypeResource rt : resourceTypes) { // System.out.println("Resource type: " + rt.getName() + " at " + rt.getEndpoint()); // } // Get a specific resource type // ResourceTypeResource userResourceType = scimService.getResourceType("User"); ``` -------------------------------- ### SCIM Value Filters with Sub-attributes Source: https://github.com/pingidentity/scim2/wiki/Working-with-SCIM-Paths Demonstrates using value filters within a path to select specific elements from an array based on a condition, combined with sub-attribute targeting. For example, selecting cities that are not 'Austin' from the addresses list. ```java List notAustin = JsonUtils.findMatchingPaths( Path.fromString("addresses[city ne \"Austin\"].city"), scimResource.getObjectNode()); assert(notAustin.size() == 2); ``` -------------------------------- ### Search SCIM Resources with Filters (Java) Source: https://github.com/pingidentity/scim2/wiki/Making-SCIM-requests Illustrates how to search for SCIM resources using a filter. It involves creating a `SearchRequestBuilder`, applying a filter, and invoking the search to retrieve a `ListResponse`. The `ListResponse` can be iterated to access individual resources. ```java Filter filter = Filter.eq("lastName", "Jensen"); ListResponse searchResponse = scimService.searchRequest("Users") .filter(filter.toString()) .invoke(UserResource.class); for (UserResource userResource : searchResponse) { // Etc. } ``` -------------------------------- ### Disable HTTPS Validation with Apache HttpClient (Java) Source: https://github.com/pingidentity/scim2/wiki/JAX-RS-Client-examples Disables strict HTTPS validation when using Apache HttpClient by configuring the HttpClientConnectionManager to trust self-signed certificates and ignore hostname verification. Requires the 'jersey-apache-connector' dependency. ```java // Required dependency: org.glassfish.jersey.connectors:jersey-apache-connector String baseUri = "https://example.com/scim/v2"; SSLContext sslContext = new SSLContextBuilder() .loadTrustMaterial(null, new TrustSelfSignedStrategy()) .build(); SSLConnectionSocketFactory trustSelfSigned = new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier()); final Registry socketFactoryRegistry = RegistryBuilder. create() .register("https", trustSelfSigned) .build(); HttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); ClientConfig config = new ClientConfig() .connectorProvider(new ApacheConnectorProvider()) .property(ApacheClientProperties.CONNECTION_MANAGER, connectionManager); Client client = ClientBuilder.newClient(config); WebTarget target = client.target(baseUri); ScimService scimService = new ScimService(target); ``` -------------------------------- ### Disable HTTPS Validation with Default Client Transport (Java) Source: https://github.com/pingidentity/scim2/wiki/JAX-RS-Client-examples Configures the default JAX-RS client to trust any HTTP certificate and accept any hostname by using a custom SSLContext and HostnameVerifier. This is useful for testing with self-signed certificates but should not be used in production. ```java String baseUri = "https://example.com/scim/v2"; SSLContext sslcontext = SSLContext.getInstance("TLS"); TrustManager[] trustManagers = new TrustManager[] { new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] certs, String s) { // Do nothing } @Override public void checkServerTrusted(X509Certificate[] certs, String s) { // Do nothing } @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } } };sslcontext.init(null, trustManagers, new SecureRandom()); Client client = ClientBuilder.newBuilder() .withConfig(config) .hostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String s, SSLSession sslSession) { return true; } }) .sslContext(sslcontext) .build(); WebTarget target = client.target(new URI(baseUri)); ScimService scimService = new ScimService(target); return new ScimService(target); ``` -------------------------------- ### Working with SCIM Attribute Paths in Java Source: https://context7.com/pingidentity/scim2/llms.txt Demonstrates how to create and use SCIM attribute paths for accessing nested and filtered values within SCIM resources. It covers simple paths, nested paths, paths with value filters, and finding matching paths in a resource. ```java import com.unboundid.scim2.common.Path; import com.unboundid.scim2.common.utils.JsonUtils; import com.fasterxml.jackson.databind.JsonNode; import java.util.List; // Create simple paths Path userNamePath = Path.fromString("userName"); Path familyNamePath = Path.fromString("name.familyName"); // Use Path.of() for simple attribute paths (since 4.1.0) Path simplePath = Path.of("userName"); Path nestedPath = Path.of("name").attribute("givenName"); // Create path with value filter for multi-valued attributes Path workEmailPath = Path.fromString("emails[type eq \"work\"]"); Path primaryEmailValue = Path.fromString("emails[primary eq true].value"); // Get the last element of a path Path.Element lastElement = familyNamePath.getLastElement(); // Find all matching paths in a resource // Assuming GenericScimResource and scimService are defined elsewhere // GenericScimResource resource = scimService.retrieve("Users", // "2819c223-7f76-453a-919d-413861904646", GenericScimResource.class); // List matchingNodes = JsonUtils.findMatchingPaths( // Path.fromString("emails.value"), // resource.getObjectNode() // ); // for (JsonNode emailValue : matchingNodes) { // System.out.println("Email: " + emailValue.textValue()); // } ``` -------------------------------- ### Handle SCIM2 Exceptions in Java Source: https://context7.com/pingidentity/scim2/llms.txt Illustrates how to catch and handle various SCIM-specific exceptions, such as `ResourceNotFoundException`, `BadRequestException`, and `ServerErrorException`. It shows how to extract detailed error information from `ScimException` and `ErrorResponse` objects. ```java import com.unboundid.scim2.common.exceptions.*; import com.unboundid.scim2.common.messages.ErrorResponse; try { UserResource user = scimService.retrieve("Users", "nonexistent-id", UserResource.class); } catch (ResourceNotFoundException e) { // 404 Not Found System.err.println("User not found: " + e.getMessage()); } catch (BadRequestException e) { // 400 Bad Request - invalid filter, malformed request ErrorResponse error = e.getScimError(); System.err.println("Bad request: " + error.getDetail()); System.err.println("SCIM type: " + error.getScimType()); } catch (UnauthorizedException e) { // 401 Unauthorized System.err.println("Authentication required: " + e.getMessage()); } catch (ForbiddenException e) { // 403 Forbidden System.err.println("Access denied: " + e.getMessage()); } catch (ResourceConflictException e) { // 409 Conflict - e.g., duplicate username System.err.println("Conflict: " + e.getMessage()); } catch (PreconditionFailedException e) { // 412 Precondition Failed - e.g., ETag mismatch System.err.println("Resource was modified: " + e.getMessage()); } catch (ServerErrorException e) { // 500 Internal Server Error System.err.println("Server error: " + e.getMessage()); } catch (ScimException e) { // Catch-all for other SCIM errors System.err.println("SCIM error " + e.getScimError().getStatus() + ": " + e.getMessage()); } ``` -------------------------------- ### Accessing Simple SCIM Attributes Source: https://github.com/pingidentity/scim2/wiki/Working-with-SCIM-Paths Demonstrates how to retrieve values for simple attributes like 'firstName' and 'shoeSize' from a SCIM resource using their respective paths. It shows how to access text and integer values. ```java assert(scimResource.getValue("firstName").textValue().equals("Bill")); assert(scimResource.getValue("shoeSize").intValue() == 13); ``` -------------------------------- ### Resource Searching Source: https://github.com/pingidentity/scim2/wiki/Making-SCIM-requests Explains how to search for SCIM resources using filters and how to paginate through the results. ```APIDOC ## GET /Users ### Description Searches for SCIM resources based on specified filters and supports pagination. ### Method GET ### Endpoint `/Users` ### Parameters #### Query Parameters - **filter** (string) - Optional - The filter expression to apply to the search. Supports RFC 7644 filter syntax. - **startIndex** (integer) - Optional - The 1-based index of the first resource to return. - **count** (integer) - Optional - The number of resources to return per page. ### Request Example ```java // Basic search Filter filter = Filter.eq("lastName", "Jensen"); ListResponse searchResponse = scimService.searchRequest("Users") .filter(filter.toString()) .invoke(UserResource.class); // Search with pagination ListResponse pagedResponse = scimService.searchRequest("Users") .filter(filter.toString()) .page(1, 10) // Start at index 1, return 10 results .invoke(UserResource.class); for (UserResource user : pagedResponse) { // Process user resource } ``` ### Response #### Success Response (200 OK) - **totalResults** (integer) - The total number of resources matching the search criteria. - **startIndex** (integer) - The starting index of the current page of results. - **itemsPerPage** (integer) - The number of resources returned in this response. - **Resources** (array) - An array of SCIM resource objects matching the search criteria. #### Response Example ```json { "totalResults": 5, "startIndex": 1, "itemsPerPage": 10, "Resources": [ { "id": "uuid-1", "userName": "user.1", "name": { "givenName": "John", "familyName": "Doe" } } // ... more resources ] } ``` ```