Liferay Security APIs

SCIM User API Basics

Liferay DXP 2024.Q1+/Portal GA112+

Liferay provides a headless API to perform CRUD operations on SCIM users to keep their identity information in sync with your company’s applications. Use the /scim endpoint from the API Explorer to manage SCIM users.

Mapping SCIM Attributes to Custom Fields

Liferay DXP 2025.Q4+

Liferay processes additional SCIM attributes during SCIM provisioning. When the incoming SCIM payload contains attributes that do not map to built-in user fields, Liferay creates matching custom fields automatically and stores the values there.

Typed addresses, multiple emails, phone numbers, profile URLs, instant-messaging handles, and other extension attributes map directly to built-in fields when possible. All remaining attributes map to auto-created custom fields under the User entity.

Adding a User

Start a new Liferay DXP instance by running

docker run -it -m 8g -p 8080:8080 liferay/dxp:2025.q1.6-lts

Sign in to Liferay at http://localhost:8080 using the email address test@liferay.com and the password test. When prompted, change the password to learn.

Once Liferay is running,

  1. Download and unzip SCIM User API Basics.

    curl https://resources.learn.liferay.com/examples/liferay-g7y9.zip -O
    
    unzip liferay-g7y9.zip
    
  2. Use the cURL script to add a SCIM user in Liferay. On the command line, navigate to the curl folder. Execute the Users_POST_ToInstance.sh script.

    ./Users_POST_ToInstance.sh
    

    The JSON response shows the addition of a new SCIM user:

    {
       "emails": [
          {
             "type": "default",
             "value": "able@liferay.com",
             "primary": true
          }
       ],
       "meta": {
          "created": "2024-03-13T09:53:22Z",
          "location": "http://localhost:8080/o/scim/v1.0/v2/Users/36433",
          "lastModified": "2024-03-13T09:53:23Z",
          "resourceType": "User"
       },
       "schemas": [
          "urn:ietf:params:scim:schemas:core:2.0:User",
          "urn:ietf:params:scim:schemas:extension:liferay:2.0:User"
       ],
       "urn:ietf:params:scim:schemas:extension:liferay:2.0:User": {
          "birthday": "1970-01-01",
          "male": true
       },
       "name": {
          "familyName": "Baker",
          "givenName": "Able"
       },
       "active": true,
       "externalId": "1446cf10-3de9-6e11-dd15-c561de806259",
       "id": "36433",
       "title": "",
       "userName": "able.baker"
    }
    
  3. Verify this by opening the Global Menu (Applications Menu icon), and navigating to Control PanelUsers and Organizations. See that a new user has been added.

    See that a new user has been added.

  4. Alternatively, call the REST service using the Java client. Navigate into the java folder and compile the source files:

    javac -classpath .:* *.java
    
  5. Run the Users_POST_ToInstance class.

    java -classpath .:* Users_POST_ToInstance
    

Examine the cURL Command

The Users_POST_ToInstance.sh script calls the REST service with a cURL command.

curl \
"http://localhost:8080/o/scim/v1.0/v2/Users" \
--data-raw '
	  {
		 "active": "'true'",
		 "emails": [
			{
			   "primary": "'true'",
			   "type": "default",
			   "value": "able@liferay.com"
			}
		 ],
		 "name": {
			"familyName": "Baker",
			"givenName": "Able"
		 },
		 "userName": "able.baker"
	  }' \
--header "Content-Type: application/scim+json" \
--request "POST" \
--user "test@liferay.com:learn"

Here are the command’s arguments:

ArgumentsDescription
"http://localhost:8080/o/scim/v1.0/v2/Users"The REST service endpoint
--data-raw "{ "active": "'true'", "emails": [ { "primary": "'true'", "type": "default", "value": "able@liferay.com" } ], "name": { "familyName": "Baker", "givenName": "Able" }, "userName": "able.baker" }"The data to post
--header "Content-Type: application/scim+json"Indicates that the request body format is in JSON and conforms to the SCIM protocol.
--request "POST"The HTTP method to invoke at the specified endpoint
--user "test@liferay.com:learn"Basic authentication credentials
Note

Basic authentication is used here for demonstration purposes. For production, you should authorize users via OAuth2. See Using OAuth2 to Authorize Users for a sample React application using OAuth2.

Examine the Java Class

The Users_POST_ToInstance.java class adds a SCIM user by calling the UserResource service.

public static void main(String[] args) throws Exception {
	UserResource.Builder builder = UserResource.builder();

	UserResource userResource = builder.authentication(
		"test@liferay.com", "learn"
	).build();

	userResource.postV2User(
		new User() {
			{
				active = true;
				name = new Name() {
					{
						familyName = "Baker";
						givenName = "Able";
					}
				};
				emails = new MultiValuedAttribute[] {
					new MultiValuedAttribute() {
						{
							primary = true;
							type = "default";
							value = "able@liferay.com";
						}
					}
				};
				userName = "able.baker";
			}
		});
}

This class invokes the REST service using only three lines of code:

Line (abbreviated)Description
UserResource.Builder builder = ...Get a Builder for generating a UserResource service instance.
UserResource userResource = builder.authentication(...).build();Use basic authentication and generate a UserResource service instance.
userResource.postV2User(...);Call the userResource.postV2User method.

