Using SCIM v1.1 as Data Source

Note

Examples are not URL encoded, but MUST be encoded according to RFC 3896 section 2.1.

Client Authentication

The Identity Server can authenticate to a SCIM server using either:

  1. Mutual TLS
  2. Basic authentication over one-way TLS

In the first case, the Identity Server proves its identity using an X.509 certificate. This is the strongest means of authentication possible and is recommended. In the latter case, the SCIM server is authenticated to the Identity Server using an X.509 SSL certificate. The Identity Server authenticates to the SCIM server using a shared secret. To keep this credential secure, HTTPS is used to encrypt the traffic between the two entities.

Required SCIM operations

Authenticating users

Authenticating users is done using the “filter” option on the /Users resource

GET /Users?filter=userName+eq+"bjensen"+and+password+eq+a_plaintext_password HTTP/1.1

On a successful authentication the SCIM server should respond with a 200 OK a single entry in a list of User objects. This entry contains all the attributes for the User.

  • Note that the password attribute NEVER shall be returned from the server.
  • We assume that userName is a unique attribute for the User.

Example Request

GET /Users?filter=userName+eq+"bjensen"+and+password+eq+a_plaintext_password+and+active+eq+true HTTP/1.1
Host: example.com
Accept: application/json

Example successful Response

Headers

HTTP/1.1 200 OK
Content-Type: application/json

Body

{
    "totalResults":1,
    "schemas": [
        "urn:scim:schemas:core:1.0",
        "urn:scim:schemas:extensions:external-ids:1.0"
    ],
    "Resources":[
    {
        "schemas":["urn:scim:schemas:core:1.0"],
        "id":"2819c223-7f76-453a-919d-413861904646",
        "externalId":"bjensen",
        "meta":{
            "created":"2015-08-01T21:32:44Z",
            "lastModified":"2015-08-01T21:32:44Z",
            "location":"https://example.com/v1/Users/2819c223-7f76-453a-919d-413861904646",
            "version":"W\/\"e180ee84f0671b1\""
        },
        "name":{
            "formatted":"Ms. Barbara J Jensen III",
            "familyName":"Jensen",
            "givenName":"Barbara"
        },
        "userName":"bjensen",
        "emails" : [
            {"value" : "bjensen@example.com", "primary" : true}
        ],
        "urn:scim:schemas:extensions:external-ids:1.0": {
            "externalIds": [
            {
                "value": "bjensen@example.com",
                "type": "domain1",
                "description": "Some description"
            },
            {
                "value": "ted@mail.com",
                "type": "domain2"
            }]
        }
    }]
}

Example failure to authenticate (incorrect username or password)

Headers

HTTP/1.1 200 OK
Content-Type: application/json

Body

{
    "totalResults":0,
    "schemas":["urn:scim:schemas:core:1.0"],
    "Resources":[]
}

Responding with a 404 is accepted as long as the response body contains the above information.

Creating Users

Creating a new User requires the following attributes to be possible to be set

  • userName
  • password
  • email (primary)
  • active (true or false, if account verficaction is used, this is set to false on create)

By default the following attributes are also included.

  • name
  • givenName
  • familyName
  • phoneNumber (primary but optional)

Other attributes are possible to add in the Create Account form, and will be forwarded according to the SCIM specification to the backend.

Verifying a User Account

TBD

Fetching user data

Fetching user data during authentication is done according to the section “Authenticating users”. But to support forgotten username or forgotten password, the ID Server needs to be able to query the Data Source with the following filtering options.

Filter by primary email

GET /Users?filter=emails.value+eq+"bjensen@example.com"+and+emails.primary+eq+true HTTP/1.1
Host: example.com
Accept: application/json

Successful Response

Headers

HTTP/1.1 200 OK
Content-Type: application/json

Body

{
    "totalResults":1,
    "schemas": [
        "urn:scim:schemas:core:1.0",
        "urn:scim:schemas:extensions:external-ids:1.0"
    ],
    "Resources":[
    {
        "schemas":["urn:scim:schemas:core:1.0"],
        "id":"2819c223-7f76-453a-919d-413861904646",
        "externalId":"bjensen",
        "meta":{
            "created":"2015-08-01T21:32:44Z",
            "lastModified":"2015-08-01T21:32:44Z",
            "location":"https://example.com/v1/Users/2819c223-7f76-453a-919d-413861904646",
            "version":"W\/\"e180ee84f0671b1\""
        },
        "name":{
            "formatted":"Ms. Barbara J Jensen III",
            "familyName":"Jensen",
            "givenName":"Barbara"
        },
        "userName":"bjensen",
        "emails" : [
            {"value" : "bjensen@example.com", "primary" : true}
        ],
        "urn:scim:schemas:extensions:external-ids:1.0": {
            "externalIds": [
            {
                "value": "bjensen@example.com",
                "type": "domain1",
                "description": "Some description"
            },
            {
                "value": "ted@mail.com",
                "type": "domain2"
            }]
        }
    }]
}

