Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Simple conditions, and those requiring to be reloadable, should be placed in a standalone file loaded via conf/services.xml.

Expand
titleBean defintion for selection by Relying Party ID

...

expand
Code Block
languagexml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:c="http://www.springframework.org/schema/c"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
 
    <bean id="ExampleOrgPredicate" parent="shibboleth.Conditions.RelyingPartyId" c:candidate="https://sp.example.com/shibboleth" />
</beans>

This file must be supplied to the appropriate resource list in conf/services.xml.  For instance for the Attribute Resolver:

Including an extra file in services.xml
Code Block
languagexml
<util:list id ="shibboleth.AttributeResolverResources">
    <value>${idp.home}/conf/attribute-resolver.xml</value>
    <value>${idp.home}/conf/THE_NEW_FILE.xml</value>
</util:list>

...

A built-in bean is provided to make this use case simple. You should provide a list of names, providing a single name may not have the expected result.

Expand
titleSpecific Relying Parties by Name

...

expand
Code Block
languagexml
<!-- Single SP -->
<bean id="MyCondition" parent="shibboleth.Conditions.RelyingPartyId"
  c:candidate="https://sp.example.com/shibboleth" />

<!-- Multiple SPs, expression -->
<bean id="MyCondition" parent="shibboleth.Conditions.RelyingPartyId"
  c:candidates="#{{'https://sp.example.com/shibboleth', 'https://another.example.com/shibboleth'}}" />

<!-- Multiple SPs, list bean -->
<bean id="MyCondition" parent="shibboleth.Conditions.RelyingPartyId">
  <constructor-arg name="candidates">
    <list>
      <value>https://sp.example.com/shibboleth</value>
      <value>https://another.example.com/shibboleth</value>
    </list>
  </constructor-arg>
</bean>

A more advanced option supported by the same parent bean is the ability to plug-in an arbitrary condition to run against the relying party name. The input to such a condition is a String rather than the ProfileRequestContext.

Expand
titleTest a Regular Expression
Expand
Code Block
languagexml
<!-- Test a regular expression against the Relying Party name -->
<bean id="MyCondition" parent="shibboleth.Conditions.RelyingPartyId">
  <constructor-arg>
    <bean class="com.google.common.base.Predicates" factory-method="containsPattern"
      c:pattern="^https://[^/]+\.example\.com/shibboleth$" />
  </constructor-arg>
</bean>

You can also write a script (Javascript being the default language):

Expand
titleJavascript Example
Expand
Code Block
languagexml
<!-- A script that checks a Relying Party name -->
<bean id="MyCondition" parent="shibboleth.Conditions.Scripted" factory-method="inlineScript">
  <constructor-arg>
    <value>
    <![CDATA[
      "use strict";
      var result = false;

      // an implementation of Predicate<ProfileRequestContext>
      // The IdP environment provides two variables "profileContext" and "custom".  
      //     profileContext  is of type org.opensaml.profile.context.ProfileRequestContext
      //     custom          is whatever you injected 
      // The value of the last statement in this function is the reurn value
      var id = "https://sp.example.com/shibboleth";  // an entityID
      
      // specify the child context of the root ProfileRequestContext
      if (profileContext!== null) {
          // check the entityID of the relying party
          var subcontext = profileContext.getSubcontext("net.shibboleth.idp.profile.context.RelyingPartyContext");
          if (subcontext !== null) {
            result = subcontext.getRelyingPartyId().equals(id);
          }
      }
      result;
    ]]>
    </value>
  </constructor-arg>
</bean>

Finally, you can write Spring Expressions, sort of a more concise scripting format:

Expand
titleSpring Expression Example
Expand
Code Block
languagexml
<!-- A Spring Expression that checks a Relying Party name -->
<bean id="MyCondition" parent="shibboleth.Conditions.Expression">
  <constructor-arg>
    <value>
    #profileContext.getSubcontext(T(net.shibboleth.idp.profile.context.RelyingPartyContext)).getRelyingPartyId().equals("https://sp.example.com/shibboleth")
    </value>
  </constructor-arg>
</bean>

...

Most use cases for this feature tend to be for relying party overrides, which are already supported separately. If you need to use this kind of condition elsewhere, you can reuse the same code with this example:

Expand
titleRelying Parties By Group

...

expand
Code Block
languagexml
<!-- One group -->
<bean id="MyCondition" parent="shibboleth.Conditions.EntityDescriptor">
  <constructor-arg name="pred">
    <bean class="org.opensaml.saml.common.profile.logic.EntityGroupNamePredicate"
      c:_0="nameofgroup" />
  </constructor-arg>
