How to use shibboleth.context-check.Function

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

How to use shibboleth.context-check.Function

Morgan, Andrew Jason
We have some services that won't do their own authorization, so we have multiple context checkers in Shibboleth.  Each of them checks for membership in an access group, like this:

    <bean id="ContextCheckPredicate" parent="shibboleth.Conditions.AND">
        <constructor-arg>
            <list>
                <bean parent="shibboleth.Conditions.RelyingPartyId" c:candidate="https://services.box.com/sp" />
                <bean class="net.shibboleth.idp.profile.logic.RegexAttributePredicate"
                        p:useUnfilteredAttributes="true"
                        p:attributeId="ismemberof"
                        p:pattern="(?i)cn=eligible,ou=box,ou=app,ou=is,ou=org,ou=osu,ou=grouper,ou=groups,o=orst.edu" />
            </list>
        </constructor-arg>
    </bean>

It's been on my list to investigate shibboleth.context-check.Function to simplify this.

I think I can replace it with the following:

<util:map id="ConditionMap">
    <entry key="https://services.box.com/sp">
        <ref bean="box-access-condition"/>
    </entry>
</util:map>

<bean id="box-access-condition" class="net.shibboleth.idp.profile.logic.RegexAttributePredicate"
                        p:useUnfilteredAttributes="true"
                        p:attributeId="ismemberof"
                        p:pattern="(?i)cn=eligible,ou=box,ou=app,ou=is,ou=org,ou=osu,ou=grouper,ou=groups,o=orst.edu" />

<bean id="shibboleth.context-check.Function" parent="shibboleth.ContextFunctions.Scripted" factory-method="inlineScript"
        p:customObject-ref="ConditionMap">
    <constructor-arg>
        <value>
        <![CDATA[
        var event = "proceed";
        var rpid = input.getSubcontext(
                "net.shibboleth.idp.profile.context.RelyingPartyContext").getRelyingPartyId();
        var condition = custom.get(rpid);
        if (condition != null && !condition.apply(input)) {
            event = "ContextCheckDenied";
        }
        event;
        ]]>
        </value>
    </constructor-arg>
</bean>

Is that correct?

Is it possible to define the ConditionMap in a way that won't require me to restart Shibboleth when I make a change?

Thanks,
Andy Morgan
Identity & Access Management
Oregon State University

