Aprovisionamiento de usuarios: guía de integración de la API

Prev Next

El servicio DocuWare User Provisioning es una API REST compatible con SCIM 2.0 que permite el aprovisionamiento automático de usuarios y la gestión de grupos desde proveedores de identidad externos (IdPs), como Azure Entra ID, Okta, Ping Identity o directorios locales (mediante la herramienta User Provisioning On-premise directory connector), hacia sistemas DocuWare.

URL base y endpoints

Estructura de la URL base

DocuWare Cloud

https://{your-organization}.docuware.cloud/DocuWare/Services/UserProvisioningService/{externalIdp}/scim

DocuWare in situ

http(s)://{your-server-address}/DocuWare/Services/UserProvisioningService/{externalIdp}/scim

Donde {externalIdp} puede ser:

  • azure - para Azure Entra ID

  • okta - para Okta

  • ping - para Ping Identity

  • onpremise - para directorios locales

  • generic-{identifier} - para proveedores de identidad genéricos

Endpoints disponibles

Recurso

Método HTTP

Endpoint

Descripción

Users

GET

/{externalIdp}/scim/Users

Obtener todos los usuarios externos con filtrado opcional por userName o externalId

GET

/{externalIdp}/scim/Users?allDocuWareUsers=true

Obtener todos los usuarios con filtrado opcional por userName o externalId

GET

/{externalIdp}/scim/Users/{id}

Obtener un usuario específico por ID

POST

/{externalIdp}/scim/Users

Crear un usuario nuevo

PUT

/{externalIdp}/scim/Users/{id}

Reemplazar un usuario completamente

PATCH

/{externalIdp}/scim/Users/{id}

Actualización parcial del usuario

DELETE

/{externalIdp}/scim/Users/{id}

Eliminar usuario

Groups

GET

/{externalIdp}/scim/Groups

Obtener todos los grupos con filtrado opcional por displayName

GET

/{externalIdp}/scim/Groups/{id}

Obtener un grupo específico por ID

POST

/{externalIdp}/scim/Groups

Crear un grupo nuevo

PUT

/{externalIdp}/scim/Groups/{id}

Reemplazar un grupo completamente

PATCH

/{externalIdp}/scim/Groups/{id}

Actualización parcial del grupo

DELETE

/{externalIdp}/scim/Groups/{id}

Eliminar grupo

Schemas

GET

/{externalIdp}/scim/Schemas

Obtener esquemas SCIM

Resource Types

GET

/{externalIdp}/scim/ResourceTypes

Obtener tipos de recursos admitidos

Health Check

GET

/AvailabilityCheck

Comprobación de disponibilidad del servicio

Autenticación

Autenticación JWT Bearer

Todos los endpoints (excepto el de comprobación de estado) requieren autenticación mediante token JWT Bearer:

Authorization: Bearer {jwt-token}

Tipo de contenido

Todas las solicitudes deben usar el tipo de contenido SCIM:

Content-Type: application/scim+json

Gestión de usuarios

Esquema de usuario (Core2EnterpriseUser)

Obtener usuarios (GET)

El endpoint GET Users admite múltiples variantes para recuperar datos de usuario con filtrado y paginación opcionales. De forma predeterminada, solo devuelve usuarios con ID externos (usuarios de proveedores de identidad externos).

1. Obtener todos los usuarios externos (predeterminado)

GET /{externalIdp}/scim/Users
Authorization: Bearer {token}

Devuelve todos los usuarios que tienen un externalId (usuarios de proveedores de identidad externos).

Respuesta:

{

  "schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],

  "totalResults": 2,

  "itemsPerPage": 2,

  "startIndex": 1,

  "resources": [

    {

      "userName": "john.doe",

      "active": true,

      "emails": [

        {

          "value": "john.doe@example.com",

          "primary": true

        }

      ],

      "name": {

        "givenName": "John",

        "familyName": "Doe"

      },

      "id": "external-user-id-123",

      "meta": {

        "resourceType": "User"

      },

      "schemas": [

        "urn:ietf:params:scim:schemas:core:2.0:User",

        "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"

      ],

    },

    {

      "userName": "jane.smith",

      "active": true,

      "emails": [

        {

          "value": "jane.smith@example.com",

          "primary": true

        }

      ],

      "name": {

        "givenName": "Jane",

        "familyName": "Smith"

      },

      "id": "external-user-id-456",

      "meta": {

        "resourceType": "User"

      },

      "schemas": [

        "urn:ietf:params:scim:schemas:core:2.0:User",

        "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"

      ]

    }

  ]

}

2. Obtener todos los usuarios de DocuWare

GET /{externalIdp}/scim/Users?allDocuWareUsers=true
Authorization: Bearer {token}

Devuelve todos los usuarios del sistema DocuWare, incluidos tanto los usuarios externos como los usuarios internos de DocuWare.

Nota: los usuarios internos no tienen id

Los usuarios internos no tienen id en la respuesta, porque no son externos y no tienen un atributo externalId establecido, que es el que se devuelve como id.

Respuesta

{

  "schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],

  "totalResults": 2,

  "itemsPerPage": 2,

  "startIndex": 1,

  "resources": [

    {

      "userName": "john.doe",

      "active": true,

      "emails": [

        {

          "value": "john.doe@example.com",

          "primary": true

        }

      ],

      "name": {

        "givenName": "John",

        "familyName": "Doe"

      },

      "id": "external-user-id-123",

      "meta": {

        "resourceType": "User"

      },

      "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User",

        "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"],

    },

    {

      "userName": "jane.smith",

      "active": true,

      "emails": [

        {

          "value": "jane.smith@example.com",

          "primary": true

        }

      ],

      "name": {

        "givenName": "Jane",

        "familyName": "Smith"

      },

      "meta": {

        "resourceType": "User"

      },

      "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User",

        "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"]

    }

  ]

}

3. Obtener un usuario específico por ID

