Shared attributes
According to the SWITCH edu-ID architecture, there are three sources for attributes of a user:
- The user, by self-declaring personal information in My Account,
- The participating organisations - universities who define attributes of affiliated users,
- Complementary attribute sources.
The shared attribute service described here is a complementary attribute source. It allows basically arbitrary services or applications (a client) to set specific attribute values for users. These attributes can then be made available to selected services.
- For each user, the client can set or reset a predefined yes/no property. It is represented in the API as group membership: the user is either member of a group or not.
- The yes/no property is translated by the SWITCH edu-ID IdP into an attribute value. The attribute is either present or not.
- The attribute value will only be seen by a set of selected SPs
Typical applications are:
- An organization gives access to their resources by setting an organizational membership flag for their members.
- The National Licenses registration platform entitles users to access to research publications at various publishers.
- A university needs to collaborate with people who are not official university member. A registration platform of for temporary members taggs selected user as "affiliates", and gives them access to collaboration platforms.
Prerequisites:
- Consuming SPs need to support (=understand) the specific attribute value
- To use the API and to define groups an agreement has to be made between the client and SWITCH. Please contact the edu-ID team: eduid@switch.ch
Current limitations:
- Currently, only setting values for the eduPersonEntitlement attribute is implemented.
API to set and share selected attributes
The shared attribute API uses a subset of the SCIM specification to set and reset group memberships.
Roles:
- SWITCH edu-ID is SCIM service provider
- an external service is SCIM client
Authentication and permissions:
Basic Authentication. An API-user is set up by the SWITCH edu-ID team on request.
The permissions of an API-user can be adjusted finely. Depending on the requirements, the following permissions can be granted to an API-user: GET-Users, POST-Users, PATCH-Groups, GET-Groups, POST-Groups.
Attributes supported in the profile:
- Users:
- id : issued by the SCIM service
- externalID: corresponds to the SWITCH edu-ID unique ID
- Groups:
- id: issued by the SCIM service
Basic steps to set and reset group memberships for a user:
- Create a user (users-POST request) with the Swiss edu-ID unique-ID as externalID
- This returns a record with an internal ID of that user
- The POST request can be repeated without any harm
- To retrieve the user’s group membership make a users-GET request and read the groups object
- To add a user to a group make a groups-PATCH request
- To remove a user from a group make a groups-PATCH request with a path expression
- To retrieve the members of a group make a groups-GET request
The required group(s) will be created for the client by the SWITCH edu-ID team.
SCIM API Reqeuests
API endpoints:
- Test base url: https://test.eduid.ch/sg/index.php
- Production base url: https://eduid.ch/sg/index.php
In the examples below, the REST service endpoint base url is https://eduid.ch/sg/index.php/.
Create a new user
Before a user can be associated to groups, an internal user record has to be created. The record contains the internal identifier "id", which is used to add or remove a user in a group.
POST /sg/index.php/Users
The body must contain information about the new user in JSON format as shown in the following example:
{ "externalID":"1234567@eduid.ch"
}
Results:
HTTP/1.1 200 OK Content-Type: application/scim+json { "id":"2819c223-7f76-453a-919d-413861904646", "externalID":"1234567@eduid.ch", "meta": { "created":"2016-07-24T11:29:51Z", "modified":"2016-07-24T11:51:09Z" }, "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"] }
Notes:
- If the user with externalID 1234567@eduid.ch already exists, 200 OK is returned including the result body, and no data is modified in the directory.
- externalID can be any identifier that is shared by SPs who share group information. In most cases it is recommended to use swissEduPersonUniqueID as externalID. SPs that are part of the organizational identity management processes may also use the identifier swissEduId.
Add a user to a group
To add an existing user (with the internal "id" 2819c22...) to an existing group (acbf3ae...):
PATCH /Groups/acbf3ae7-8463-425b-bded-9b4da3f908ce Content-Type: application/scim+json { "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations":[ { "op":"add", "path":"members", "value":[ { "$ref": "https://eduid.ch/sg/index.php/Users/2819c223...413861904646", "value": "2819c223-7f76-453a-919d-413861904646" } ] } ] }
Response: (if successful)
HTTP/1.1 204 No Content Location: "https://eduid.ch/sg/index.php/Groups/acbf3ae7-8463-...-9b4da3f908ce"
Remove a user from a group
To remove the member (with the internal "id" 2819c22...) from the group (acbf3ae...) use a PATCH operation with a path expression:
PATCH /sg/index.php/Groups/acbf3ae7-8463-425b-bded-9b4da3f908ce Accept: application/scim+json Content-Type: application/scim+json { "Schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations":[{ "op":"remove", "path":"members[value eq \"2819c223-7f76-...413861904646\"]" }] }
Response:
Retrieve all members of a group
Find all users in an existing group (acbf3ae...):
GET /Groups/acbf3ae7-8463-425b-bded-9b4da3f908ce
Example response: (if successful)
HTTP/1.1 200 OK
Content-Type: application/scim+json
{
"id":"acbf3ae7-8463-425b-bded-9b4da3f908ce",
"displayName":"Test Group",
"schemas":["urn:ietf:params:scim:schemas:core:2.0:Group"],
"members":[
{"value":"2819c223-7f76-453a-919d-413861904646", "display":" "},
{"value":"c626d45b-2bbd-483d-8d34-9c1c6dc5fdc3", "display":" "}
]
}
Note: To use this function, the API user needs to have the permission "GET-groups".
Retrieve an internal User-ID by the Swiss edu-ID unique ID
Request:
GET /sg/index.php/Users?filter=externalID eq “1234567@eduid.ch” Host: eduid.ch Accept: application/scim+json
Example response:
HTTP/1.1 200 OK Content-Type: application/scim+json { "schemas":["urn:ietf:params:scim:api:messages:2.0:ListResponse"], "totalResults":1, "Resources":[ { "id":"e64a2bef-02f2-4a67-8f29-6121a8f4aff3", } ] }
Retrieve a user by the internal User-ID
and check his/her group membership:
GET /sg/index.php/Users/e64a2bef-02f2-4a67-8f29-6121a8f4aff3
Example response:
HTTP/1.1 200 OK Content-Type: application/scim+json { "id":"e64a2bef-02f2-4a67-8f29-6121a8f4aff3", "externalID":"1234567@eduid.ch", "groups": [ { "value":"acbf3ae7-8463-425b-bded-9b4da3f908ce", "display":"Test Group" } ], "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"] }
This user is a member of the group “National Library License Compliant”
Error responses
Error responses that can be issued for all of the above GET, POST and PATCH requests:
The authentication failed
Response:
HTTP/1.1 401 Unauthorized Content-Type: application/scim+json
Not authorized
The authentication was ok, but the client is not authorized to do this operation.
Response:
HTTP/1.1 403 Forbidden Content-Type: application/scim+json
Not found
If the referenced user or group does not exist.
Response:
HTTP/1.1 404 Not Found Content-Type: application/scim+json
Test Sequence Example
- Endpoint base URL:
https://test.eduid.ch/sg/index.php/
- User external ID:
1234567@eduid.ch
- Group internal ID:
f4d40595-6d7d-41bc-9fa2-7139d2fcf892
1) Create a user (can also be safely used to determine the internal 'id' of an existing user)
curl --user apiuser:passwd -X POST \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ --data '{ "externalID":"1234567@eduid.ch" }' https://test.eduid.ch/sg/index.php/Users
Response:
{"externalID":"1234567@eduid.ch","schemas":["urn:ietf:params:scim:schemas:core:2.0:User"],"id":"6943fc0d-61a5-4dc8-a7fa-234243323a49"}
2) Get the user, and his/her group membership information using the internal id
curl --user apiuser:passwd https://test.eduid.ch/sg/index.php/Users/6943fc0d-61a5-4dc8-a7fa-234243323a49
Response:
{"id":"6943fc0d-61a5-4dc8-a7fa-234243323a49","externalID":"1234567@eduid.ch","schemas":["urn:ietf:params:scim:schemas:core:2.0:User"],"groups":[]}
(here, the user belongs to no group)
3) Add a user
add the user 6943fc0d-61a5-4dc8-a7fa-234243323a49
to the group f4d40595-6d7d-41bc-9fa2-7139d2fcf892
:
Precondition: the user and the group must already exist
curl --user apiuser:passwd -X PATCH \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ --data '{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations":[ { "op":"add", "path":"members", "value":[ { "$ref": "https://test.eduid.ch/sg/index.php/Users/6943fc0d-61a5-4dc8-a7fa-234243323a49", "value": "6943fc0d-61a5-4dc8-a7fa-234243323a49" } ] } ] }' https://test.eduid.ch/sg/index.php/Groups/f4d40595-6d7d-41bc-9fa2-7139d2fcf892
Response:
HTTP/1.1 200 OK
4) Get the user, and his/her group membership information using the internal id
curl --user apiuser:passwd https://test.eduid.ch/sg/index.php/Users/6943fc0d-61a5-4dc8-a7fa-234243323a49
Response:
{"id":"6943fc0d-61a5-4dc8-a7fa-234243323a49","externalID":"1234567@eduid.ch","schemas":["urn:ietf:params:scim:schemas:core:2.0:User"],"groups":[{"value":"f4d40595-6d7d-41bc-9fa2-7139d2fcf892","display":"National Licenses Programme"}]}
The groups object is not empty now.
5) Remove a user
Remove the user 6943fc0d-61a5-4dc8-a7fa-234243323a49
from the group f4d40595-6d7d-41bc-9fa2-7139d2fcf892
:
curl --user apiuser:passwd -X PATCH \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ --data '{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations":[ { "op":"remove", "path":"members[value eq \"6943fc0d-61a5-4dc8-a7fa-234243323a49\"]" } ] }' https://test.eduid.ch/sg/index.php/Groups/f4d40595-6d7d-41bc-9fa2-7139d2fcf892
Response:
HTTP/1.1 200 OK
Web GUI
The above requests can also be made using the human-friendly web GUI that is available here:
GUI endpoints:
- Test GUI url: https://test.eduid.ch/sg/gui/
- Production GUI url: https://eduid.ch/sg/gui/
To access the GUI, client credentials are required.
Example case: National licenses (shared yes/no property)
In the national licenses case a registration service decides for each user if he/she is entitled to have access to contents of publishers who participate in the programme. For each user who has access, the shared property “national-license-compliant” is written to a shared database. The Swiss edu-ID IdP reads the shared database and sets the attribute “common-lib-terms” for the users who are entitled to have access to the contents.
In this use case, SWITCH edu-ID acts as a SCIM service and the national license registration platform as SCIM client.
Available SCIM API endpoints:
POST /Users
GET /Users/{id}
GET /Users?filter
PATCH /Groups
POST /Groups
(not for public use)PUT /Groups
(not for public use)DELETE /Groups
(not for public use)
Example case: Grant access to digital content for private cantonal library members
Cantonal libraries are legally mandated to provide access to digital publications to their patrons. These are typically private persons who meet particular conditions like
- They are mostly cantonal residents
- They showed up in person at a library’s service desk for registration
Example case: Manage loosely coupled affiliates at FHNW
Requirements:
- The organization needs to manage accounts for affiliates
- The affiliates are not enrolled at the organization and they do not get an organizational account
Solution concept:
- The affiliates get a SWITCH edu-ID...
- ... and registered at a registration service of the organization
- the organization sets the shared property "org-affiliate" for selected users
- the edu-ID IdP translates the property to an entitlement attribute