Design
- This is a pure SCIM API with extensions and new Resource Types
- PennState implemented a generic SCIM server in their github. Grouper is using that as a third party library. None of our work (except perhaps pull requests) is stored there
- Since 2.6.17, a second SCIM service is part of Grouper web services using a different library, so JSON objects look slightly different (mostly by following RFC 7643 more closely)
- The PennState version will eventually go away, since it is Grouper's only dependence on J2EE and thus TomEE
- The Grouper SCIM adapter is a grouper component in Grouper's Internet Github repo
Note, there is also the SCIM change log consumer
Steps to run SCIM in a Grouper container
For the PennState implementation, set grouper.hibernate.properties value grouper.is.scim = true
, or set environment variable GROUPER_SCIM=true
. The enpoint URI's will be /grouper-ws-scim/v2/ (e.g. http://localhost:8080/grouper-ws-scim/v2/Groups/systemName:etc:sysadmingroup)
For the Grouper WS implementation set grouper.hibernate.properties value grouper.is.ws = true
and grouper.is.scim = true
, or set environment variables GROUPER_WS=true
and GROUPER_SCIM=true
. The endpoint URI's will be /grouper-ws/scim/v2/ (e.g. http://localhost:8080/grouper-ws/scim/v2/Groups/systemName:etc:sysadmingroup)
Steps to run SCIM server locally. First four steps are to install docker on Mac.
- Download Docker Toolbox from https://www.docker.com/products/docker-toolbox and install it. It's a simple few steps wizard. By default, it will be installed in /usr/local/bin.
- Launch Docker Quick Start Terminal (First time when you open this application, it will create a "default" machine under ~/.docker)
- Towards the bottom of the terminal, there will be a message something like: docker is configured to use the default machine with IP 192.168.99.100
- Set the environment variables below. Chane the DOCKER_CERT_PATH value. DOCKER_HOST is the same as mentioned in step 3.export DOCKER_TLS_VERIFY="1"export DOCKER_HOST="tcp://192.168.99.100:2376"export DOCKER_CERT_PATH="/Users/vsachdeva/.docker/machine/machines/default"export DOCKER_MACHINE_NAME="default"
- Run command: "docker run hello-world" from the terminal. I run it just to make sure that the installation was correct.
- Checkout scim project by running: "git clone https://github.com/PennState/SCIMple-Identity.git" (It should automatically be on develop branch. Switch if already not)
- Checkout tier project by running: "git clone https://github.com/PennState/tier.git" (It should automatically be on develop branch. Switch if already not)
- Checkout commons-jaxrsbyrunning: "git clone https://github.com/PennState/commons-jaxrs.git" (It should automatically be on develop branch. Switch if already not)
- Run "mvnclean install" from common-jaxrsproject
- Run "mvnclean install" from SCIMple-Identity project
- Run "mvnclean install -Pdocker" from tier project (It might take a few minutes the first time since it has to download the jboss/widlflyimagefrom internet). If it fails saying: Failed to execute
goal io.fabric8:docker-maven-plugin:0.14.2:build (build) onprojecteduperson-scim-web: Unable to build image [eduperson-scim-server]: Unknown instruction: --SILENT. In theeduperson-scim-web/pom.xml, put --silentin the same line as the command. It's around line # 108. - Run "docker run --rm -it -p 8080:8080 -p 9990:9990 eduperson-scim-server"
- Hit this URL http://192.168.99.100:8080/tier/v2/Schemas to verify that server is up and running (You might have to change the IP. It would be same as in step # 3 above)
- You can access the management console of wildflyserver by going to http://192.168.99.100:9990/
Grouper TIER SCIM on demo server
- Grouper TIER SCIM is on the
- It runs in 2.3 under tomcat_h
- The URL is on the demo server which is: https://grouperdemo.internet2.edu/grouper-ws-scim_v2_3/
tomcat_h has:
[appadmin@i2midev1 grouper-ws-scim_v2_3]$ more /etc/init.d/tomcat_h export CATALINA_BASE="/opt/tomcats/tomcat_h" export JAVA_HOME="/opt/javas/java_h" export TOMCAT_HOME="/opt/tomee7base" [appadmin@i2midev1 grouper-ws-scim_v2_3]$ ls -latr /opt/tomee7base lrwxrwxrwx 1 appadmin users 29 Jul 22 12:42 /opt/tomee7base -> apache-tomee-webprofile-7.0.1 [appadmin@i2midev1 grouper-ws-scim_v2_3]$ ls -latr /opt/javas/java_h lrwxrwxrwx 1 appadmin users 8 Jul 22 18:35 /opt/javas/java_h -> ../java8 [appadmin@i2midev1 grouper-ws-scim_v2_3]$
- Java8
- TomEE (7.0.1)
Warfile/webapp
[appadmin@i2midev1 grouper-ws-scim_v2_3]$ ls /opt/tomcats/tomcat_h/webapps/ grouper-ws-scim_v2_3 grouper-ws-scim_v2_3.war
Control the server
[appadmin@i2midev1 grouper-ws-scim_v2_3]$ /sbin/service tomcat_h status|stop|start|restart
- Note: the demo server uses Apache basic auth, not tomcat tomcat-users.xml
Common Http status codes clients can expect from the Grouper TIER web services
Status Code | Description |
---|---|
200 | When everything goes OK for GET and PUT |
201 | When POST request which is used to create new resources is successful |
204 | When DELETE request is successful |
400 | When the request is BAD. Example idIndex in the request is not a numeric value. |
403 | When the user is authorized but doesn't have sufficient privileges to perform the operation. |
404 | When the resource (group, user, membership) client is looking for is not found. |
500 | When a server side error occurs. |
Common structure of error message:
{ "detail": "Something went wrong. Please try again later.", "status": "500", "schemas": [ "urn:ietf:params:scim:api:messages:2.0:Error" ] }
Sample Group GET
You can get a group by UUID, systemName or idIndex. systemName and idIndex are prefixes and must be provided in the path if looking up a group by system name or id Index.
Authorized user must have sufficient privileges or http response status will be 403 (Forbidden).
Response status is 404 (Not Found) if the group is not found.
https://grouperdemo.internet2.edu/grouper-ws-scim_v2_3/v2/Groups/b32e826380ea42c69dbf59cc262584f8
or: https://grouperdemo.internet2.edu/grouper-ws-scim_v2_3/v2/Groups/systemName:chris:testGroup
or: https://grouperdemo.internet2.edu/grouper-ws-scim_v2_3/v2/Groups/idIndex:10342
Response
{ "meta": { "version": "vGTxTe/oj21b6+dweSG7Kbn1mZh394Tiv33IkJrOCcg=" }, "id": "b32e826380ea42c69dbf59cc262584f8", "displayName": "chris:testGroup", "members": [ { "value": "87e53b36915c4fc9ac454a06ffa65da5", "$ref": "../Users/0b5949edd3bf4b65a0ab7e9ce97a4cf9", "type": "DIRECT" } ], "schemas": [ "urn:ietf:params:scim:schemas:core:2.0:Group", "urn:grouper:params:scim:schemas:extension:TierGroupExtension", "urn:tier:params:scim:schemas:extension:TierMetaExtension" ], "urn:tier:params:scim:schemas:extension:TierMetaExtension": { "resultCode": "SUCCESS", "responseDurationMillis": 23659 }, "urn:grouper:params:scim:schemas:extension:TierGroupExtension": { "description": "description updated using grouper-ws-scim PUT request", "idIndex": 10342, "systemName": "chris:testGroup" } }
Sample Group Find By Exact Field
Valid fields names are:name, uuid, idIndex, displayName, extension, displayExtension and description.
Examples are:
https://grouperdemo.internet2.edu/grouper-ws-scim_v2_3/v2/Groups?filter=idIndex%20eq%20%2211157%22
Response
{ "totalResults": 1, "startIndex": 1, "itemsPerPage": 1, "schemas": [ "urn:ietf:params:scim:api:messages:2.0:ListResponse" ], "Resources": [ { "meta": { "version": "jvge2T4+dEay9n49YDBM6gF2BS3bLG/ifUlfN5Zg6qY=" }, "id": "f50afe0442ab452bb0dbeae4bb1faefa", "displayName": "test:groupTest1", "members": [ { "value": "87e53b36915c4fc9ac454a06ffa65da5", "$ref": "../Users/0b5949edd3bf4b65a0ab7e9ce97a4cf9", "type": "DIRECT" }, { "value": "da1b779fbfce448d91fc7926ecb693ba", "$ref": "../Users/237dd8909c20481eb143fa3ae32df998", "type": "DIRECT" }, { "value": "c6927b11dd74411d9881f7c528766b7b", "$ref": "../Users/39f0db14af5a412e81e2108856188cab", "type": "DIRECT" }, { "value": "02ac936fe85c42aead3973558ee3cc3b", "$ref": "../Users/02d6d01291bb43f09e3b5e387ef0bab2", "type": "DIRECT" }, { "value": "8648fddf0345448a9bea21f953116f83", "$ref": "../Users/aa04aec5f93b4e1b80e45bf592dc2770", "type": "DIRECT" } ], "schemas": [ "urn:ietf:params:scim:schemas:core:2.0:Group", "urn:grouper:params:scim:schemas:extension:TierGroupExtension" ], "urn:grouper:params:scim:schemas:extension:TierGroupExtension": { "description": "group description updated", "idIndex": 11157, "systemName": "test:groupTest1" } } ] }
Sample Group Find By Approximate Field
Valid field names are: displayName, extension, displayExtension and description
Response
{ "totalResults": 2, "startIndex": 1, "itemsPerPage": 2, "schemas": [ "urn:ietf:params:scim:api:messages:2.0:ListResponse" ], "Resources": [ { "meta": { "version": "LGPfv7vSj+TjclWZxGRTMAM0Bq5v6hl+6QRgmIz4I+0=" }, "id": "cf6a3e71e5e545609f5b04b6a26c9ec7", "displayName": "users:penn:mageerc:test:rickGroupTest", "members": [ { "value": "87e53b36915c4fc9ac454a06ffa65da5", "$ref": "../Users/0b5949edd3bf4b65a0ab7e9ce97a4cf9", "type": "INDIRECT" }, { "value": "f06d86631b4b45118d4a18540c04f48e", "$ref": "../Users/58be116e1cae4e18b2e3d40b9777f99b", "type": "DIRECT" } ], "schemas": [ "urn:ietf:params:scim:schemas:core:2.0:Group", "urn:grouper:params:scim:schemas:extension:TierGroupExtension" ], "urn:grouper:params:scim:schemas:extension:TierGroupExtension": { "description": "", "idIndex": 10260, "systemName": "users:penn:mageerc:rcm:rgt" } }, { "meta": { "version": "jvge2T4+dEay9n49YDBM6gF2BS3bLG/ifUlfN5Zg6qY=" }, "id": "f50afe0442ab452bb0dbeae4bb1faefa", "displayName": "test:groupTest1", "members": [ { "value": "87e53b36915c4fc9ac454a06ffa65da5", "$ref": "../Users/0b5949edd3bf4b65a0ab7e9ce97a4cf9", "type": "DIRECT" }, { "value": "da1b779fbfce448d91fc7926ecb693ba", "$ref": "../Users/237dd8909c20481eb143fa3ae32df998", "type": "DIRECT" }, { "value": "c6927b11dd74411d9881f7c528766b7b", "$ref": "../Users/39f0db14af5a412e81e2108856188cab", "type": "DIRECT" }, { "value": "02ac936fe85c42aead3973558ee3cc3b", "$ref": "../Users/02d6d01291bb43f09e3b5e387ef0bab2", "type": "DIRECT" }, { "value": "8648fddf0345448a9bea21f953116f83", "$ref": "../Users/aa04aec5f93b4e1b80e45bf592dc2770", "type": "DIRECT" } ], "schemas": [ "urn:ietf:params:scim:schemas:core:2.0:Group", "urn:grouper:params:scim:schemas:extension:TierGroupExtension" ], "urn:grouper:params:scim:schemas:extension:TierGroupExtension": { "description": "group description updated", "idIndex": 11157, "systemName": "test:groupTest1" } } ] }
Sample POST request to create a new group
Authorized user must have sufficient privileges otherwise response status will be 403 (Forbidden)
https://grouperdemo.internet2.edu/grouper-ws-scim_v2_3/v2/Groups
Request payload: displayName has to have at least one colon if payload doesn't have systemName as shown in the second request payload.
{ "displayName": "test:testGroup6", "schemas": [ "urn:ietf:params:scim:schemas:core:2.0:Group", "urn:grouper:params:scim:schemas:extension:TierGroupExtension" ] }
If systemName is provided in the payload as shown below then that is used.
{ "displayName": "display name test", "urn:grouper:params:scim:schemas:extension:TierGroupExtension": { "systemName": "test:testGroup4", "description": "this is a test group4" }, "schemas": [ "urn:ietf:params:scim:schemas:core:2.0:Group", "urn:grouper:params:scim:schemas:extension:TierGroupExtension" ] }
Response
{ "meta": { "version": "YTv3TYGYQhJkrymAiLLCy6MyCM6ZGf1UxHIzoCIRZKk=" }, "id": "91371bd82bf544ebbb689b598041ab68", "displayName": "test:display name test", "schemas": [ "urn:ietf:params:scim:schemas:core:2.0:Group", "urn:grouper:params:scim:schemas:extension:TierGroupExtension", "urn:tier:params:scim:schemas:extension:TierMetaExtension" ], "urn:tier:params:scim:schemas:extension:TierMetaExtension": { "resultCode": "SUCCESS_CREATED", "responseDurationMillis": 3325 }, "urn:grouper:params:scim:schemas:extension:TierGroupExtension": { "description": "this is a test group4", "idIndex": 8474946, "systemName": "test:testGroup4" } }
Sample PUT request to update an existing group
Authorized user must have sufficient privileges otherwise response status will be 403 (Forbidden)
https://grouperdemo.internet2.edu/grouper-ws-scim_v2_3/v2/Groups/f50afe0442ab452bb0dbeae4bb1faefa
or https://grouperdemo.internet2.edu/grouper-ws-scim_v2_3/v2/Groups/idIndex:11157
or https://grouperdemo.internet2.edu/grouper-ws-scim_v2_3/v2/Groups/systemName:test:groupTest1
Request Payload:
{ "displayName": "display name test updated", "urn:grouper:params:scim:schemas:extension:TierGroupExtension": { "description": "group description updated", "systemName": "test:groupTest1" }, "schemas": [ "urn:ietf:params:scim:schemas:core:2.0:Group", "urn:grouper:params:scim:schemas:extension:TierGroupExtension" ] }
Response
{ "meta": { "version": "gOzP8eFq93LqFiqaGdNoPhWkJbf291AehW57iQSkn4Q=" }, "id": "f50afe0442ab452bb0dbeae4bb1faefa", "displayName": "test:groupTest1", "schemas": [ "urn:ietf:params:scim:schemas:core:2.0:Group", "urn:grouper:params:scim:schemas:extension:TierGroupExtension", "urn:tier:params:scim:schemas:extension:TierMetaExtension" ], "urn:tier:params:scim:schemas:extension:TierMetaExtension": { "resultCode": "SUCCESS_UPDATED", "responseDurationMillis": 104 }, "urn:grouper:params:scim:schemas:extension:TierGroupExtension": { "description": "group description updated", "idIndex": 11157, "systemName": "test:groupTest1" } }
Sample DELETE request to delete an existing group
Authorized user must have sufficient privileges otherwise response status will be 403 (Forbidden)
Successful response code is 204
https://grouperdemo.internet2.edu/grouper-ws-scim_v2_3/v2/Groups/6eb2c39133f148d0a960dcf98aec2ff2
or https://grouperdemo.internet2.edu/grouper-ws-scim_v2_3/v2/Groups/idIndex:11157
or https://grouperdemo.internet2.edu/grouper-ws-scim_v2_3/v2/Groups/systemName:test:groupTest1
Sample GET request to get an existing user
https://grouperdemo.internet2.edu/grouper-ws-scim_v2_3/v2/Users/test
Response
{ "meta": { "version": "L86GgGkmB9UZN0i220nMQIgh1XQO3uwHDLl6QbZf2z8=" }, "id": "test", "active": true, "displayName": "Test WS user", "schemas": [ "urn:ietf:params:scim:schemas:core:2.0:User", "urn:tier:params:scim:schemas:extension:TierMetaExtension" ], "urn:tier:params:scim:schemas:extension:TierMetaExtension": { "resultCode": "SUCCESS", "responseDurationMillis": 285 } }
Sample GET request to find users
https://grouperdemo.internet2.edu/grouper-ws-scim_v2_3/v2/Users?filter=identifier%20eq%20%22test%22
or https://grouperdemo.internet2.edu/grouper-ws-scim_v2_3/v2/Users?filter=id%20eq%20%22test%22
{ "totalResults": 1, "startIndex": 1, "itemsPerPage": 1, "schemas": [ "urn:ietf:params:scim:api:messages:2.0:ListResponse" ], "Resources": [ { "meta": { "version": "1hIKxhtMi+C50FHsVUQhoUesGzb0So4tgcmv0qV4b4A=" }, "id": "test", "active": true, "displayName": "Test WS user", "schemas": [ "urn:ietf:params:scim:schemas:core:2.0:User" ] } ] }
Sample GET request to retrieve a membership (By Membership Id)
Response
{ "meta": { "version": "KrrJpOgXNYzNKUOcsKNFSycBZ5hcZM94n76Cy7U2nYI=" }, "id": "ca7f77ae69d540589bce0a4fc03e1f33:502e5c0d505f4438ae87d18552504e7e", "enabledTime": "2016-01-26T04:56:22", "enabled": true, "membershipType": "immediate", "owner": { "value": "f50afe0442ab452bb0dbeae4bb1faefa", "display": "test:groupTest1", "systemName": "test:groupTest1", "$ref": "../Groups/f50afe0442ab452bb0dbeae4bb1faefa" }, "member": { "value": "39f0db14af5a412e81e2108856188cab", "display": "Joseph Streeter", "$ref": "../Users/39f0db14af5a412e81e2108856188cab" }, "schemas": [ "urn:tier:params:scim:schemas:Membership" ] }
Sample GET request to find memberships
Valid attribute names for groups are groupId, groupName, and groupIdIndex. Valid attribute names for subjects are subjectId and subjectIndentifier. Request URL can filter based on one of the group's attributes, or one of the subject attributes or can have AND operation between any group attribute and any subject attributes. A few valid examples are:
Filter by group attribute:
Filter by subject attribute
Filter by group attribute and subject attribute
{ "totalResults": 1, "startIndex": 1, "itemsPerPage": 1, "schemas": [ "urn:ietf:params:scim:api:messages:2.0:ListResponse" ], "Resources": [ { "meta": { "version": "nRjCxbOfOT7j50mS+4r3iqwtTmAbTRuJqjkZIFS3t+Y=" }, "id": "77d1bdeff3b9416c9497e0b5913959cc:502e5c0d505f4438ae87d18552504e7e", "enabled": true, "membershipType": "immediate", "owner": { "value": "f50afe0442ab452bb0dbeae4bb1faefa", "display": "test:groupTest1", "systemName": "test:groupTest1", "$ref": "../Groups/f50afe0442ab452bb0dbeae4bb1faefa" }, "member": { "value": "0b5949edd3bf4b65a0ab7e9ce97a4cf9", "display": "Chris Hyzer", "$ref": "../Users/0b5949edd3bf4b65a0ab7e9ce97a4cf9" }, "schemas": [ "urn:tier:params:scim:schemas:Membership" ] } ] }
Sample POST request to create a new membership
https://grouperdemo.internet2.edu/grouper-ws-scim_v2_3/v2/Memberships
Request payload:
{ "enabledTime": "2008-01-23T04:56:22Z", "disabledTime": "2008-01-27T04:56:22Z", "owner": { "value": "b88088776c6b4ecba61995155c79e146" }, "member": { "value": "214de63823c441ea98eb8a8ec8548a0e" }, "schemas": [ "urn:tier:params:scim:schemas:Membership" ] }
owner property represents the owner group. Owner group can be searched by UUID as shown above or systemName or idIndex. member can be looked up by subjectId or subjectIdentifier.
Response
{ "meta": { "version": "6rPfFAez3/engCnh7NPPutMM8xN/HQW0dKBMZVWyKtA=" }, "id": "63da8a4d3f934fdaac922e6b6eff3fca:2715ecca492b4499ab978d9e3c69fc2d", "enabledTime": "2008-01-23T04:56:22", "disabledTime": "2008-01-27T04:56:22", "enabled": true, "membershipType": "immediate", "owner": { "value": "0fecc9b4756241d2ad4a2959bd4a0c26", "display": "top display name:scim10", "systemName": "top:scim10", "$ref": "../Groups/0fecc9b4756241d2ad4a2959bd4a0c26" }, "member": { "value": "test.subject.4", "display": "my name is test.subject.4", "$ref": "../Users/test.subject.4" }, "schemas": [ "urn:tier:params:scim:schemas:Membership" ] }
Sample PUT request to update a membership
enabledTime and disabledTime can only be updated with the update membership service
{ "enabledTime": "2016-01-26T04:56:22Z", "owner": { "systemName": "test:groupTest1" }, "member": { "value": "jstreeter@wisc.edu" }, "schemas": [ "urn:tier:params:scim:schemas:Membership" ] }
Response:
{ "meta": { "version": "KrrJpOgXNYzNKUOcsKNFSycBZ5hcZM94n76Cy7U2nYI=" }, "id": "ca7f77ae69d540589bce0a4fc03e1f33:502e5c0d505f4438ae87d18552504e7e", "enabledTime": "2016-01-26T04:56:22", "enabled": true, "membershipType": "immediate", "owner": { "value": "f50afe0442ab452bb0dbeae4bb1faefa", "display": "test:groupTest1", "systemName": "test:groupTest1", "$ref": "../Groups/f50afe0442ab452bb0dbeae4bb1faefa" }, "member": { "value": "39f0db14af5a412e81e2108856188cab", "display": "Joseph Streeter", "$ref": "../Users/39f0db14af5a412e81e2108856188cab" }, "schemas": [ "urn:tier:params:scim:schemas:Membership" ] }
Sample DELETE request to delete an existing membership
See Also
Grouper SCIM Change Log Consumer