GET /{externalIdp}/scim/Users/{externalId}

Authorization: Bearer {token}

Devuelve un usuario específico por su ID externo.

Respuesta:

{

  "userName": "john.doe",

  "active": true,

  "emails": [

    {

      "value": "john.doe@example.com",

      "primary": true

    }

  ],

  "name": {

    "givenName": "John",

    "familyName": "Doe"

  },

  "id": "external-user-id-123",

  "meta": {

    "resourceType": "User"

  },

  "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User",

    "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"],

}

4. Consultar usuarios con filtros

Filtrar por nombre de usuario (en usuarios externos):

GET /{externalIdp}/scim/Users?filter=userName eq "john.doe"

Authorization: Bearer {token}

Filtrar por nombre de usuario en todos los usuarios de DocuWare:

GET /{externalIdp}/scim/Users?allDocuWareUsers=true&filter=userName eq "john.doe"

Authorization: Bearer {token}

Filtrar por ID externo:

GET /{externalIdp}/scim/Users?filter=externalId eq "external-user-id-123"

Authorization: Bearer {token}

Obtener usuarios con paginación:

GET /{externalIdp}/scim/Users?startIndex=2&count=5

Authorization: Bearer {token}
GET /{externalIdp}/scim/Users?allDocuWareUsers=true&startIndex=2&count=5

Authorization: Bearer {token}

Parámetros de consulta admitidos

Paginación:

  • startIndex - Índice del primer resultado basado en 1 (valor predeterminado: 1, mínimo: 1)

  • count - Número de resultados por página (valor predeterminado: todos los resultados si no se especifica, mínimo: 0)

Filtrado:

  • filter - Expresión de filtro SCIM (solo admite userName eq "value" y externalId eq "value") (sin distinción entre mayúsculas y minúsculas)

Formato de respuesta

Todas las solicitudes GET /Users devuelven una respuesta SCIM ListResponse con la siguiente estructura:

Propiedades:

  • schemas - Array que contiene "urn:ietf:params:scim:api:messages:2.0:ListResponse"

  • totalResults - Número total de usuarios coincidentes

  • itemsPerPage - Número de usuarios devueltos en la respuesta actual

  • startIndex - Índice de inicio de la página actual (basado en 1)

  • Resources - Array de objetos de usuario

Respuestas de error

400 Bad Request - Filtro no válido:

{

  "ScimType": "invalidFilter",

  "Detail": "Unsupported filter attribute: FirstName",

  "Status": 400,

  "Schemas": [

      "urn:ietf:params:scim:api:messages:2.0:Error"

  ]

}
{

  "ScimType": "invalidFilter",

  "Detail": "Unsupported comparison operator: 'ne'",

  "Status": 400,

  "Schemas": [

      "urn:ietf:params:scim:api:messages:2.0:Error"

  ]

}

Todas las solicitudes GET /Users/{externalId} devuelven un objeto User con la siguiente estructura:

Propiedades del objeto User:

  • id - ID externo del usuario

  • userName - Nombre de inicio de sesión del usuario (sin dominio si es un correo electrónico para IdPs no genéricos)

  • active - Estado de actividad del usuario (booleano)

  • emails - Array de objetos de correo electrónico con propiedades value y primary

  • name - Objeto con propiedades givenName y familyName

  • meta - Objeto de metadatos con resourceType: "User"

  • schemas - Array de identificadores de esquema SCIM

Respuestas de error

404 Not Found - Usuario no encontrado:

{

  "Detail": "User with External ID 'external-user-id-404' was not found.",

  "Status": 404,

  "Schemas": [

      "urn:ietf:params:scim:api:messages:2.0:Error"

  ]

}

Ejemplos

Obtener los primeros 5 usuarios externos:

GET /{externalIdp}/scim/Users?startIndex=1&count=5

Obtener usuarios externos a partir de una posición:

GET /{externalIdp}/scim/Users?startIndex=10&count=20

Buscar un usuario por nombre de usuario:

GET /{externalIdp}/scim/Users?filter=userName eq "john.doe"

Buscar un usuario por nombre de usuario en todos los usuarios de DocuWare:

GET /{externalIdp}/scim/Users?allDocuWareUsers=true&filter=userName eq "jane.smith"

Buscar un usuario por externalId:

GET /{externalIdp}/scim/Users?filter=externalId eq "external-user-id-123"

Obtener todos los usuarios de DocuWare con paginación:

GET /{externalIdp}/scim/Users?allDocuWareUsers=true&startIndex=1&count=50

Crear usuario (POST)

Cómo funciona la creación de usuarios

El sistema implementa una lógica inteligente de creación/actualización de usuarios que sigue estos pasos:

  1. Búsqueda del usuario por ID externo: primero intenta localizar un usuario existente por el externalId proporcionado. Si lo encuentra, se trata de una coincidencia exacta y el usuario existente se actualiza con los atributos de la solicitud.

  2. Búsqueda alternativa por nombre de usuario: si no se encuentra ningún usuario por ID externo, se busca por el nombre de usuario extraído del campo userName. Si se encuentra uno y el correo electrónico entrante coincide con el correo electrónico del usuario existente, se trata de una coincidencia exacta y el usuario existente se actualiza con los atributos de la solicitud. En caso contrario, cuando los correos electrónicos no coinciden, la creación del nuevo usuario falla porque ya existe un usuario con el userName proporcionado (lo que genera un error 409 Conflict).

Lógica de creación frente a actualización de usuarios:

  • Usuario nuevo: si no se encuentra ningún usuario existente por externalID o userName, se crea un usuario nuevo.

  • Actualización de usuario: si se encuentra un usuario existente que coincida por externalId o por userName + correo electrónico, se actualiza la información del usuario.

  • Validación de correo electrónico: al buscar por userName, se valida que el correo electrónico del usuario existente coincida con el correo electrónico proporcionado (sin distinción entre mayúsculas y minúsculas). Si los correos no coinciden, se genera una excepción para evitar conflictos.

