Impersonation AccessControlPolicy question
Robert Führicht
robert.fuehricht at jku.at
Thu Mar 4 14:47:22 UTC 2021
>> and have the input validated
>> against a regex (rather than a list of usernames) read from an attribute
>> (e.g. impersonatableUsernameRegex, to stick closely to the example).
>
> The policy is a bean implementing the appropriate interface, it can do anything you need, and implement, it to do.
I've used the access control policy below to achieve what I need. It's a
little clunky though, delegating access control to a groovy script function.
The script itself replicates roughly what DynamicAttributePredicate
does, but gives me control over the actual comparison logic - e.g. how
the values of attribute used are matched against the input given.
I'm baffled by the use of the function in the example (the
c:expression="#input.getSubcontext(T(org.opensaml.profile.context.AccessControlContext)).getResource()")
line given in the docs.
It just extracts the target username to impersonate against from the
ProfileRequestContext - a value the intercept form submits and that is
extracted the same way all the time.
I'd rather have the actual matching against allowed values be delegated
to a function being supplied by whoever manages the access control policy.
That example is ill fitted to explain the reasoning behind the
DynamicAttributePredicate class in my opinion.
> <entry key="SpecificImpersonationPolicy">
> <bean parent="shibboleth.PredicateAccessControl">
> <constructor-arg>
> <bean parent="shibboleth.Conditions.AND">
> <constructor-arg>
> <bean parent="shibboleth.Conditions.Scripted" factory-method="inlineScript" p:hideExceptions="false">
> <constructor-arg>
> <value>
> groovy
> </value>
> </constructor-arg>
> <constructor-arg>
> <value>
> <![CDATA[
> package at.jku
>
> import org.slf4j.*
> import net.shibboleth.idp.attribute.*
> import net.shibboleth.idp.attribute.context.*
> import net.shibboleth.idp.profile.context.*
> import org.opensaml.messaging.context.navigate.ChildContextLookup
> import org.opensaml.profile.context.ProfileRequestContext
> import org.opensaml.profile.context.AccessControlContext
>
> /*
> * Objective:
> * Vary the list of acceptable Usernames for impersonation on per-account basis
> *
> * Solution:
> * Introduce an attribute "impersonatableUserRegex" that holds a regular expression
> * against which the input from the impersonation form is tested.
> *
> * Limitations:
> * - Single value
> * - Not relying party dependant
> */
> def logger = LoggerFactory.getLogger("at.jku.script.impersonationfilter")
> logger.debug("script start")
> logger.debug("input="+input)
> logger.debug("custom="+custom)
>
> // Necessary prerequisite to query attributes (see net.shibboleth.idp.profile.logic.AbstractAttributePredicate)
> def attributeContextLookupStrategy = new ChildContextLookup<>(AttributeContext.class).compose(
> new ChildContextLookup<>(RelyingPartyContext.class)
> );
> /*
> * Attributes used for impersonation are likely not handed out to the SP.
> * We must use the unfiltered attribute set then to make our decision.
> */
> def attributes = attributeContextLookupStrategy.apply(input).getUnfilteredIdPAttributes()
> logger.debug("attributes="+attributes)
> // Extract target username for impersonation from the ProfileRequestContext
> def username = input.getSubcontext(AccessControlContext.class).getResource()
> // Query attribute containing the regular expression
> def impersonatableUserRegex = attributes.get("impersonatableUserRegex")
> logger.info("username="+username)
> logger.info("impersonatableUserRegex="+impersonatableUserRegex)
>
> // Finally match against the regex
> (impersonatableUserRegex != null) ? username ==~ impersonatableUserRegex.values[0].value : false
> ]]>
> </value>
> </constructor-arg>
> </bean>
> </constructor-arg>
> <constructor-arg>
> <bean class="net.shibboleth.idp.profile.logic.DynamicAttributePredicate">
> <property name="attributeFunctionMap">
> <map>
> <entry key="impersonatableServices">
> <list>
> <bean parent="shibboleth.RelyingPartyIdLookup.Simple" />
> </list>
> </entry>
> </map>
> </property>
> </bean>
> </constructor-arg>
> </bean>
> </constructor-arg>
> </bean>
> </entry>
More information about the users
mailing list