Failure Response (Not found)

Headers

HTTP/1.1 200 OK
Content-Type: application/json

Body

{
    "totalResults":0,
    "schemas":["urn:scim:schemas:core:1.0"],
    "Resources":[]
}

Responding with a 404 is accepted as long as the response body contains the above information.

If the SCIM Service Provider responds with more than one user matching the filter, the ID server will treat this as an error, and will assume that a user cannot be found based on email.

Filter by userName

GET /Users?filter=userName+eq+"bjensen@example.com" HTTP/1.1
Host: example.com
Accept: application/json

Successful Response

Headers

HTTP/1.1 200 OK
Content-Type: application/json

Body

{
    "totalResults":1,
    "schemas": [
        "urn:scim:schemas:core:1.0",
        "urn:scim:schemas:extensions:external-ids:1.0"
    ],
    "Resources":[
    {
        "schemas":["urn:scim:schemas:core:1.0"],
        "id":"2819c223-7f76-453a-919d-413861904646",
        "externalId":"bjensen",
        "meta":{
            "created":"2015-08-01T21:32:44Z",
            "lastModified":"2015-08-01T21:32:44Z",
            "location":"https://example.com/v1/Users/2819c223-7f76-453a-919d-413861904646",
            "version":"W\/\"e180ee84f0671b1\""
        },
        "name":{
            "formatted":"Ms. Barbara J Jensen III",
            "familyName":"Jensen",
            "givenName":"Barbara"
        },
        "userName":"bjensen",
        "emails" : [
            {"value" : "bjensen@example.com", "primary" : true}
        ],
        "urn:scim:schemas:extensions:external-ids:1.0": {
            "externalIds": []
        }
    }]
}

Failure Response (Not found)

Headers

HTTP/1.1 200 OK
Content-Type: application/json

Body

{
    "totalResults":0,
    "schemas":["urn:scim:schemas:core:1.0"],
    "Resources":[]
}

Responding with a 404 is accepted as long as the response body contains the above information.

Required User Attributes

To support the basic User model, the following attributes are assumed to exist with the following preconditions

Attribute Name Attribute Value Pre condition
userName The given Id of the user (given when logging in) globally unique
password The password for the user. Provided as plaintext when the account is created or the user resets the password  
emails The email can be used to lookup usernames for users when their username is lost. Optional. One globally unique email set with the attribute “primary” must exist per user if reset password and forgotten username should be supported.
phoneNumbers If SMS authentication should be used, this attribute must be set for the user Optional. One “primary” phoneNumber must exist for SMS functions to be available

Note

externalIds is also assumed to be supported if account linking is desired. See below.

Linking Accounts

To link account, the service provider must support an extension to the SCIM protocol that allows the SCIM client (i.e., the Identity Server) to set multiple related account IDs for a user. These related IDs will be the ones that are linked to the user’s identity. They can be from any domain or security realm. Therefore, the client will also store the name of the domain from which the linked ID resides.

In particular, the service provider must support an additional multi-valued attribute in the user model. This attribute is called externalIds and is in the urn:scim:schemas:extensions:external-ids:1.0 schema. Each of these attributes has a value, a type, and a description attribute. The value is the foreign user ID (i.e., the one being linked). This is the ID of the linkee in some other security realm. To know which domain the user ID is from, the type will contain the domain or realm of the user. This might be something like facebook, legacy_app_1, etc. Optionally, a description can also be included.

Typically, the user ID that is having these links added to it is the global or primary user ID in your organization, whereas the linked ones are secondary or auxiliary IDs. Linking can be bidirectional, however, and the user ID in the URI may actually be some secondary account ID whereas the linked on is a global account ID. Both use cases are viable.

A sample request and response is shown below:

Headers

PUT /Users/2819c223-7f76-453a-919d-413861904646 HTTP/1.1
Host: example.com
Accept: application/json
Content-Type: application/json

Body

{
    "schemas": [
        "urn:scim:schemas:core:1.0",
        "urn:scim:schemas:extensions:external-ids:1.0"
    ],
    "id":"2819c223-7f76-453a-919d-413861904646",
    "userName":"bjensen",
    "externalId":"bjensen",
    "name":{
        "formatted":"Ms. Barbara J Jensen III",
        "familyName":"Jensen",
        "givenName":"Barbara",
        "middleName":"Jane"
    },
    "emails" : [
        {"value" : "bjensen@example.com", "primary" : true}
    ],
    "urn:scim:schemas:extensions:external-ids:1.0": {
        "externalIds": [
        {
            "value": "bjensen@domain1.com",
            "type": "domain1",
            "description": "Some description"
        }]
    }
}

Successful Response

Headers

HTTP/1.1 200 OK
Content-Type: application/json
Location: https://example.com/v1/Users/2819c223-7f76-453a-919d-413861904646

Body