Notas sobre el servicio de resolución de direcciones de correo electrónico

El servicio determina la dirección de correo electrónico del usuario según el siguiente orden de prioridad:

  1. Correo electrónico principal: se utiliza el correo electrónico marcado como primary: true en el array de emails.

  2. Primer correo electrónico válido: si no existe un correo electrónico principal, se selecciona el primer correo electrónico válido del array de emails.

  3. Validación: si ninguno de los anteriores es una dirección de correo electrónico válida, la solicitud falla con un error 400 Bad Request.

Solicitud

POST /{externalIdp}/scim/Users

Content-Type: application/scim+json

Authorization: Bearer {token}

{

  "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User", "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"],

  "userName": "john.doe@example.com",

  "externalId": "external-user-id-123",

  "active": true,

  "name": {

    "givenName": "John",

    "familyName": "Doe"

  },

  "emails": [

    {

      "value": "john.doe@example.com",

      "primary": true

    }

  ]

}

Campos obligatorios y opcionales

Campos obligatorios:

  • schemas - Identificadores de esquema SCIM (debe incluir los esquemas Core y Enterprise User)

  • userName - Nombre de inicio de sesión del usuario (debe ser único)

  • externalId - ID de usuario del proveedor de identidad externo (debe ser único)

  • active - Estado de actividad del usuario

  • emails - Array de direcciones de correo electrónico

Campos opcionales:

  • name - Objeto con el nombre para mostrar del usuario

    • name.givenName - Nombre

    • name.familyName - Apellido

Reglas de validación de campos:

  • UserName: obligatorio, distingue entre mayúsculas y minúsculas, no debe estar vacío ni contener solo espacios en blanco

  • ExternalId: obligatorio, distingue entre mayúsculas y minúsculas, no debe estar vacío ni contener solo espacios en blanco

  • Emails: debe poder resolverse al menos un correo electrónico válido (en caso de múltiples, se respetan las reglas de resolución de direcciones de correo electrónico)

  • Active: valor booleano

  • Campos de nombre: cadenas opcionales con fines de visualización

Respuesta

Éxito (200 OK):

{

  "userName": "john.doe",

  "active": true,

  "emails": [

    {

      "value": "john.doe@example.com",

      "primary": true

    }

  ],

  "name": {

    "givenName": "John",

    "familyName": "Doe"

  },

  "id": "external-user-id-123",

  "meta": {

    "resourceType": "User"

  },

  "schemas": [

      "urn:ietf:params:scim:schemas:core:2.0:User",

      "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"

  ]

}

Respuestas de error

400 Bad Request - Campos obligatorios ausentes:

{

  "ScimType": "invalidValue",

  "Detail": "Validation failed: UserName: is required",

  "Status": 400,

  "Schemas": [

      "urn:ietf:params:scim:api:messages:2.0:Error"

  ]

}

409 Conflict - El usuario ya existe:

{

  "ScimType": "uniqueness",

  "Detail": "User with username 'john.doe' already exists with different email address!",

  "Status": 409,

  "Schemas": [

      "urn:ietf:params:scim:api:messages:2.0:Error"

  ]

}

Actualizar usuario (PUT) - Reemplazo completo del usuario

La operación PUT realiza un reemplazo completo del recurso de usuario. A diferencia de PATCH, que solo actualiza los campos especificados, PUT reemplaza el objeto de usuario completo con los datos proporcionados.

Solicitud PUT básica

PUT /{externalIdp}/scim/Users/{externalId}

Content-Type: application/scim+json

Authorization: Bearer {token}

{

  "userName": "john.doe",

  "externalId": "external-user-id-123",

  "active": true,

  "emails": [

    {

      "value": "john.doe@example.com",

      "primary": true

    }

  ],

  "name": {

    "givenName": "John",

    "familyName": "Doe"

  },

  "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User", "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"]

}

Parámetros

  • {externalIdp} - Identificador del proveedor de identidad externo (azure, okta, ping, onpremise, etc.)

  • {externalId} - El ID externo del usuario que se desea actualizar

Campos obligatorios para PUT

Se deben proporcionar todos los campos obligatorios para la creación de usuarios:

  • userName - Nombre de inicio de sesión del usuario

  • externalId - ID de usuario del proveedor de identidad externo

  • active - Estado de actividad del usuario (booleano, valor predeterminado false si no se proporciona)

  • emails - Array de direcciones de correo electrónico (consulte Resolución de direcciones de correo electrónico)

  • schemas - Identificadores de esquema SCIM (debe incluir los esquemas Core y Enterprise User)

Campos opcionales (se conservan los valores anteriores si no se proporcionan valores nuevos)

  • name - Objeto con el nombre para mostrar del usuario

    • name.givenName - Nombre

    • name.familyName - Apellido

Ejemplo completo de PUT

PUT /azure/scim/Users/external-user-id-123

Content-Type: application/scim+json

Authorization: Bearer {jwt-token}

{

  "userName": "john.smith",

  "externalId": "external-user-id-123",

  "active": false,

  "name": {

    "givenName": "John",

    "familyName": "Smith"

  },

  "emails": [

    {

      "value": "john.smith@example.com",

      "primary": true

    }

  ],

  "schemas": [

    "urn:ietf:params:scim:schemas:core:2.0:User",

    "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"

  ]

}

Respuesta

Éxito (200 OK):

{

  "userName": "john.smith",

  "active": false,

  "emails": [

    {

      "value": "john.smith@example.com",

      "primary": true

    }

  ],

  "name": {

    "givenName": "John",

    "familyName": "Smith"

  },

  "id": "external-user-id-123",

  "meta": {

    "resourceType": "User"

  },

  "schemas": [

    "urn:ietf:params:scim:schemas:core:2.0:User",

    "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"

  ]

}

Respuestas de error