Note that the project includes the com.liferay.scim.rest.client.jar file as a dependency. You can find client JAR dependency information for all REST applications in the API explorer in your installation at /o/api (e.g., http://localhost:8080/o/api).

Note

The main method’s comment demonstrates running the class.

Important

See UserResource for service details.

Users_GET_FromInstance.sh

Command:

./Users_GET_FromInstance.sh

Code:

curl \
"http://localhost:8080/o/scim/v1.0/v2/Users" \
--user "test@liferay.com:learn"

Users_GET_FromInstance.java

Command:

java -classpath .:* Users_GET_FromInstance

Code:

public static void main(String[] args) throws Exception {
	UserResource.Builder builder = UserResource.builder();

	UserResource userResource = builder.authentication(
		"test@liferay.com", "learn"
	).build();

	System.out.println(userResource.getV2Users(null, null));
}

The User objects of your Liferay instance appear in JSON.

Read API Query Parameters for more information.

Get a User

Get a specific user with the following cURL or Java command. Replace 1234 with the user’s ID.

Tip

Use Users_GET_FromInstance.[java|sh] to get a list of all users, and note the id of the user you want specifically.

Users_GET_ById.sh

Command:

./Users_GET_ById.sh 1234

Code:

curl \
"http://localhost:8080/o/scim/v1.0/v2/Users/${1}" \
--user "test@liferay.com:learn"

Users_GET_ById.java

Command:

java -classpath .:* -DuserId=1234 Users_GET_ById

Code:

public static void main(String[] args) throws Exception {
	UserResource.Builder builder = UserResource.builder();

	UserResource userResource = builder.authentication(
		"test@liferay.com", "learn"
	).build();

	System.out.println(
		userResource.getV2UserById(
			String.valueOf(System.getProperty("userId"))));
}

The User fields appear in JSON.

Using Query Parameters

You can filter the data you get by using query parameters. The example below gets users by user name.

Users_GET_ByUserName.sh

Command:

./Users_GET_ByUserName.sh 1234

Code:

curl \
	"http://localhost:8080/o/scim/v1.0/v2/Users?filter=userName%20eq%20%22${1}%22" \
	--user "test@liferay.com:learn"

Query parameters can also be used to refine the data returned. When querying the Users resource, filtering supports only the externalId and userName attributes. For example, you can filter results by modifying the query in the script above like this:

http://localhost:8080/o/scim/v1.0/v2/Users?filter=userName%20eq%20%22${1}%22

Put a User

Update an existing user with the following cURL and Java commands. Replace 1234 with your user’s ID.

Users_PUT_ById.sh

Command:

./Users_PUT_ById.sh 1234

Code:

curl \
"http://localhost:8080/o/scim/v1.0/v2/Users/${1}" \
--data-raw '
	  {
		 "emails": [
			{
			   "primary": true,
			   "type": "default",
			   "value": "able@liferay.com"
			}
		 ],
		 "name": {
			"familyName": "Charlie",
			"givenName": "Able"
		 },
		 "userName": "able.baker"
	  }' \
--header "Content-Type: application/scim+json" \
--request "PUT" \
--user "test@liferay.com:learn"

Users_PUT_ById.java

Command:

java -classpath .:* -DuserId=1234 Users_PUT_ById

Code:

public static void main(String[] args) throws Exception {
	UserResource.Builder builder = UserResource.builder();

	UserResource userResource = builder.authentication(
		"test@liferay.com", "learn"
	).build();

	userResource.putV2User(
		String.valueOf(System.getProperty("userId")),
		new User() {
			{
				name = new Name() {
					{
						familyName = "Charlie";
						givenName = "Able";
					}
				};
				emails = new MultiValuedAttribute[] {
					new MultiValuedAttribute() {
						{
							primary = true;
							type = "default";
							value = "able@liferay.com";
						}
					}
				};
				userName = "able.baker";
			}
		});
}

Deactivate a User

Deactivate an existing user with the following cURL and Java commands. Replace 1234 with your user’s ID.

Users_DELETE_ById.sh

Command:

./Users_DELETE_ById.sh 1234

Code:

curl \
"http://localhost:8080/o/scim/v1.0/v2/Users/${1}" \
--request "DELETE" \
--user "test@liferay.com:learn"

Users_DELETE_ById.java

Command

java -classpath .:* -DuserId=1234 Users_DELETE_ById

Code:

public static void main(String[] args) throws Exception {
	UserResource.Builder builder = UserResource.builder();

	UserResource userResource = builder.authentication(
		"test@liferay.com", "learn"
	).build();

	userResource.deleteV2User(String.valueOf(System.getProperty("userId")));
}

Patch a User

Liferay DXP 2025.Q2+

Patch an existing user with the following cURL command. Replace 1234 with your user’s ID.

Command:

./Users_PATCH_ById.sh 1234

Code:

curl \
	"http://localhost:8080/o/scim/v1.0/v2/Users/${1}" \
	--data-raw '
		{
			"Operations": [
				{
					"op": "replace",
					"path": "name.givenName",
					"value": "Abel"
				}
				],
				"schemas": [
					"urn:ietf:params:scim:api:messages:2.0:PatchOp"
				]
		}' \
	--header "Content-Type: application/scim+json" \
	--request "PATCH" \
	--user "test@liferay.com:learn"

The API Explorer lists all of the User services and schemas and has an interface to try out each service.

Feature Availability by Version

FeatureLiferay DXP VersionPortal VersionNotes
Mapping SCIM Attributes to Custom Fields2025.Q4+-Initially released as a release feature (LPD-56434). Made Generally Available (GA) in Liferay DXP 2026.Q1.