--
For Consortium Member technical support, see https://wiki.shibboleth.net/confluence/x/coFAAg
To unsubscribe from this list send an email to [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: How to use shibboleth.context-check.Function

John C. Pfeifer
Move the scripted part to the attribute-resolver.xml (I have an attribute definition called authorizedUser) since that file is reloadable. My conf/intercept/context-check-intercept-config.xml then looks like:

    <util:map id="context-check.Map">
        <entry key="authorizedUser" value="*" />
    </util:map>

    <bean id="shibboleth.context-check.Condition" class="net.shibboleth.idp.profile.logic.SimpleAttributePredicate"
           p:useUnfilteredAttributes="true"
           p:attributeValueMap-ref="context-check.Map" />


> On Jan 13, 2020, at 8:22 PM, Morgan, Andrew Jason <[hidden email]> wrote:
>
> We have some services that won't do their own authorization, so we have multiple context checkers in Shibboleth.  Each of them checks for membership in an access group, like this:
>
>     <bean id="ContextCheckPredicate" parent="shibboleth.Conditions.AND">
>         <constructor-arg>
>             <list>
>                 <bean parent="shibboleth.Conditions.RelyingPartyId" c:candidate="https://services.box.com/sp" />
>                 <bean class="net.shibboleth.idp.profile.logic.RegexAttributePredicate"
>                         p:useUnfilteredAttributes="true"
>                         p:attributeId="ismemberof"
>                         p:pattern="(?i)cn=eligible,ou=box,ou=app,ou=is,ou=org,ou=osu,ou=grouper,ou=groups,o=orst.edu" />
>             </list>
>         </constructor-arg>
>     </bean>
>
> It's been on my list to investigate shibboleth.context-check.Function to simplify this.
>
> I think I can replace it with the following:
>
> <util:map id="ConditionMap">
>     <entry key="https://services.box.com/sp">
>         <ref bean="box-access-condition"/>
>     </entry>
> </util:map>
>
> <bean id="box-access-condition" class="net.shibboleth.idp.profile.logic.RegexAttributePredicate"
>                         p:useUnfilteredAttributes="true"
>                         p:attributeId="ismemberof"
>                         p:pattern="(?i)cn=eligible,ou=box,ou=app,ou=is,ou=org,ou=osu,ou=grouper,ou=groups,o=orst.edu" />
>
> <bean id="shibboleth.context-check.Function" parent="shibboleth.ContextFunctions.Scripted" factory-method="inlineScript"
>         p:customObject-ref="ConditionMap">
>     <constructor-arg>
>         <value>
>         <![CDATA[
>         var event = "proceed";
>         var rpid = input.getSubcontext(
>                 "net.shibboleth.idp.profile.context.RelyingPartyContext").getRelyingPartyId();
>         var condition = custom.get(rpid);
>         if (condition != null && !condition.apply(input)) {
>             event = "ContextCheckDenied";
>         }
>         event;
>         ]]>
>         </value>
>     </constructor-arg>
> </bean>
>
> Is that correct?
>
> Is it possible to define the ConditionMap in a way that won't require me to restart Shibboleth when I make a change?
>
> Thanks,
> Andy Morgan
> Identity & Access Management
> Oregon State University
> --
> For Consortium Member technical support, see https://wiki.shibboleth.net/confluence/x/coFAAg
> To unsubscribe from this list send an email to [hidden email]


//
John Pfeifer
Division of Information Technology
University of Maryland, College Park

--
For Consortium Member technical support, see https://wiki.shibboleth.net/confluence/x/coFAAg
To unsubscribe from this list send an email to [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: How to use shibboleth.context-check.Function

Cantor, Scott E.
In reply to this post by Morgan, Andrew Jason
On 1/13/20, 8:23 PM, "users on behalf of Morgan, Andrew Jason" <[hidden email] on behalf of [hidden email]> wrote:

> Is that correct?

Yes, more or less.

> Is it possible to define the ConditionMap in a way that won't require me to restart Shibboleth when I make a change?

I built a possible way to do it for V4 but it's fragile and not very easy to use, and doesn't always get the intended result. I find myself conflicted in that while I personally have leveraged the reloadability paradigm, and probably will continue to, the world is enamored of Docker and the idea that any change of any size means completely replacing the running system. So it's hard to justify continuing to invest in more and more reloadability tricks.

Generally it's probably better to try and push that kind of thing into the resolver and try and get a consistent answer out that you can code a single condition against.

The purpose of the function mechanism is more to support alternative error events coming back since the old condition model had to produce just a single ContextCheckDenied outcome.
 
-- Scott


--
For Consortium Member technical support, see https://wiki.shibboleth.net/confluence/x/coFAAg
To unsubscribe from this list send an email to [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: How to use shibboleth.context-check.Function

Cantor, Scott E.
In reply to this post by John C. Pfeifer
On 1/14/20, 8:31 AM, "John C. Pfeifer" <[hidden email]> wrote:

> Move the scripted part to the attribute-resolver.xml (I have an attribute definition called authorizedUser) since that
> file is reloadable.

Ninja'd, that's basically what I'd suggest.

-- Scott


--
For Consortium Member technical support, see https://wiki.shibboleth.net/confluence/x/coFAAg
To unsubscribe from this list send an email to [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: How to use shibboleth.context-check.Function

Morgan, Andrew Jason
In reply to this post by John C. Pfeifer
This worked great!  For the list archives, I made the following configuration:

conf/intercept/context-check-intercept-config.xml:

    <bean id="shibboleth.context-check.Condition" class="net.shibboleth.idp.profile.logic.SimpleAttributePredicate" p:useUnfilteredAttributes="true">
        <property name="attributeValueMap">
            <map>
                <entry key="context_check">
                    <list>
                        <value>1</value>
                    </list>
                </entry>
            </map>
        </property>
    </bean>

conf/attribute-resolver.xml:

    <AttributeDefinition id="context_check" xsi:type="ScriptedAttribute">
        <InputDataConnector ref="ONIDLDAP" attributeNames="ismemberof" />
        <Script><![CDATA[
            logger = Java.type("org.slf4j.LoggerFactory").getLogger("net.shibboleth.idp.attribute.resolver.check_context");
            rpid = profileContext.getSubcontext("net.shibboleth.idp.profile.context.RelyingPartyContext").getRelyingPartyId();
            logger.debug("rpid=" + rpid);
            access = "0";

            // Lynda
            if (rpid.equals("https://shib.lynda.com/shibboleth-sp")) {
                for (i=0; i < ismemberof.getValues().size(); i++) {
                    tmp = ismemberof.getValues().get(i);
                    if (tmp.toLowerCase().equals("cn=lynda-eligible,ou=lynda,ou=app,ou=is,ou=org,ou=osu,ou=grouper,ou=groups,o=orst.edu")) {
                        logger.debug("Access granted to Lynda");
                        access = "1";
                    }
                }
            }
   ... else if other RPs ...
            // All others, grant access
            else {
                access = "1";
            }

            context_check.addValue(access);
            logger.debug("context_check final value: " + context_check.getValues().get(0));
        ]]></Script>
    </AttributeDefinition>

Anytime I want a new access check, I modify this scripted attribute and reload it.

Thanks,
Andy




From: users <[hidden email]> on behalf of John C. Pfeifer <[hidden email]>
Sent: Tuesday, January 14, 2020 5:30 AM
To: Shib Users <[hidden email]>
Subject: Re: How to use shibboleth.context-check.Function
 
Move the scripted part to the attribute-resolver.xml (I have an attribute definition called authorizedUser) since that file is reloadable. My conf/intercept/context-check-intercept-config.xml then looks like:

    <util:map id="context-check.Map">
        <entry key="authorizedUser" value="*" />
    </util:map>

    <bean id="shibboleth.context-check.Condition" class="net.shibboleth.idp.profile.logic.SimpleAttributePredicate"
           p:useUnfilteredAttributes="true"
           p:attributeValueMap-ref="context-check.Map" />


> On Jan 13, 2020, at 8:22 PM, Morgan, Andrew Jason <[hidden email]> wrote:
>
> We have some services that won't do their own authorization, so we have multiple context checkers in Shibboleth.  Each of them checks for membership in an access group, like this:
>
>     <bean id="ContextCheckPredicate" parent="shibboleth.Conditions.AND">
>         <constructor-arg>
>             <list>
>                 <bean parent="shibboleth.Conditions.RelyingPartyId" c:candidate="https://services.box.com/sp" />
>                 <bean class="net.shibboleth.idp.profile.logic.RegexAttributePredicate"
>                         p:useUnfilteredAttributes="true"
>                         p:attributeId="ismemberof"
>                         p:pattern="(?i)cn=eligible,ou=box,ou=app,ou=is,ou=org,ou=osu,ou=grouper,ou=groups,o=orst.edu" />
>             </list>
>         </constructor-arg>
>     </bean>
>
> It's been on my list to investigate shibboleth.context-check.Function to simplify this.
>
> I think I can replace it with the following:
>
> <util:map id="ConditionMap">
>     <entry key="https://services.box.com/sp">
>         <ref bean="box-access-condition"/>
>     </entry>
> </util:map>
>
> <bean id="box-access-condition" class="net.shibboleth.idp.profile.logic.RegexAttributePredicate"
>                         p:useUnfilteredAttributes="true"
>                         p:attributeId="ismemberof"
>                         p:pattern="(?i)cn=eligible,ou=box,ou=app,ou=is,ou=org,ou=osu,ou=grouper,ou=groups,o=orst.edu" />
>
> <bean id="shibboleth.context-check.Function" parent="shibboleth.ContextFunctions.Scripted" factory-method="inlineScript"
>         p:customObject-ref="ConditionMap">
>     <constructor-arg>
>         <value>
>         <![CDATA[
>         var event = "proceed";
>         var rpid = input.getSubcontext(
>                 "net.shibboleth.idp.profile.context.RelyingPartyContext").getRelyingPartyId();
>         var condition = custom.get(rpid);
>         if (condition != null && !condition.apply(input)) {
>             event = "ContextCheckDenied";
>         }
>         event;
>         ]]>
>         </value>
>     </constructor-arg>
> </bean>
>
> Is that correct?
>
> Is it possible to define the ConditionMap in a way that won't require me to restart Shibboleth when I make a change?
>
> Thanks,
> Andy Morgan
> Identity & Access Management
> Oregon State University
> --
> For Consortium Member technical support, see https://wiki.shibboleth.net/confluence/x/coFAAg
> To unsubscribe from this list send an email to [hidden email]


//
John Pfeifer
Division of Information Technology
University of Maryland, College Park

--
For Consortium Member technical support, see https://wiki.shibboleth.net/confluence/x/coFAAg
To unsubscribe from this list send an email to [hidden email]

--
For Consortium Member technical support, see https://wiki.shibboleth.net/confluence/x/coFAAg
To unsubscribe from this list send an email to [hidden email]