400 Bad Request - Campos obligatorios ausentes

{

  "ScimType": "invalidValue",

  "Detail": "Validation failed: UserName: is required",

  "Status": 400,

  "Schemas": [

      "urn:ietf:params:scim:api:messages:2.0:Error"

  ]

}

404 Not Found - Usuario no encontrado:

{

  "Detail": "User with External ID 'external-user-id-404' was not found.",

  "Status": 404,

  "Schemas": [

      "urn:ietf:params:scim:api:messages:2.0:Error"

  ]

}

409 Conflict - Nombre de usuario duplicado:

{

    "ScimType": "uniqueness",

    "Detail": "User with username 'john.doe' already exists!",

    "Status": 409,

    "Schemas": [

        "urn:ietf:params:scim:api:messages:2.0:Error"

    ]

}

409 Conflict - ExternalId duplicado:

{

  "ScimType": "uniqueness",

  "Detail": "User with External ID 'external-user-id-409' already exists!",

  "Status": 409,

  "Schemas": [

      "urn:ietf:params:scim:api:messages:2.0:Error"

  ]

}

409 Conflict - Recurso bloqueado:

{

  "ScimType": "mutability",

  "Detail": "The resource with ID 'external-user-id-409' is immutable.",

  "Status": 409,

  "Schemas": [

      "urn:ietf:params:scim:api:messages:2.0:Error"

  ]

}

Reglas de validación para PUT

Todas las reglas de validación de las operaciones POST se aplican a las operaciones PUT:

  • UserName: obligatorio, distingue entre mayúsculas y minúsculas, no debe estar vacío ni contener solo espacios en blanco

  • ExternalId: obligatorio, distingue entre mayúsculas y minúsculas, no debe estar vacío ni contener solo espacios en blanco

  • Active: valor booleano (valor predeterminado false si no se proporciona)

  • Emails: debe poder resolverse al menos un correo electrónico válido (en caso de múltiples, se respetan las reglas de resolución de direcciones de correo electrónico)

  • Campos de nombre: opcionales, pero recomendables para la experiencia del usuario

  • Schemas: debe incluir los esquemas Core y Enterprise User

Guía de operaciones PATCH de usuario

La operación PATCH permite actualizaciones parciales de los atributos de usuario mediante operaciones de patch SCIM 2.0. El servicio admite las operaciones replace y add para la actualización de usuarios.

Estructura básica de PATCH:

PATCH /{externalIdp}/scim/Users/{id}

Content-Type: application/scim+json

Authorization: Bearer {token}

{

  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],

  "Operations": [

    {

      "op": "replace",

      "path": "attribute_path",

      "value": "new_value"

    },

    {

      "op": "add",

      "path": "attribute_path",

      "value": "new_value"

    }

  ]

}

Operaciones admitidas

  • replace - Actualizar el valor de un atributo existente

  • add - Actualizar el valor de un atributo vacío o existente

  • remove - No admitida para operaciones de usuario

Rutas de atributos admitidas

Estado de actividad del usuario:

{
  "op": "replace",
  "path": "active",
  "value": "false"
}

Actualización del nombre de usuario:

{
  "op": "replace",
  "path": "userName", 
  "value": "new.username"
}

Campos de nombre:

{
  "op": "replace",
  "path": "name.givenName",
  "value": "NewFirstName"
}
{

  "op": "replace",

  "path": "name.familyName", 

  "value": "NewLastName"

}

Dirección de correo electrónico:

{
  "op": "replace",
  "path": "emails",
  "value": "new.email@example.com"
}
{
  "op": "replace",
  "path": "emails[primary eq true].value",
  "value": "new.email@example.com"
}

Notas:

  • Ambas sintaxis para la ruta de emails son válidas

  • La dirección de correo electrónico debe tener un formato de correo electrónico válido

ID externo

{
  "op": "replace",
  "path": "externalId",
  "value": "new-external-id-456"
}

Ejemplo con múltiples operaciones:

PATCH /{externalIdp}/scim/Users/{id}

Content-Type: application/scim+json

Authorization: Bearer {token}

{

  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],

  "Operations": [

    {

      "op": "replace",

      "path": "active",

      "value": "false"

    },

    {

      "op": "replace", 

      "path": "name.givenName",

      "value": "Jonathan"

    },

    {

      "op": "replace",

      "path": "name.familyName",

      "value": "Smith"

    },

    {

      "op": "replace",

      "path": "emails",

      "value": "jonathan.smith@example.com"

    }

  ]

}

Notas importantes:

  • Todas las operaciones se procesan en secuencia

  • La operación remove no es admitida y devolverá un error

  • Se realiza validación de correo electrónico para los campos relacionados con email

  • El campo active requiere valores de cadena booleanos ("true" o "false")

  • Las rutas de atributos no válidas generarán un error 400 Bad Request

  • Si el externalId o el userName ya está asignado a otro usuario, se producirá un error de conflicto

Gestión de errores:

  • 400 Bad Request: tipo de operación no válido, ruta no admitida o error de validación

  • 404 Not Found: no se encontró el usuario con el ID especificado

  • 409 Conflict: la actualización generaría un conflicto (p. ej., nombre de usuario o externalId duplicado)

Atributos de usuario admitidos para operaciones PATCH

  • userName - Nombre de inicio de sesión del usuario

  • externalId - ID de usuario del proveedor de identidad externo

  • name.givenName - Nombre

  • name.familyName - Apellido

  • active - Estado de actividad del usuario (true/false)

  • emails/emails[].value - Dirección de correo electrónico

Eliminar usuario (DELETE)

La operación DELETE realiza una eliminación lógica del usuario en el sistema DocuWare. Esta operación desactiva al usuario.

Solicitud DELETE básica

DELETE /{externalIdp}/scim/Users/{externalId}

Authorization: Bearer {token}

