This quickstart shows how to setup the Roles and Entitlements functionality through the SCIM component. This includes enabling the /Roles
& /Entitlements
endpoints, as well as building up either a roles or entitlements structure to be added to an in-memory store. Throughout the SCIM component and in this documentation Roles and Entitlements may be refeerred to as Assignments, using models such as EntitlementResource & RoleResource, that inherit from AssignmentResource. The Roles and Entitlements endpoints and functionality are based on the Roles and Entitlements RFC. Samples for the code that follows can be found on the SCIM Sample github repository.
Enabling
To enable Roles and/or Entitlements, configure the RolesAndEntitlement record in the ScimServiceProviderConfigOptions
passed in when calling AddScimServiceProvider
public void ConfigureServices(IServiceCollection services)
{
services.AddScimServiceProvider(
"/SCIM",
new ScimLicensingOptions("Demo", "Get your license key from https://www.identityserver.com/products/scim-for-aspnet"),
new ScimServiceProviderConfigOptions
{
...
RolesAndEntitlements = new RolesAndEntitlementsOptions(
new AvailableRoleOptions(
Enabled: true, PrimarySupported: true, TypeSupported: true, MultipleRolesSupported: true
),
new AvailableEntitlementOptions(
Enabled: true, PrimarySupported: true, TypeSupported: true, MultipleEntitlementsSupported: true
)
);
...
}
);
}
Validation
For each of the assignment types, when they are enabled the SCIM component will validate the existence of the assignments provided when adding or updating a user through their respective stores, i.e. through IScimAssignmentStore<RoleResource>
or IScimAssignmentStore<EntitlementResource>
. In the case of failed validation a 400 Bad Request
will be returned to the calling SCIM client with a list of validation errors.
Type Flag
If type
is supported, the component will validate user add or update requests by assuming that all of the assignments being validated have the type property set, null or whitespace values are not accepted. In addition to this, when checking for the existence of an assignment, the assignment being assigned is expected to have a matching assignment by value
& type
in the store. If type
is not supported, then values on the type
property will be ignored by the validation.
Primary Flag
If primary
is supported, the component will validate requests by assuming that all of the assignments have at least one assignment where the primary
property is set to true. If primary
is not supported, then the primary flag is ignored.
Multiple Assignments
If the MultipleRolesSupported
or MultipleEntitlementsSupported
flags are set to false, then the component will check for multiple values of the given assignment when performing an add or an update operation for a User.
Modelling
The SCIM component allows for modelling a structured set of assignments via building an in-memory store that can be registered with the component. To get started, create an instance of the ScimAssignmentsStoreBuilder<TAssignmentResource>
. From here you can add assignments through AddAssignment
. The AddAssignment
method takes in two strings, one for Value
and one for Display
. Additionally if you pass in an Action<ScimAssignmentsStoreBuilder<TAssignmentResource>>
you can add children to the assignment. After adding all of the required assignments, call the Build
method on the store builder to return an in-memory store and then pass this to AddAssignmentStore
on the ScimServiceProviderBuilder
ScimAssignmentsStoreBuilder<EntitlementResource> entitlementStoreBuilder = new ScimAssignmentsStoreBuilder<EntitlementResource>();
IScimAssignmentsStore<EntitlementResource> entitlementStore =
entitlementStoreBuilder
.AddAssignment("5", "All Printer Permissions",
c =>
c.AddAssignment("1", "Printing")
.AddAssignment("2", "Scanning")
.AddAssignment("3", "Copying")
.AddAssignment("4", "Collating")
).Build();
services.AddScimServiceProvider("/SCIM", new ScimLicensingOptions('...', '...'))
.AddAssignmentStore(entitlementStore);
ScimAssignmentsStoreBuilder<RoleResource> roleStoreBuilder = new ScimAssignmentsStoreBuilder<RoleResource>();
IScimAssignmentsStore<RoleResource> roleStore =
roleStoreBuilder.AddAssignment("global_lead", "Global Team Lead", gbl =>
gbl.AddAssignment("us_team_lead", "U.S. Team Lead", us =>
us.AddAssignment("nw_regional_lead", "Northwest Regional Lead")))
.Build();
services.AddScimServiceProvider("/SCIM", new ScimLicensingOptions('...', '...'))
.AddAssignmentStore(roleStore);
Now when querying the Entitlements
and /Roles
the following results are returned
{
"totalResults": 5,
"itemsPerPage": 5,
"startIndex": 1,
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:ListResponse"
],
"resources": [
{
"value": "5",
"display": "All Printer Permissions",
"enabled": true,
"contains": [
"1",
"2",
"3",
"4"
]
},
{
"value": "4",
"display": "Collating",
"enabled": true,
"contains": [],
"containedBy": [
"5"
]
},
{
"value": "3",
"display": "Copying",
"enabled": true,
"contains": [],
"containedBy": [
"5"
]
},
{
"value": "2",
"display": "Scanning",
"enabled": true,
"contains": [],
"containedBy": [
"5"
]
},
{
"value": "1",
"display": "Printing",
"enabled": true,
"contains": [],
"containedBy": [
"5"
]
}
]
}
{
"totalResults": 3,
"itemsPerPage": 3,
"startIndex": 1,
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:ListResponse"
],
"resources": [
{
"value": "global_lead",
"display": "Global Team Lead",
"enabled": true,
"contains": [
"us_team_lead"
]
},
{
"value": "us_team_lead",
"display": "U.S. Team Lead",
"enabled": true,
"contains": [
"nw_regional_lead"
],
"containedBy": [
"global_lead"
]
},
{
"value": "nw_regional_lead",
"display": "Northwest Regional Lead",
"enabled": true,
"contains": [],
"containedBy": [
"us_team_lead"
]
}
]
}
Custom Store
You can provide a custom entitlement or roles store by implementing the IScimAssignmentsStore<TAssignmentResource>
interface, where TAssignmentResource
is a class that inherits from AssignmentResource
, i.e. RoleResource
or EntitlementResource
. To register the custom store with the SCIM component, call the AddAssignmentStore
method on the ScimServiceProviderBuilder
services.AddScimServiceProvider("/SCIM", new ScimLicensingOptions('...', '...'))
.AddAssignmentStore<RoleResource, MyCustomRoleStore>();