Consentors are a Curity extensibility mechanism used to perform additional processing during delegation and token issuance, including validation, information retrieval, and user interaction. Consentors are executed as a part of the authorization request for various flows (e.g., code, implicit and assisted token), after user-consent has been gathered and before the delegation or token is issued.
There are two types of consentors: generic consentors (frequently named only by consentors), and signing consentors.
Generic consentors receive the consent attributes, which are made up of the client identifier, authentication attributes, and consented scope and claims, and produce a consentor result, that is added to the created delegation. During their execution, generic consentors can also:
Signing consentors are a specialization of generic consentors, used when the goal is just to sign the consented information. They receive a text-to-display and an object-to-sign and use this information to produce a signature that is added to the resulting delegation:
Signing consentors can also involve user interaction, namely to show the information that will be signed. However this interaction is rather constrained when compared with the one available to generic consentors.
Curity already includes built-in consentors, namely BankID, however new consentors can be added as plugins.
Each token profile defines the list of consentors usable on that profile. This list is configured under the consentors element, where each consentor is defined by a consentor element.
The following figure illustrates this list, present in the profile’s configuration user interface.
Fig. 158 Profile consentor list configuration.
Consentor configuration is comprised by consentor-independent information and consentor-specific information. The consentor-specific information is described in the documentation for each consentor.
The consentor-independent configuration information for generic consentors is comprised by:
id
description
For signing consentors, this common configuration information is extended with:
token-issuer
generic
text-to-display-procedure
webservice
attribute-data-source
The configured token-issuer is used to sign the JWT containing the consent attributes and the text-to-display. If no token-issuer is configured, then the profile’s default token issuer is used.
The text-to-display-procedure is used to create the text-to-display from the consented information. It must include the definition of a result function that returns this text-to-display string. This function receives a context object with:
result
context
consentAttributes
clientId
authenticationAttributes
scopes
claims
attributeDataAccessProvider
getWebServiceClient()
getClient()
client
The following code excerpt illustrates the context available to the text-to-display procedure.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
function result(context) { // Just to illustrate subject attributes usage var subject = context.consentAttributes.authenticationAttributes.subject.subject; if(subject != context.subjectAttributes().subject) { // Send error back to the requesting client throw exceptionFactory.forbiddenException("Subject mismatch"); } // Just to illustrate context attributes usage var acr = context.consentAttributes.authenticationAttributes.context.acr; if(acr != context.contextAttributes().acr) throw exceptionFactory.forbiddenException("Acr mismatch"); // Just to illustrate the attribute data source var attributes = context.attributeDataAccessProvider.getAttributes(subject); if (!attributes) throw exceptionFactory.forbiddenException("missing attributes") // Just to illustrate the web service client var response = context.getWebServiceClient().get() if (response.statusCode != 200) throw exceptionFactory.forbiddenException("bad response status " + response.statusCode) // To illustrate the client object var client = context.client; var clientName = client.name; var scopesAndClaims = Java.from(context.consentAttributes.claims) .concat(Java.from( context.consentAttributes.scopes)); // the text-to-display return clientName + " requests access to: " + scopesAndClaims.join(', '); }
Any log entries issued by the text-to-display procedure, using the logger global object, are associated with the se.curity.identityserver.scripting.textToDisplayProcedure.<consentorId> logger name, where consentorId is the consentor’s instance identifier.
logger
se.curity.identityserver.scripting.textToDisplayProcedure.<consentorId>
consentorId
The following figure illustrates the configuration for a signing consentor:
Fig. 159 Signing consentor configuration example.
bankid-signing-consentor
Consentors are enabled per client when the client’s user-consent setting is enabled. By default, all the profile’s consentor instances are applicable to a client. However a client configuration can define a subset of the profile’s consentor instances that should be used.
As an example, if a profile has the consentor-1 and consentor-2 consentor instances configured, then the client behaviour will be as follows:
consentor-1
consentor-2
user-consent
It is also possible to disable the built-in consent form and have only consentors run. This is achieved by enabling the only-consentors element.
only-consentors
The following diagram illustrate the configuration user interface for a specific client.
Fig. 160 Client consentor configuration example.
In this case, the client is explicitly listing a single consentor (the-consentor-id), so only this consentor will be applicable when this client is used, independently of the consentors configured on the profile. Notice also that “Only Consentors” is disabled, meaning that both the built-in consent form and the configured consentor will be used.
A similar configuration also exists for the profile’s non-templatized dynamic clients.
If more than one consentor is applicable to a given request, then a consentor selection form is presented to the user. This form is defined by the consentor-chooser.vm and consentor-chooser-single-color.vm templates, located in the templates/core/fragments. The choice between these two templates, as well as additional presentation characteristics, are defined by the settings single_color_consentor_chooser and icons_only_consentor_chooser.
consentor-chooser.vm
consentor-chooser-single-color.vm
templates/core/fragments
single_color_consentor_chooser
icons_only_consentor_chooser
The messages used by the form are located in messages/core/{lang}/views/select-consentor.
messages/core/{lang}/views/select-consentor
The consentor templates get the String value of the original query of the authorization request set in the template context as _originalQuery template variable.
_originalQuery
The result of a successful consentor execution is stored in the issued delegation and is available to procedures. The following code excerpt illustrates how this information can be obtained.
1 2 3 4 5 6 7 8 9 10
// a procedure with access to issued delegations function result(context) { ... var issuedDelegation = ...; var consent = issuedDelegation.consent; var consentorId = consent.consentorId; var consentorResultAttributes = consent.consentorResultAttributes; var consentorSpecificInfo = consentorResultAttributes.consentorSpecificInfo. ... }
The issued delegation consent field is an object with consent-related information.
consent
prompt
consentorResultAttributes
signingConsentorObjectToSign