Parámetros:

  • {externalIdp} - Identificador del proveedor de identidad externo (azure, okta, ping, etc.)

  • {externalId} - El ID externo del usuario que se desea eliminar

Ejemplo de solicitud

DELETE /azure/scim/Users/external-user-id-123

Authorization: Bearer {jwt-token}

Respuesta

Éxito (204 No Content):

HTTP/1.1 204 No Content
Content-Type: application/scim+json

La operación DELETE devuelve HTTP 204 (No Content) con un cuerpo de respuesta vacío cuando se ejecuta correctamente.

Respuestas de error

404 Not Found - Usuario no encontrado:

{

  "Detail": "User with External ID 'ExternalUser112' was not found.",

  "Status": 404,

  "Schemas": [

      "urn:ietf:params:scim:api:messages:2.0:Error"

  ]

}

409 Conflict - El usuario está bloqueado y no se puede eliminar:

{

  "ScimType": "mutability",

  "Detail": "The resource 'ExternalUser11' with ID 'ExternalUser11' is immutable.",

  "Status": 409,

  "Schemas": [

      "urn:ietf:params:scim:api:messages:2.0:Error"

  ]

}

Alternativa a la eliminación: en lugar de eliminar un usuario, la alternativa es desactivarlo mediante una operación PATCH o PUT:

PATCH /{externalIdp}/scim/Users/{externalId}

Content-Type: application/scim+json

Authorization: Bearer {token}

{

  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],

  "Operations": [

    {

      "op": "replace",

      "path": "active",

      "value": "false"

    }

  ]

}

Gestión de grupos

Esquema de grupo (Core2Group)

Cómo funciona la creación de grupos

El sistema implementa una lógica inteligente de creación/actualización de grupos que sigue estos pasos:

  1. Búsqueda del grupo por DisplayName:
    primero intenta localizar un grupo existente por el displayName proporcionado. Si lo encuentra, se trata como una actualización de grupo; de lo contrario, se crea un grupo nuevo.

  2. Lógica de creación frente a actualización de grupos:

    • Grupo nuevo: si no se encuentra ningún grupo existente por displayName, se crea un grupo nuevo con los miembros proporcionados.

    • Actualización de grupo: si se encuentra un grupo existente, se actualiza la información del grupo y se añaden los nuevos miembros a la membresía existente (no se reemplazan los miembros existentes).

    • Adición de miembros: los nuevos miembros se añaden a los grupos existentes sin eliminar los miembros actuales.

    • Prevención de duplicados: el sistema evita la adición de miembros duplicados a los grupos.

Notas importantes sobre la creación de grupos:

  • Unicidad del nombre para mostrar: los grupos se identifican por su displayName.

  • Resolución de miembros: todas las referencias de miembros (campo value) deben ser valores externalId válidos de usuarios existentes.

  • Membresía incremental: las operaciones POST sobre grupos existentes añaden miembros de forma incremental en lugar de reemplazar toda la membresía.

  • Validación de miembros: el sistema solo añade miembros que existan. Si un miembro con el value (externalId) proporcionado no existe, se omite sin devolver un error.

  • Ámbito del proveedor de identidad externo: solo puede gestionar la parte del grupo compuesta por usuarios del externalIdp actual. Los usuarios de otros proveedores de identidad externos o usuarios internos de DocuWare no se ven afectados por estas operaciones.

  • Respuesta: la respuesta solo incluye miembros del grupo que son usuarios externos aprovisionados por el externalIdp especificado (como azure, okta, ping, onpremise o generic). Los usuarios internos o los usuarios creados por otros proveedores de identidad externos se excluyen de la respuesta.

Formato de referencia de miembros:

  • Los miembros se referencian por su externalId (no por el ID de usuario interno de DocuWare)

  • Cada objeto de miembro debe contener un campo value con el ID externo del usuario

  • El campo opcional display (userName del usuario) se puede proporcionar, pero no es necesario para la asignación de membresía

Crear grupo (POST)


POST /{externalIdp}/scim/Groups

Content-Type: application/scim+json

Authorization: Bearer {token}

{

  "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],

  "displayName": "Engineering Team",

  "members": [

    {

      "value": "external-user-id-123"

    },

    {

      "value": "external-user-id-456"

    }

  ]

}

Respuesta



{

  "displayName": "Engineering Team",

  "members": [

    {

      "value": "external-user-id-123",

      "display": "john.doe"

    },

    {

      "value": "external-user-id-456",

      "display": "jane.smith"

    }

  ],

  "id": "12345678-1234-1234-1234-123456789012",

  "meta": {

    "resourceType": "Group"

  },

  "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"]

}

Creación de un grupo vacío:

POST /{externalIdp}/scim/Groups

Content-Type: application/scim+json

Authorization: Bearer {token}

{

  "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],

  "displayName": "Future Project Team",

  "members": []

}

Campos obligatorios:

  • schemas - Identificadores de esquema SCIM (debe incluir "urn:ietf:params:scim:schemas:core:2.0:Group")

  • displayName - Nombre para mostrar del grupo (usado para la identificación)

  • members - Array de objetos de miembro (puede estar vacío para la creación de grupos)

    • members[].value - ID externo del usuario (obligatorio si se especifican miembros)

Respuestas de error

400 Bad Request - Campos obligatorios ausentes:

{

  "ScimType": "invalidValue",

  "Detail": "Validation failed: DisplayName: is required",

  "Status": 400,

  "Schemas": [

      "urn:ietf:params:scim:api:messages:2.0:Error"

  ]

}
{

  "ScimType": "invalidValue",

  "Detail": "Validation failed: Members: The Members field is required.",

  "Status": 400,

  "Schemas": [

      "urn:ietf:params:scim:api:messages:2.0:Error"

  ]

}
{

  "ScimType": "invalidValue",

  "Detail": "Validation failed: Members[0].Value: Member Value is required.",

  "Status": 400,

  "Schemas": [

      "urn:ietf:params:scim:api:messages:2.0:Error"

  ]

}

