Date: Thu, 28 Mar 2024 19:16:46 +0000 (UTC)
Message-ID: <1810791759.19.1711653406176@1352d1d1f7ee>
Subject: Exported From Confluence
MIME-Version: 1.0
Content-Type: multipart/related;
boundary="----=_Part_18_518547849.1711653406176"
------=_Part_18_518547849.1711653406176
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Content-Location: file:///C:/exported.html
Files: conf/idp.properties, conf/intercept/=
consent-intercept-config.xml, messages/message.properties, views/intercept/=
attribute-release.vm, views/intercept/terms-of-use.vm
Forma=
t: Native Spring
Overview
The IdP includes the ability to require user consent to attribute releas=
e, as well as presenting a "terms of use" message prior to completing a log=
in to a service, a simpler "static" form of consent.
Consent is implemented by the intercept/attribute-release and intercept/terms-of-use
interceptor flows.
Enabling Module (V4.1=
+)
For V4.1+, configuring and using this feature requires that you first en=
able the "idp.intercept.Consent" module if i=
t isn't already enabled. Systems upgraded from older releases generally com=
e pre-enabled due to the prior state of the configuration tree.
(Window=
s)
C:\opt\shibboleth-idp> bin\module.bat -t idp.intercept.Consent || bin\mo=
dule.bat -e idp.intercept.Consent
=20
(Other)
$ bin/module.sh -t idp.intercept.Consent || bin/module.sh -e idp.intercept.=
Consent
Attribute Release C=
onsent
Attribute release consent requires users to accept the release of attrib=
utes to Service Providers during front-channel authentication profiles that=
include attribute data in the response.
Users are prompted to consent to attribute release :
-
on initial access to service provider resources
-
on release of an attribute to which consent has not been previously give=
n
-
when an attribute previously consented to is no longer released
-
(optionally) when the value of an attribute previously consented to chan=
ges, see ConsentConfiguration#Attribute Release Value Comparison.
Attribute release consent is enabled for profiles that do user authentic=
ation via the postAuthenticationFlows
property =
in conf/relying-party.xml.
De=
fault relying party configuration
<bean=
id=3D"shibboleth.DefaultRelyingParty" parent=3D"RelyingParty">
<property name=3D"profileConfigurations">
<list>
<!-- SAML 1.1 and SAML 2.0 AttributeQuery are disabled by de=
fault. -->
=09=09=09<!--
<bean parent=3D"Shibboleth.SSO" p:postAuthenticationFlows=3D=
"attribute-release" />
<ref bean=3D"SAML1.AttributeQuery" />
<ref bean=3D"SAML1.ArtifactResolution" />
=09=09=09-->
<bean parent=3D"SAML2.SSO" p:postAuthenticationFlows=3D"attr=
ibute-release" />
<ref bean=3D"SAML2.ECP" />
<ref bean=3D"SAML2.Logout" />
=09=09=09<!--
<ref bean=3D"SAML2.AttributeQuery" />
=09=09=09-->
<ref bean=3D"SAML2.ArtifactResolution" />
</list>
</property>
</bean>
Per Attribute Consent
To allow users to select the attributes they wish to be released, provid=
ed the attributes are not being released via a back-channel exchange, you c=
an set the idp.consent.allowPerAttribute property in =
conf/idp.properties.
Rejection
When a user rejects consent to attribute release, an Attribut=
eReleaseRejected
event will be signalled. The text presented to the =
user may be modified via standard Er=
rorHandlingConfiguration and via messages/messages.properties =
(see the Messages tab below).
Attribute Display
Localization
The names and values of attributes displayed during consent may be custo=
mized. By default, the locale-aware attribute display name and display value are displ=
ayed. Customizing the localization information is generally handled through=
the rules defined in the AttributeRe=
gistryConfiguration.
Selective Display
By default, users are prompted to consent to release all attributes unle=
ss specifically suppressed on a per-attribute basis. Suppressed attributes =
are released to relying parties but are not displayed to users. =
A prompted list, ignored list, and match expressions determine whether=
consent should be obtained for an attribute based on the attribute ID.
To prevent an attribute from being displayed, add the attribute ID to th=
e ignored list or exclude it by a match expression. The ignored list and ma=
tch expression override the prompted list.
Type |
Description |
Bean name conf/intercept/consent-intercept-config.xml |
Prompted |
Attribute IDs for which users should be prompted to consent |
shibboleth.consent.attribute-release.PromptedAttributeIDs 4.1
shibboleth.consent.attribute-release.WhitelistedAttributeIDs (DEPRECATED) |
Ignored |
Attribute IDs for which users should not be p=
rompted to consent |
shibboleth.consent.attribute-release.IgnoredAttributeIDs 4.1
shibboleth.consent.attribute-release.BlacklistedAttributeIDs (DEPRECATED) |
Regex |
Attribute IDs matching a regular expression that users should be pr=
ompted to consent |
shibboleth.consent.attribute-release.MatchExpression&nb=
sp; =
&nb=
sp; =
&nb=
sp; =
&nb=
sp; =
&nb=
sp; =
|
Order
Attributes are, by default, displayed in the natural order of their IDs.=
Deployers may wish to customize the order in which attributes are displaye=
d to users, in order to present the most relevant or personal attributes fi=
rst.
The order in which attributes are displayed to users may be customized b=
y providing a list of attribute IDs. Attributes not in the list will s=
till be sorted in their natural order, but subsequent to attributes in the =
list. Define the bean named shibboleth.consent.attribute-release.At=
tributeDisplayOrder in conf/intercept/consent-intercept-c=
onfig.xml representing the desired order. The values of the list are a=
ttribute IDs.
The following example displays the mail
attribute=
first and then all other attributes in alphabetic order by ID:
<bea=
n id=3D"shibboleth.consent.attribute-release.CustomAttributeIDComparator" c=
lass=3D"org.example.CustomAttributeIDComparator" />
For advanced customization of the attribute display order, a custom Comp=
arator may be provided. Define a bean named shibboleth.consent.attr=
ibute-release.AttributeIDComparator in conf/intercep=
t/consent-intercept-config.xml which implements Comparator<String>. For example:
<bea=
n id=3D"shibboleth.consent.attribute-release.CustomAttributeIDComparator"&n=
bsp;class=3D"org.example.CustomAttributeIDComparator" />
Consent Duration
Users may choose from three options when deciding the duration of their =
consent to attribute release. The duration options and descriptive text may=
be customized via messages/messages.properties.
Duration Option |
Description |
"Ask me a=
gain at next login" |
Users will be prompted to consent to attribute release at every log in. =
This is implemented by not storing consent. |
|
The default. Users will be prompted to consent to attribute release if a=
ttributes have changed since consent was previously given. |
"Do not ask me =
again" |
Optional. Users will not be prompted to consent to attribute release aga=
in. All attributes will be released to any service provider. The presence of this option is cont=
rolled by the idp.consent.allowGlobal property. |
Value Comparison
By default, users are prompted to consent to attribute release if a "new=
" attribute is released or if an "old" attribute is no longer released. "Ne=
w" and "old" in this context indicate whether consent has already been give=
n to an attribute ID regardless of the attribute's values. In other words, =
by default, users are not prompted to consent to attribute release if an at=
tribute's values change.
To prompt users to consent to attribute release if the values of an attr=
ibute have changed, set idp.consent.compareValues&nbs=
p;to true in conf/idp.properties
Prompting users to consent to attribute release if an attribute's value =
changes requires additional storage capability, because the hash of an attr=
ibute's values must be stored for comparison. If client-side storage withou=
t use of HTML Local Storage is used to store consent, comparing attribute v=
alues may reduce the number of records that may be stored. Since a consent =
record is stored for every Service Provider, this may increase how often us=
ers are prompted to consent to attribute release
Terms Of Use Consent
Consent to terms of use is not enabled by default. To enable it, you wil=
l need to :
-
Configure terms of use message(s) to suit your needs.
-
Enable the terms of use intercept flow for the cases it should appear.=
p>
Configuring Messages
The "terms" are managed as Spring messages via the messages/messages=
.properties file (or localized versions of it) (see ConsentConfiguration#Message=
s).
The title and message of the terms of use page displayed to users is der=
ived using the bean named shibboleth.consent.terms-of-use.Key, which defaults to the relying party ID. For example:
https\:=
//sp.example.org =3D sp-example-org
sp-example-org.title =3D Example Terms of Use
sp-example-org.text=09=3D This is an example Terms of Use
You may add additional terms of use messages and web page titles specifi=
c to relying parties using this mechanism. Each key is mapped to a specific=
prefix used in the corresponding pair of message properties.
Customizing the Mapping of Relying Party to Terms of Us=
e Message and Title
To customize the mapping of relying party to terms of use message and ti=
tle, you override the shibboleth.consent.terms-of-use.Key =
bean in conf/intercept/consent-intercept-config.xml. The following=
example use a utility class available in the Guava library to turn a map i=
nto a compliant Function=
a> that is composed with a call to lookup the relying party ID. The example=
isn't all that interesting, but it illustrates the indirection. You can ma=
p multiple SPs to a single vale, and so forth.
<bea=
n id=3D"shibboleth.consent.terms-of-use.Key" parent=3D"shibboleth.Functions=
.Compose">
<constructor-arg name=3D"g">
<bean class=3D"com.google.common.base.Functions" factory-method=
=3D"forMap" c:defaultValue=3D"terms-of-use">
<constructor-arg name=3D"map">
<map>
<entry key=3D"https://sp.example.org/shibboleth" val=
ue=3D"example-terms" />
<entry key=3D"https://other.example.org/shibboleth" =
value=3D"example-terms" />
</map>
</constructor-arg>
</bean>
</constructor-arg>
<constructor-arg name=3D"f">
<ref bean=3D"shibboleth.RelyingPartyIdLookup.Simple" />
</constructor-arg>
</bean>
Using One Terms of Use Message for Every Relying Party
To configure a single terms of use page for every relying party, overrid=
e the bean named shibboleth.consent.terms-of-use.Key in conf/intercept/consent-intercept-config.xml:
<bea=
n id=3D"shibboleth.consent.terms-of-use.Key" parent=3D"shibboleth.Functions=
.Constant">
<constructor-arg value=3D"my-terms"/>
</bean>
and define the terms of use message and title in messages/messages.p=
roperties:
my-term=
s =3D my-tou
my-tou.title =3D Example Terms of Use
my-tou.text=09=3D This is an example Terms of Use
Enabling Te=
rms Of Use Intercept Flow
To enable the flow, you would add terms-of-use
to the&=
nbsp;postAuthenticationFlows
profile setting in conf/relyi=
ng-party.xml.
For example for use with SAML 2.0 requests, replace:
<bea=
n parent=3D"SAML2.SSO" p:postAuthenticationFlows=3D"attribute-release" />=
;
with :
<bea=
n parent=3D"SAML2.SSO" p:postAuthenticationFlows=3D"#{ {'terms-of-use', 'at=
tribute-release'} }" />
Rejection of T=
erms of Use Consent
When a user rejects consent to terms of use, a TermsRejected<=
/code> event will be signaled. The text presented to the user may be modifi=
ed via standard ErrorHandlingConfigu=
ration and via messages/messages.properties (see ConsentConfiguration#M=
essages).
User Interface
The user interface for the attribute release and terms of use consent fl=
ows are implemented as Velocity templates, views/intercept/attribute-re=
lease.vm and views/intercept/terms-of-use.vm respectively.
The templates can be customized in a similar way to the login pages and other views.
Messages displayed to users may be localized in the standard Spring way,=
for example, by providing messages/messages_de.properties. Some t=
ranslations are already included in the distribution.
Revoking Consent
Users may revoke previous consent choices by selecting a checkbox on the=
login page (views/login.vm).
The text of the checkbox displayed on the login page is set by the =
idp.attribute-release.revoke message ID, overridable in messages/messages.properties.
Storage
In order to remember users' consent choices and to prompt users to conse=
nt to attribute release if attributes change, users' consent choices must b=
e persisted by a storage service. User consent may be stored either cl=
ient-side (cookies or HTML5 Local Storage) or server-side (database). The d=
efault is to store consent client-side via Local Storage, not out of any pa=
rticular belief that it makes sense, but because it allows easy deployment =
of the feature for demonstration.
The storage service used to store consent is configured by the idp.consent.StorageService property in conf/idp.properties=
See StorageConfiguration for more on the=
configuration of various approaches to storage.
Limiting Records
While the default client-side storage solution is HTML Local Storage, it=
is possible to use cookies. Because cookies provide limited storage capabi=
lity, the number of stored consent records is also very limited. By default=
, for client-side storage via cookies, the maximum number of stored consent=
records is 10. Depending on the number of attributes released and whether =
released attribute values are compared, the default limit of 10 may be incr=
eased. It is not clear what a reasonable default value should be, but it ma=
y be significantly higher. We were conservative with the default.
If server-side storage is used, the number of stored consent records sho=
uld probably be unlimited, represented by a limit of -1 or 0.
The maximum number of stored consent records is configured via the =
idp.consent.maxStoredRecords property in conf/idp.prop=
erties
Retention in V4.0
A map is supported to store numbers which refer to attribute IDs in=
order to reduce the size of consent storage records if desired. The defaul=
t mapping of attribute IDs to numbers is defined by the shibbo=
leth.consent.DefaultAttributeSymbolics bean, internally to the sys=
tem.
Additional mappings may be added to the shibboleth.consent.Attri=
buteSymbolics bean in conf/intercept/consent-intercept-config.=
xml
Retention in V4.1
The default lifetime for consent storage records is 1 year, and may=
be configured via idp.consent.storageRecordLifetime in conf/idp.properties. When consent storage records expire, they will =
no longer by visible via the storage service. Actual timing of deletion is =
specific to the storage implementation.
Record Format
Consent storage records consist of a key and value, like all StorageRecords.
The (default) storage key for consent records is a concatenation of the =
user key and the relying party ID, though this is customizeable.
The storage value for consent records is the JSON-serialized form of a M=
ap of Consent objects.
A per-user index is maintained in order to expire or limit the number of=
stored records.
{ =20
"jdoe:https://sp1.example.org":{ =20
"v":"[{\"id\":307},{\"id\":\"mail\"},{\"id\":\"uid\"}]",
"x":1479847202110
},
"jdoe:https://sp2.example.org":{ =20
"v":"[{\"id\":307},{\"id\":\"mail\"},{\"id\":\"uid\"}]",
"x":1479847206825
},
"jdoe:https://sp3.example.org":{ =20
"v":"[{\"id\":307},{\"id\":\"mail\"},{\"id\":\"uid\",\"appr\":false}]=
",
"x":1479847566214
},
"jdoe:_key_idx":{ =20
"v":"[\"jdoe:https://sp1.example.org\",\"jdoe:https://sp2.example.org=
\",\"jdoe:https://sp3.example.org\"]"
}
}
Auditing
By default, consent audit logs are written to logs/idp-consent-audit=
.log as defined in conf/logback.xml.
The format of consent audit logs are defined by the shibbol=
eth.consent.attribute-release.AuditFormattingMap and =
shibboleth.consent.terms-of-use.AuditFormattingMap beans in co=
nf/intercept/consent-intercept-config.xml
See ConsentAuditFields and also the AuditLoggingConfiguration for additional fields available wit=
hout additional work.
Consent flows (like any other interceptor flow) may be run conditionally=
based on ActivationConditions.
Because the attribute release flow has an internal condition attached al=
ready, customizing the condition for it requires combining the default acti=
vation condition with the custom activation condition. By default, the attribute release flow is not activat=
ed if both (1) attributes are not pushed and (2) per attribute consent=
is enabled.
The terms of use flow does not have a default activation condition.
Example
Consent flows may be activated=
based on the presence (or absence) of a particular attribute or value for =
a user.
The following example activate=
s the attribute release flow if an attribute is present by combining the de=
fault activation condition with a custom condition:
V4.0
Example activation condition in conf/intercep=
t/profile-intercept.xml
<bea=
n id=3D"intercept/attribute-release" parent=3D"shibboleth.consent.Attribute=
ReleaseFlow"
p:activationCondition-ref=3D"MyCondition" />
<bean id=3D"MyCondition" parent=3D"shibboleth.Conditions.AND">
<constructor-arg>
<list>
<!-- The default condition from system/conf/profile-intercep=
t-system.xml -->
<bean parent=3D"shibboleth.Conditions.OR">
<constructor-arg>
<bean parent=3D"shibboleth.Conditions.NOT">
<constructor-arg value=3D"%{idp.consent.allowPer=
Attribute:false}" />
</bean>
</constructor-arg>
<constructor-arg>
<bean class=3D"net.shibboleth.idp.saml.profile.confi=
g.logic.IncludeAttributeStatementPredicate" />
</constructor-arg>
</bean>
<!-- A custom condition -->
<bean class=3D"net.shibboleth.idp.profile.logic.SimpleAttrib=
utePredicate" p:useUnfilteredAttributes=3D"true">
<property name=3D"attributeValueMap">
<map>
<entry key=3D"eppn">
<list>
<value>*</value>
</list>
</entry>
</map>
</property>
</bean>
</list>
</constructor-arg>
</bean>
V4.1+
To combine your own condition with the system default, you would define =
your bean in, e.g., conf/global.xml:
Cus=
tom condition bean in global.xml
<bean=
id=3D"example.AttributeReleaseCondition"
=09=09class=3D"net.shibboleth.idp.profile.logic.SimpleAttributePredicate"
=09=09p:useUnfilteredAttributes=3D"true">
<property name=3D"attributeValueMap">
<map>
<entry key=3D"eppn">
<list>
<value>*</value>
</list>
</entry>
</map>
</property>
</bean>
Then define the property idp.consent.attribute-release.activatio=
nCondition to example.AttributeReleaseCondition (your custom bean'=
s ID) to install it and it will be combined with the system's default condi=
tion for you
Reference
Beans
Beans defined, or expected to be defined, in conf/intercept/con=
sent-intercept-config.xml:
Bean ID / Type |
Function |
shibboleth.consent.terms-of-use.Key
Function<Profi=
leRequestContext,String>=
p> |
Function which returns the key used to (1) lookup terms of use messages =
and when concatenated with the user key to (2) lookup storage records, defa=
ults to the relying party ID |
shibboleth.consent.attribute-release.rp.Key 4.1
Function<Profi=
leRequestContext,String>=
p> |
Function which returns the key which is concatenated with the user =
key to lookup storage records, defaults to the relying party ID.
Overriding this bean allows a single consent record to cover multiple Re=
lying Parties. |
shibboleth.consent.attribute-release.PromptedAttributeIDs 4.1=
shibboleth.consent.attribute-release.WhitelistedAttributeIDs
(DEPRECATED)
Set<String> |
List of attribute IDs for which consent should be obtained |
shibboleth.consent.attribute-release.IgnoredAttributeIDs 4.1
shibboleth.consent.attribute-release.BlacklistedAttributeIDs
(DEPRECATED)
Set<String> |
List of attribute IDs for which consent should not be obtained |
shibboleth.consent.attribute-release.MatchExpression
Pattern |
Regular expression matching the attribute IDs for which consent should b=
e obtained |
shibboleth.consent.attribute-release.AuditFormattingMap
Map<String,List<String>> |
Attribute release audit log format, maps logger name to audit fields =
|
shibboleth.consent.terms-of-use.AuditFormattingMap
Map<String,List<String>> |
Terms of use audit log format, maps logger name to audit fields |
shibboleth.consent.PreConsentAuditExtractors
Map<String,F=
unction<ProfileRequestContext,Object>> |
Audit fields in addition to the default fields populated at the start of=
the consent flow |
shibboleth.consent.ConsentAuditExtractors
Map<String,F=
unction<ProfileRequestContext,Object>> |
Audit fields in addition to the default fields used when writing the aud=
it log |
shibboleth.consent.AttributeSymbolics
Map<String> |
Limits storage record size by mapping attribute IDs to numbers |
shibboleth.consent.DefaultAttributeSymbolics &nbs=
p; &=
nbsp;
Map<String> |
Default map that can be used as a parent bean for the bean above to merg=
e in additional values |
shibboleth.consent.AttributeQuery.Condition
Predicate<Pro=
fileRequestContext> |
Condition that determines whether to apply prior consent decisions in se=
rver-side storage to back-channel query requests. Defaults to FALSE.
|
Properties
Relevant properties defined in conf/idp.properties:
Property / Type |
Default |
Function |
idp.consent.StorageService
Bean ID |
shibboleth.ClientPersistentStorageService |
Name of storage service used to store users' consent choices |
idp.consent.userStorageKey
Bean ID |
shibboleth.consent.PrincipalConsentStorageKey |
DEPRECATED
Name of function used to return the String storage key representing a us=
er, defaults to the principal name |
idp.consent.attribute-release.userStorageKey
Bean ID |
shibboleth.consent.PrincipalConsentStorageKey |
Replacement for "idp.consent.userStorageKey" specific to attribute-relea=
se flow |
idp.consent.terms-of-use.userStorageKey
Bean ID |
shibboleth.consent.PrincipalConsentStorageKey |
Replacement for "idp.consent.userStorageKey" specific to terms-of-use fl=
ow |
idp.consent.userStorageKeyAttribute
String |
uid |
DEPRECATED
Attribute whose value is the storage key representing a user, only used =
when idp.consent.userStorageKey =3D shibboleth.consent.AttributeConsentStor=
ageKey |
idp.consent.attribute-release.userStorageKeyAttribute
String |
uid |
Replacement for "idp.consent.userStorageKeyAttribute" specific to attrib=
ute-release flow |
idp.consent.terms-of-use.userStorageKeyAttribute
String |
uid |
Replacement for "idp.consent.userStorageKeyAttribute" specific to terms-=
of-use flow |
idp.consent.attribute-release.activationCondition 4.1
Bean ID |
shibboleth.Conditions.TRUE |
Optional condition to apply to control activation of attribute-release f=
low along with system default behavior |
idp.consent.terms-of-use.activationCondition 4.1
Bean ID |
shibboleth.Conditions.TRUE |
Optional condition to apply to control activation of terms-of-use flow=
p> |
idp.consent.allowDoNotRemember
Boolean |
true |
Whether not remembering/storing consent is allowed |
idp.consent.allowGlobal
Boolean |
true |
Whether consent to any attribute and to any relying party is allowed =
|
idp.consent.allowPerAttribute
Boolean |
false |
Whether per-attribute consent is allowed |
idp.consent.compareValues
Boolean |
false |
Whether attribute values and terms of use text are stored and compared f=
or equality |
idp.consent.maxStoredRecords
Integer |
10 |
Maximum number of records stored when using space-limited storage (e.g. =
cookies), 0 =3D no limit |
idp.consent.expandedMaxStoredRecords
Integer |
0 |
Maximum number of records stored when using larger/server-side storage, =
0 =3D no limit |
idp.consent.storageRecordLifetime
Duration |
P1Y4.0 Infinite4.1+ |
Time in milliseconds to expire consent storage records |
Messages
=
p>
Relevant messages overridable via messages/messages.properties:=
Message |
Text |
no-release.title |
Title of error page displayed when attribute release consent is rejected=
|
no-release.message |
Text of error page displayed when attribute release consent is rejected<=
/p> |
no-terms.title |
Title of error page displayed when terms of use consent is rejected <=
/td>
|
no-terms.message |
Text of error page displayed when terms of use consent is rejected =
td>
|
V3 Compatibility
An IdP can be upgraded to the current version without any changes, but t=
here are issues around the sorting and hashing of attribute values that may=
cause unexpected re-prompting for consent even when the actual values of a=
n attribute haven't changed.
V4.1 resolves this bug going forward but cannot correct the issue retroa=
ctively.
Prior to V4.1, avoiding use of consent with multi-valued attributes is o=
ne workaround.
------=_Part_18_518547849.1711653406176
Content-Type: image/png
Content-Transfer-Encoding: base64
Content-Location: file:///C:/dcc286f285661dc98ca1f8dec5511d9027fc767b2b194fd56c029fae177413fc
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAA3NCSVQICAjb4U/gAAAAFVBMVEX/
//9wcHBwcHBwcHBwcHBwcHBwcHA3RenHAAAAB3RSTlMAZoiZzN3/SzZomQAAAAlwSFlzAAALEgAA
CxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAAAUdEVYdENy
ZWF0aW9uIFRpbWUANi8xLzEzOKlF0AAAACFJREFUCJljYCATsCgwqIAZTMnMyRAhsTABCIMxkVxT
GQCLcwHyUKXpLgAAAABJRU5ErkJggg==
------=_Part_18_518547849.1711653406176--