</bean>

<!-- Multiple groups, expression -->
<bean id="MyCondition" parent="shibboleth.Conditions.EntityDescriptor">
  <constructor-arg name="pred">
    <bean class="org.opensaml.saml.common.profile.logic.EntityGroupNamePredicate"
      c:_0="#{{'group1', 'group2'}}" />
  </constructor-arg>
</bean>

<!-- Multiple groups, list bean -->
<bean id="MyCondition" parent="shibboleth.Conditions.EntityDescriptor">
  <constructor-arg name="pred">
    <bean class="org.opensaml.saml.common.profile.logic.EntityGroupNamePredicate">
      <constructor-arg>
        <list>
          <value>group1</value>
          <value>group2</value>
        </list>
      </constructor-arg>
    </bean>
  </constructor-arg>
</bean>

...

Most use cases for this feature tend to be for relying party overrides, which are already supported separately. If you need to use this kind of condition elsewhere, you can reuse the same code with this example:

Expand
titleRelying Party By Tag
Expand
Code Block
languagexml
<!-- Tag condition -->
<bean id="MyCondition" parent="shibboleth.Conditions.EntityDescriptor">
  <constructor-arg name="pred">
    <bean class="org.opensaml.saml.common.profile.logic.EntityAttributesPredicate">
      <constructor-arg>
        <list>
          <bean class="org.opensaml.saml.common.profile.logic.EntityAttributesPredicate.Candidate"
          c:name="http://macedir.org/entity-category"
          p:values="http://refeds.org/category/research-and-scholarship" />
        </list>
      </constructor-arg>
    </bean>
  </constructor-arg>
</bean>

...

The class provided supports only simple string-valued attributes, and supports a simple form of wildcarding to indicate that any value is acceptable as long as one exists.

Expand
titleAttribute Checking Examples

...

expand
Code Block
languagexml
<!-- Check for a particular entitlement -->
<bean class="net.shibboleth.idp.profile.logic.SimpleAttributePredicate" p:useUnfilteredAttributes="true">
  <property name="attributeValueMap">
    <map>
      <entry key="entitlement">
        <list>
          <value>urn:mace:dir:entitlement:common-lib-terms</value>
        </list>
      </entry>
    </map>
  </property>
</bean>

<!-- Check that an eduPersonPrincipalName exists -->
<bean class="net.shibboleth.idp.profile.logic.SimpleAttributePredicate">
  <property name="attributeValueMap">
    <map>
      <entry key="eppn">
        <list>
          <value>*</value>
        </list>
      </entry>
    </map>
  </property>
</bean>

...

The first example demonstrates an OR operation that is equivalent to earlier examples but illustrates the syntax. The argument to the condition is a collection of condition beans to OR together.

Expand
titleEither of Two Relying Parties
Expand
Code Block
languagexml
<!-- An OR used to check for one of two relying parties -->
<bean id="MyCondition" parent="shibboleth.Conditions.OR">
  <constructor-arg>
    <list>
      <bean parent="shibboleth.Conditions.RelyingPartyId" c:candidate="https://sp.example.com/shibboleth" />
      <bean parent="shibboleth.Conditions.RelyingPartyId" c:candidate="https://another.example.com/shibboleth" />
    </list>
  </constructor-arg>
</bean>

The second example demonstrates a compound condition that checks a specific SP AND for a particular client network range.

Expand
titleSpecific Relying Party AND Client Address Range
Expand
Code Block
languagexml
<!-- An AND checking for both an SP and a network address -->
<bean id="MyCondition" parent="shibboleth.Conditions.AND">
  <constructor-arg>
    <bean parent="shibboleth.Conditions.RelyingPartyId" c:candidate="https://sp.example.com/shibboleth" />
  </constructor-arg>
  <constructor-arg>
    <bean class="org.opensaml.profile.logic.IPRangePredicate"
      p:httpServletRequest-ref="shibboleth.HttpServletRequest"
      p:ranges="192.168.1.0/24" />
  </constructor-arg>
</bean>

Finally, a simple NOT example checking for any SP except for one:

Expand
titleNOT a Specific Relying Party

...

expand
Code Block
languagexml
<!-- Any SP except for one -->
<bean id="MyCondition" parent="shibboleth.Conditions.NOT">
  <constructor-arg>
    <bean parent="shibboleth.Conditions.RelyingPartyId" c:candidate="https://sp.example.com/shibboleth" />
  </constructor-arg>
</bean>

...