Obtener grupos (GET)

El endpoint GET Groups admite múltiples variantes para recuperar datos de grupo con filtrado y paginación opcionales. Los grupos incluyen miembros que son usuarios externos del proveedor de identidad externo especificado.

1. Obtener todos los grupos (predeterminado)

GET /{externalIdp}/scim/Groups
Authorization: Bearer {token}

Devuelve todos los grupos que existen en DocuWare, sin incluir los miembros. Estos se pueden consultar con la solicitud GET: /Groups/{groupId}

Respuesta:

{

  "schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],

  "totalResults": 2,

  "itemsPerPage": 2,

  "startIndex": 1,

  "resources": [

    {

      "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],

      "id": "group-id-123",

      "displayName": "Engineering Team",

      "meta": {

        "resourceType": "Group"

      }

    },

    {

      "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],

      "id": "group-id-456",

      "displayName": "Marketing Team",

      "meta": {

        "resourceType": "Group",

      }

    }

  ]

}

2. Obtener un grupo específico por ID

GET /{externalIdp}/scim/Groups/{groupId}

Authorization: Bearer {token}

Recupera los detalles de un grupo específico mediante su ID de grupo. El atributo members solo incluye usuarios externos aprovisionados por el proveedor de identidad especificado.

Respuesta:

{

  "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],

  "displayName": "Engineering Team",

  "members": [

    {

      "value": "external-user-id-123",

      "display": "john.doe",

    },

    {

      "value": "external-user-id-456",

      "display": "jane.smith",

    }

  ],

  "id": "group-external-id-123",

  "meta": {

    "resourceType": "Group"

  }

}

3. Consultar grupos con filtros

Filtrar por nombre para mostrar:

GET /{externalIdp}/scim/Groups?filter=displayName eq "Engineering Team"

Authorization: Bearer {token}

Obtener grupos con paginación:

GET /{externalIdp}/scim/Groups?startIndex=1&count=10

Authorization: Bearer {token}
GET /{externalIdp}/scim/Groups?startIndex=2&count=5

Authorization: Bearer {token}

Parámetros de consulta admitidos

Filtrado:

  • filter - Expresión de filtro SCIM (solo admite displayName eq "value") (sin distinción entre mayúsculas y minúsculas, coincidencia exacta)

Paginación:

  • startIndex - Índice del primer resultado basado en 1 (valor predeterminado: 1, mínimo: 1)

  • count - Número de resultados por página (valor predeterminado: todos los resultados si no se especifica, mínimo: 0)

Formato de respuesta

Todas las solicitudes GET /Groups devuelven una respuesta SCIM ListResponse con la siguiente estructura:

Propiedades de ListResponse:

  • schemas - Array que contiene "urn:ietf:params:scim:api:messages:2.0:ListResponse"

  • totalResults - Número total de grupos coincidentes

  • itemsPerPage - Número de grupos devueltos en la respuesta actual

  • startIndex - Índice de inicio de la página actual (basado en 1)

  • resources - Array de objetos de grupo (el atributo members solo está disponible cuando se consulta por ID de grupo)

Propiedades del objeto Group:

  • id - ID externo del grupo

  • displayName - Nombre para mostrar del grupo

  • members - Array de objetos de miembro (solo usuarios externos del externalIdp especificado)

    • value - ID de usuario externo del miembro

    • display - Nombre de usuario del miembro

  • meta - Tipo de recurso del objeto

  • schemas - Array que contiene identificadores de esquema SCIM

Notas sobre las respuestas de grupo

Filtrado de miembros:

  • Solo se incluyen en las respuestas los miembros que son usuarios externos gestionados por el {externalIdp} especificado

  • Se excluyen los usuarios internos de DocuWare y los usuarios de otros proveedores de identidad externos

  • Los grupos vacíos (sin miembros que cumplan los criterios) pueden seguir apareciendo en los resultados si existen

Identificación de grupos:

  • Los grupos se identifican por su ID para las operaciones GET

  • El displayName se usa para el filtrado y la búsqueda de grupos durante la creación/actualización

Respuestas de error

400 Bad Request - Filtro no válido:

Filtrado por atributo incorrecto:

{

  "ScimType": "invalidFilter",

  "Detail": "Unsupported filter attribute: id",

  "Status": 400,

  "Schemas": [

      "urn:ietf:params:scim:api:messages:2.0:Error"

  ]

}

Filtrado con expresión no válida (la única válida es - filter=displayName eq "groupName"):

{

  "ScimType": "invalidFilter",

  "Detail": "Invalid filter expression: 'displasyname asd \"engineering team\"'",

  "Status": 400,

  "Schemas": [

      "urn:ietf:params:scim:api:messages:2.0:Error"

  ]

}

Filtrado con operador de comparación no admitido:

{

  "ScimType": "invalidFilter",

  "Detail": "Unsupported comparison operator: 'ne'",

  "Status": 400,

  "Schemas": [

      "urn:ietf:params:scim:api:messages:2.0:Error"

  ]

}

404 Not Found - Grupo no encontrado:

{

  "Detail": "Group with identifier 'group-id-404' was not found.",

  "Status": 404,

  "Schemas": [

      "urn:ietf:params:scim:api:messages:2.0:Error"

  ]

}

Actualizar membresía del grupo (PATCH)

La operación PATCH permite actualizaciones parciales de los atributos de grupo mediante operaciones de patch SCIM 2.0. El servicio admite las operaciones add, remove y replace (solo para el displayName del grupo) para la gestión de grupos.

Estructura básica de PATCH

PATCH /{externalIdp}/scim/Groups/{id}

Content-Type: application/scim+json

Authorization: Bearer {token}

{

  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],

  "Operations": [

    {

      "op": "operation_type",

      "path": "attribute_path",

      "value": "new_value_or_array"

    }

  ]

}

Operaciones admitidas