{
    "schemas": [
        "urn:scim:schemas:core:1.0",
        "urn:scim:schemas:extensions:external-ids:1.0"
    ],
    "id":"2819c223-7f76-453a-919d-413861904646",
    "userName":"bjensen",
    "externalId":"bjensen",
    "name":{
        "formatted":"Ms. Barbara J Jensen III",
        "familyName":"Jensen",
        "givenName":"Barbara",
        "middleName":"Jane"
    },
    "emails" : [
        {"value" : "bjensen@example.com", "primary" : true}
    ],
    "urn:scim:schemas:extensions:external-ids:1.0": {
        "externalIds": [
        {
            "value": "bjensen@domain1.com",
            "type": "domain1"
        }]
    }
    "meta": {
        "created":"2011-08-08T04:56:22Z",
        "lastModified":"2011-08-08T08:00:12Z",
        "location":"https://example.com/v1/Users/2819c223-7f76-453a-919d-413861904646",
        "version":"W\/\"b431af54f0671a2\""
    }
}

Devices

In many scenarios, devices need to be associated with a particular user account. This is usually the case when 2-factor authentication is deployed. To provide stronger authentication using something the user has, devices of different sorts and types need to be associated with a user account. Afterwards, the devices associated with a user account need to be queried, so that authentication using such devices can be performed. This association and retrieval of devices on a per user basis can be done using the SCIM credential backend with an Account Manager.

Neither version of the SCIM standard provides a way of storing a user’s devices like this. SCIM does provide a flexible extension mechanism that can be used for this purpose, however. Similarly to the schema extensions described in the previous subsection for account linking, a SCIM server must support the following extension if devices are to be stored with user accounts.

To provide these types of device storage capabilities, the SCIM service provide must support a complex type called devices which is in the urn:scim:schemas:extensions:devices:1.0 schema. This list will contain zero or more device objects that are connected with the enclosing user account. Each device will have the following attributes:

Attribute Name Required Explanation and Meaning
id Yes A unique ID of the device for the given type
type Yes The device type (i.e., make, manufacturer, provider, class)
deviceName Yes The name of the device (e.g., “my iPad” or “blue key fob”)
externalId No The identifier or number used externally to recognize the device (e.g., a phone number or a company-provided asset tag)
owner No The owner of the device which may or may not be the same as the user to which the device is associated. If it is not provided, it is assumed that the associated user is the owner
formFactor No The form of the device (e.g., laptop, tablet, mobile phone, desktop, other)

A device also contains various metadata, similarly to the user object itself. Unlike the standard metadata of a user, however, a device can also contain an expiresAt meta property that indicates when the device association to the user expires. This can be very helpful when implementing temporary connections between a user and a device. This sort of temporal association is common when the device is shared amongst a group of users (e.g., in a hospital ward or school).

A sample request and response containing a user’s devices is shown below:

Headers

GET /Users/2819c223-7f76-453a-919d-413861904646 HTTP/1.1
Host: example.com
Accept: application/json

Successful Response

Headers

HTTP/1.1 200 OK
Content-Type: application/json
Location: https://example.com/v1/Users/2819c223-7f76-453a-919d-413861904646

Body

{
    "schemas": [
        "urn:scim:schemas:core:1.0",
        "urn:scim:schemas:extensions:devices:1.0"
    ],
    "meta": {
        "created":"2011-08-08T04:56:22Z",
        "lastModified":"2011-08-08T08:00:12Z",
        "location":"https://example.com/v1/Users/2819c223-7f76-453a-919d-413861904646",
        "version":"W\/\"b431af54f0671a2\""
    },
    "id":"2819c223-7f76-453a-919d-413861904646",
    "userName":"bjensen",
    "externalId":"bjensen",
    "urn:scim:schemas:extensions:devices:1.0": {
        "devices": [
        {
            "id": "456789",
            "deviceName": "Blue NFC Yubikey",
            "formFactor": "fob",
            "type": "yubikey",
            "meta": {
                "created": "2010-01-23T04:56:22Z",
                "lastModified": "2011-05-13T04:42:34Z",
                "version": 1,
            }
        },
        {
            "id": "AE79F230-CDA0-4248-B85C-F3B43BE4715A",
            "externalId": "+1-530-450-5565",
            "deviceName": "iPhone",
            "formFactor": "phone",
            "type": "encapApp1",
            "meta": {
                "created": "2010-01-23T04:56:22Z",
                "lastModified": "2011-05-13T04:42:34Z",
                "version": 55,
                "expiresAt": "2010-01-23T10:56:22Z"
            }
        },
        {
            "id": "4563456",
            "deviceName": "MyGoodLaptop",
            "formFactor": "laptop",
            "type": "smartcardReader1",
            "owner": "Acme, Inc.",
            "meta": {
                "created": "2010-01-23T04:56:22Z",
                "lastModified": "2011-05-13T04:42:34Z",
                "version": "v22"
            }
        }]
    }
}