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