Añadir miembros (add): añade nuevos miembros al grupo sin eliminar los miembros existentes.

vPATCH /{externalIdp}/scim/Groups/{id}

Content-Type: application/scim+json

Authorization: Bearer {token}

{

  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],

  "Operations": [

    {

      "op": "add",

      "path": "members",

      "value": [

        {

          "value": "external-user-id-789"

        },

        {

          "value": "external-user-id-101"

        }

      ]

    }

  ]

}

Eliminar miembros específicos (remove): elimina los miembros especificados del grupo.

PATCH /{externalIdp}/scim/Groups/{id}

Content-Type: application/scim+json

Authorization: Bearer {token}

{

  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],

  "Operations": [

    {

      "op": "remove",

      "path": "members",

      "value": [

        {

          "value": "external-user-id-123"

        },

        {

          "value": "external-user-id-456"

        }

      ]

    }

  ]

}

Eliminar todos los miembros (remove): elimina del grupo todos los miembros que sean usuarios creados por el externalIdp proporcionado (vacía el grupo).

PATCH /{externalIdp}/scim/Groups/{id}

Content-Type: application/scim+json

Authorization: Bearer {token}

{

  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],

  "Operations": [

    {

      "op": "remove",

      "path": "members"

    }

  ]

}

Cuando no se proporciona un value con la operación remove, se eliminan todos los miembros externos (del externalIdp proporcionado).

  1. Reemplazar el nombre para mostrar del grupo (replace) Actualiza el nombre para mostrar del grupo.

PATCH /{externalIdp}/scim/Groups/{id}

Content-Type: application/scim+json

Authorization: Bearer {token}

{

  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],

  "Operations": [

    {

      "op": "replace",

      "path": "displayName",

      "value": "Updated Team Name"

    }

  ]

}

Rutas de atributos admitidas

Ruta

Operaciones

Descripción

Formato de valor

displayName

replace, add

Nombre para mostrar del grupo

String

members

add, remove

Membresía del grupo

Array de objetos de miembro

Múltiples operaciones en una sola solicitud

Puede combinar múltiples operaciones en una sola solicitud PATCH:

PATCH /{externalIdp}/scim/Groups/{id}

Content-Type: application/scim+json

Authorization: Bearer {token}

{

  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],

  "Operations": [

    {

      "op": "replace",

      "path": "displayName",

      "value": "DevOps Engineering Team"

    },

    {

      "op": "add",

      "path": "members",

      "value": [

        {

          "value": "external-user-id-new1"

        }

      ]

    },

    {

      "op": "remove",

      "path": "members",

      "value": [

        {

          "value": "external-user-id-old1"

        }

      ]

    }

  ]

}

Formato del objeto de miembro

Al especificar miembros en las operaciones, utilice este formato:

Campos obligatorios:

  • value - El ID externo del usuario que se desea añadir/eliminar

Ejemplo de objeto de miembro:

{
  "value": "external-user-id-123"
}

Detalles del comportamiento de las operaciones

Operación Add:

  • Añade los miembros especificados al grupo

  • Ignora los miembros que ya pertenecen al grupo (sin duplicados)

  • Los ID externos de usuario inexistentes se ignoran de forma silenciosa

  • No afecta a los miembros existentes

Operación Remove:

  • Con value: elimina solo los miembros especificados (si son usuarios creados desde el externalIdp proporcionado)

  • Sin value: elimina todos los miembros (usuarios creados desde el externalIdp proporcionado) del grupo

  • Ignora los ID externos que no son miembros actuales

  • No afecta a los miembros no especificados

Operación Replace:

  • Para displayName: actualiza el nombre del grupo

Respuestas

  • Respuesta PATCH exitosa (204 No Content)

  • 400 Bad Request - Operación no válida

  • 400 Bad Request - Ruta no válida

  • 400 Bad Request - Formato de miembro no válido

  • 404 Not Found - Grupo no encontrado

  • 409 Conflict - El nombre de grupo ya existe

Notas importantes sobre las operaciones PATCH

Procesamiento de operaciones:

  • Las operaciones se procesan secuencialmente en el orden en que aparecen

Validación de miembros:

  • Los ID externos de usuario deben hacer referencia a usuarios existentes

  • Los ID externos no válidos se ignoran de forma silenciosa (sin error)

  • Solo se gestionan los usuarios externos del mismo proveedor de identidad (externalIdp)

Estado del grupo:

  • La respuesta solo incluye usuarios externos del {externalIdp} especificado

  • Los usuarios internos de DocuWare y los usuarios de otros proveedores de identidad se excluyen de las respuestas

  • Los grupos vacíos siguen siendo válidos y se incluyen en las respuestas

Actualizar grupo (PUT) - Reemplazo completo del grupo

La operación PUT realiza un reemplazo completo de la parte del grupo proporcionada por el externalIdp. A diferencia de PATCH, que solo actualiza los campos especificados, PUT reemplaza el objeto de grupo completo con los datos proporcionados.

Solicitud PUT básica

PUT /{externalIdp}/scim/Groups/{groupId}

Content-Type: application/scim+json

Authorization: Bearer {token}

{

  "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],

  "displayName": "Updated Engineering Team",

  "members": [

    {

      "value": "external-user-id-123"

    },

    {

      "value": "external-user-id-456"

    }

  ]

}

Parámetros

  • {externalIdp} - Identificador del proveedor de identidad externo (azure, okta, ping, etc.)

  • {groupId} - El ID del grupo que se desea actualizar

Campos obligatorios para PUT

Se deben proporcionar todos los campos obligatorios para la creación de grupos:

  • schemas - Identificadores de esquema SCIM (debe incluir "urn:ietf:params:scim:schemas:core:2.0:Group")

  • displayName - Nombre para mostrar del grupo

  • members - Array de objetos de miembro (puede estar vacío)

Ejemplo completo de PUT

PUT /azure/scim/Groups/group-id-123

