pingidentity / scim2

The UnboundID SCIM 2.0 SDK for Java

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Include both core and extension schema in application/scim+json representation

michel-zedler opened this issue · comments

Use Case: I need to extend the core user schema with some additional attributes.

In the com.unboundid.scim2.server.annotations.ResourceType annotation I can specify:
schema=com.unboundid.scim2.common.types.UserResource requiredSchemaExtensions = my.custom.UserExtension
then the /Schemas endpoint will correctly expose both schemas
and the /ResourceTypes endpoint will correctly reference both schemas:
"schema": "urn:ietf:params:scim:schemas:core:2.0:User", "schemaExtensions": [ { "schema": "urn:ietf:params:scim:schemas:extension:mycustom:2.0:User", "required": true } ],

I understand from the Enterprise User Extension Representation example in https://tools.ietf.org/html/rfc7643#section-8.3
that the schemas attribute must reference all relevant schemas
but I seem to be unable to achieve this with the current SDK.

When I have my.custom.UserExtension extend BaseScimResource
and return my.custom.UserExtension or ListResponse<my.custom.UserExtension> in a GET response
schemas it will only reference the schema extension
(urn:ietf:params:scim:schemas:extension:mycustom:2.0:User
and not urn:ietf:params:scim:schemas:core:2.0:User).
Also this does not allow me to expose any core attributes in the response.

Currently I could have my.custom.UserExtension extend com.unboundid.scim2.common.types.UserResource but that would redefine all core attributes in the schema extension.

I would like to be able to extend com.unboundid.scim2.common.types.UserResource,
have the GET response reference both schemas (urn:ietf:params:scim:schemas:extension:mycustom:2.0:User
and not urn:ietf:params:scim:schemas:core:2.0:User)
and urn:ietf:params:scim:schemas:extension:mycustom:2.0:User schema exposed by /Schemas be clean of attributes inherited from the com.unboundid.scim2.common.types.UserResource.

Java class extension is the wrong approach, instead it can be achieved by using com.unboundid.scim2.common.BaseScimResource#setExtension
e.g. on a UserResource object instance - then the com.fasterxml.jackson.databind.ObjectMapper provided by com.unboundid.scim2.common.utils.JsonUtils#createObjectMapper will to the trick.

@michel-zedler, do you mind giving more information about this? I have set the extension on a UserResource, but I can only see the schema URN showing up in the schemasUrn" field; I don't see the urn:ietf:params:scim:schemas:extension:enterprise:2.0:User field populated with the values I set.

@iinuwa I needed to register the ObjectMapper provided as JAX-RS provider for application/scim+json:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.unboundid.scim2.common.utils.ApiConstants;
import com.unboundid.scim2.common.utils.JsonUtils;

import javax.ws.rs.Produces;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;

@Provider
@Produces({ApiConstants.MEDIA_TYPE_SCIM})
class JacksonScimConfig implements ContextResolver<ObjectMapper> {

    ObjectMapper mapper = JsonUtils.createObjectMapper();

    @Override
    public ObjectMapper getContext(Class<?> type) {
        return mapper;
    }
}

Ah, ok. Thanks!

Your post made me realize that I was doing that already and that the ObjectMapper I registered wasn't being used. A couple of searches on StackOverflow led me to this answer that showed me I needed to remove the jersey-media-json-binding dependency generated by the Grizzly project archetype that I used in order for it to work.

Here's how I'm doing it (stolen from example in scim2-server-sdk tests):

final ResourceConfig config = new ResourceConfig();
// ...
JacksonJsonProvider provider =
        new JacksonJsonProvider(JsonUtils.createObjectMapper());
provider.configure(JaxRSFeature.ALLOW_EMPTY_INPUT, false);
config.register(provider);

All is well, thank you!