Content-Type: application/scim+json

Authorization: Bearer {jwt-token}

{

  "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],

  "displayName": "DevOps Engineering Team",

  "members": [

    {

      "value": "external-user-id-789"

    },

    {

      "value": "external-user-id-101"

    }

  ]

}

Respuesta

Éxito (200 OK):

{

  "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],

  "id": "group-id-123",

  "displayName": "DevOps Engineering Team",

  "members": [

    {

      "value": "external-user-id-789",

      "display": "john.doe",

    },

    {

      "value": "external-user-id-101",

      "display": "jane.smith",

    }

  ],

  "meta": {

    "resourceType": "Group"

  }

}

Notas importantes sobre el comportamiento de PUT

  1. Reemplazo completo de miembros: PUT reemplaza toda la lista de miembros gestionada por el externalIdp actual. Los miembros no incluidos en la solicitud se eliminarán del grupo.

  2. Actualización del nombre para mostrar: el nombre para mostrar del grupo se puede cambiar mediante operaciones PUT.

  3. Validación de miembros: todos los ID externos de miembros especificados deben hacer referencia a usuarios existentes. Los ID externos no válidos se omitirán de forma silenciosa.

  4. Ámbito del proveedor de identidad externo: esta operación solo gestiona los miembros que son usuarios externos del {externalIdp} especificado. Los usuarios internos de DocuWare y los usuarios de otros proveedores de identidad no se ven afectados.

  5. Identificación del grupo: el grupo se identifica mediante el parámetro {groupId} en la URL.

Respuestas de error

400 Bad Request - Campos obligatorios ausentes:

{

  "ScimType": "invalidValue",

  "Detail": "Validation failed: DisplayName: is required",

  "Status": 400,

  "Schemas": [

      "urn:ietf:params:scim:api:messages:2.0:Error"

  ]

}

404 Not Found - Grupo no encontrado:

{

  "Detail": "Group with identifier 'group-id-404' was not found.",

  "Status": 404,

  "Schemas": [

      "urn:ietf:params:scim:api:messages:2.0:Error"

  ]

}

Reglas de validación para PUT

Todas las reglas de validación de las operaciones POST se aplican a las operaciones PUT:

  • DisplayName: obligatorio, distingue entre mayúsculas y minúsculas, no debe estar vacío ni contener solo espacios en blanco

  • Members: array opcional. Cada miembro debe tener un campo value válido con el ID externo de un usuario existente

  • ID externos de miembros: deben hacer referencia a usuarios existentes del mismo proveedor de identidad externo

  • Schemas: debe incluir el esquema Core Group

Eliminar grupo (DELETE) - No admitido

La operación DELETE para grupos no es admitida por el servicio DocuWare User Provisioning v3. Si intenta eliminar un grupo, se devolverá una respuesta de error.

Códigos de estado HTTP

Código de estado

Descripción

Uso

200 OK

Éxito

Operaciones GET, PATCH

201 Created

Recurso creado

Operaciones POST

204 No Content

Éxito, sin contenido

Operaciones DELETE, algunas operaciones PATCH

400 Bad Request

Solicitud no válida

Errores de validación

401 Unauthorized

Autenticación requerida

Token ausente o no válido

403 Forbidden

Acceso denegado

Permisos insuficientes

404 Not Found

Recurso no encontrado

ID de recurso no válido

409 Conflict

Conflicto de recurso

Nombre de usuario o correo electrónico duplicado

500 Internal Server Error

Error del servidor

Problemas del servicio

501 Not Implemented

No implementado

No admitido por el producto

Formato de respuesta de error

{

  "ScimType": "invalidValue",

  "Detail": "Validation failed.",

  "Status": 400,

  "Schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"]

}

Requisitos de configuración

Configuración del proveedor de identidad

  1. Configure su IdP para que apunte a la URL de tenant adecuada

  2. Configure la autenticación OAuth 2.0/OIDC con tokens JWT

  3. Configure los ámbitos correctos: docuware.userProvisioning

  4. Asegúrese de que el usuario que realiza las operaciones de la API tenga permisos suficientes.

Proveedores de identidad admitidos

  • Azure Entra ID (Azure AD): utilice azure como externalIdp

  • Okta: utilice okta como externalIdp

  • Ping Identity: utilice ping como externalIdp

  • On-Premise: utilice onpremise como externalIdp

  • IdP genérico

Información de esquemas

Obtener esquemas disponibles

GET /{externalIdp}/scim/Schemas
Authorization: Bearer {token}

Obtener tipos de recursos

GET /{externalIdp}/scim/ResourceTypes  
Authorization: Bearer {token}

Comprobación de estado

Disponibilidad del servicio

GET /AvailabilityCheck

Este endpoint no requiere autenticación y devuelve 200 OK si el servicio está en funcionamiento.

Ejemplos de flujos de trabajo de integración

Flujo de trabajo completo de aprovisionamiento de usuarios

  1. Crear usuario: POST a /Users con los datos del usuario

  2. Verificar la creación: GET a /Users/{id} para confirmar

  3. Actualizar usuario: PATCH a /Users/{id} para realizar cambios

  4. Añadir a grupos: PATCH a /Groups/{groupId} para añadir al usuario

  5. Desactivar: PATCH a /Users/{id} con active: false

Flujo de trabajo de gestión de grupos

  1. Crear grupo: POST a /Groups con los datos del grupo

  2. Añadir miembros: PATCH a /Groups/{id} con operaciones add

  3. Actualizar nombre: PATCH a /Groups/{id} con cambio de displayName

  4. Eliminar miembros: PATCH a /Groups/{id} con operaciones remove

Esta API proporciona una interfaz sólida y conforme a los estándares para gestionar usuarios y grupos en DocuWare a través de proveedores de identidad externos, manteniendo las mejores prácticas de seguridad y rendimiento.

Versiones compatibles: DocuWare Cloud + 7.13