<html>
  <head>
    <meta content="text/html; charset=windows-1252"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <p><br>
    </p>
    <br>
    <div class="moz-cite-prefix">On 7/26/16 3:17 PM, Robert A Basch
      wrote:<br>
    </div>
    <blockquote cite="mid:CFD38445-7774-43E4-B151-EC7E7DC68850@mit.edu"
      type="cite">
      <pre wrap="">

First of all, I found that this setting apparently needs to be included
in Liberty.SSOS override for the second-tier SP, instead of (or maybe in
addition to?) that of the first-tier SP.
</pre>
    </blockquote>
    <br>
    If I understand what you are saying, I think that you are indeed
    correct in that the sense of the policy bits applied here is
    reversed from that in the v2 extension, and is applied to the
    "other" party in the exchange.  The reason was mostly practical: it
    was going to be very difficult to replicate the v2 way given the way
    the v3 relying party config stuff works.  The way it worked in v2
    was arbitrary anyway, sort of a big endian/little endian choice. 
    Scott expressed a mild preference for it working in the other
    direction, so I took the path of least resistance and changed it.<br>
    <br>
    This is how it's supposed to work: Here are 2 example RP configs
    from my test system.  The portal.example.edu one is what (I think)
    you are calling the first tier SP - it's the initial plain old
    browser-facing SAML SSO SP, that gets a specially-decorated
    Assertion.  The service.example.com one is the SP "behind" the
    portal one, issuing ECP requests to the IdP "through" the portal
    one.<br>
    <br>
    <br>
    <tt>        <bean parent="RelyingPartyByName" c:relyingPartyIds="</tt><tt><tt><a class="moz-txt-link-freetext" href="https://portal.example.edu/shibboleth">https://portal.example.edu/shibboleth</a></tt>"></tt><tt><br>
    </tt><tt>            <property name="profileConfigurations"></tt><tt><br>
    </tt><tt>                <list></tt><tt><br>
    </tt><tt>                    <bean parent="SAML2.SSO"
      p:encryptAssertions="false" p:encryptNameIDs="false"
      p:allowDelegation="true" p:maximumTokenDelegationChainLength="3"
      /></tt><tt><br>
    </tt><tt>                </tt><tt></list></tt><tt><br>
    </tt><tt>            </property></tt><tt><br>
    </tt><tt>        </bean></tt><tt><br>
    </tt><tt><br>
    </tt><tt><br>
    </tt><tt>        <bean parent="RelyingPartyByName"
      c:relyingPartyIds=<a class="moz-txt-link-rfc2396E" href="https://service.example.com/shibboleth">"https://service.example.com/shibboleth"</a>></tt><tt><br>
    </tt><tt>            <property name="profileConfigurations"></tt><tt><br>
    </tt><tt>                <list></tt><tt><br>
    </tt><tt>                    <bean parent="Liberty.SSOS"></tt><tt><br>
    </tt><tt>                        <property
      name="delegationPredicate"></tt><tt><br>
    </tt><tt>                            <bean
      parent="shibboleth.Conditions.AllowedSAMLPresenters"
      p:allowedPresenters=<a class="moz-txt-link-rfc2396E" href="https://portal.example.edu/shibboleth">"https://portal.example.edu/shibboleth"</a> /></tt><tt><br>
    </tt><tt>                        </property></tt><tt><br>
    </tt><tt>                    </bean></tt><tt><br>
    </tt><tt>                </list></tt><tt><br>
    </tt><tt>            </property></tt><tt><br>
    </tt><tt>        </bean></tt><br>
    <br>
    <br>
    <br>
    Couple of things to note:<br>
    <br>
    1) You put the main policy bits on the Liberty.SSOS profile.  It can
    be any Predicate<ProfileRequestContext>, but the usual sense
    is "which SP(s) acting in the SAML SSO Presenter role are eligible
    to present a delegated Assertion for purposes of authenticating to
    this RP".  For that most common sense you typically just want to
    enumerate one or more presenter entityIDs.  And so there is a
    supplied abstract parent utility predicate bean for that purpose
    'shibboleth.Conditions.AllowedSAMLPresenters', where you just have
    to supply the allowed presenter(s).  The value there can also be a
    list of entityIDs in SpEL, e.g:<br>
    <br>
    "#{ {'<a class="moz-txt-link-freetext" href="https://portal.example.edu/shibboleth">https://portal.example.edu/shibboleth</a>',
    '<a class="moz-txt-link-freetext" href="https://portalXXX.bogus.com/shibboleth">https://portalXXX.bogus.com/shibboleth</a>'} }"<br>
    <br>
    <br>
    2) IIRC this is the same as in v2, but just noting since your
    example had otherwise: the maximumTokenDelegationChainLength is only
    effective on the initial SSO SP, as I have it there.  The policy set
    there applies to the whole delegation chain.  In the v3 approach,
    differing from v2, and again for reasons having to do with the
    changed RP config impl, the max delegation chain is actually
    inserted into the initial delegated Assertion as a custom
    DelegationPolicy element in the Assertion's Advice element, and then
    simply gets copied into new Assertions issued off of it.<br>
    <br>
    <br>
    <br>
    <blockquote type="cite">
      <pre wrap="">Second, while it is now properly referencing the predicate bean, it is
not evaluating it in the way I expected, i.e. where its parent is
"shibboleth.Conditions.RelyingPartyId" and it contains (in the override
for the second-tier SP) a list of the first-tier SPs allowed to present
requests.  But, changing this bean to the "alwaysTrue" predicate does
make it get past the evaluation successfully, so there must still be
something about this predicate (or perhaps another setting) I am not
getting.</pre>
    </blockquote>
    <br>
    <br>
    Yeah, I think that might not be working correctly because that
    predicate is looking at the wrong context data.  It typically needs
    to evaluate the entityID of the SAML actor acting in the SSO
    Presenter role.  The one you're using doesn't do that.  Use the
    'shibboleth.Conditions.AllowedSAMLPresenters' instead, which was
    added specifically to support delegation, and you should be ok.<br>
    <br>
    <br>
    <blockquote type="cite">
      <pre wrap="">Putting this problem aside for the moment, I ran into another issue
in the handling of the SOAP request itself, while testing with the
"alwaysTrue" predicate; these seem to be the relevant log entries:</pre>
    </blockquote>
    <br>
    <br>
    Hmm, not sure on this.  A lot of this is swapped out of my brain at
    the moment.  I remember that the c14n stuff is special-cased in the
    Liberty SSOS flow, we actually skip most/all of the standard c14n
    subflows which are present in the regular SSO flow, but still have
    to perform c14n transformation of the presented Assertion's NameID
    back into the principal name.<br>
    <br>
    Once you get the above RP config issues fixed, seeing a full DEBUG
    log trace of the entire request into the Liberty SSOS endpoint might
    be helpful.<br>
    <br>
    <br>
    <blockquote type="cite">
      <pre wrap="">
WARN [net.shibboleth.idp.saml.nameid.impl.BaseCryptoTransientDecoder:117] -
 Crypto Transient Decoder 'net.shibboleth.idp.saml.nameid.impl.CryptoTransientNameIDDecoder#<number>':
 Transient identifier issued to <SP1> but requested by <SP2></pre>
    </blockquote>
    <br>
    So I infer from this that you are indeed using the crypto transient
    plugin to issue transient NameIDs here? <br>
    <br>
    <br>
    <blockquote type="cite">
      <pre wrap="">
The result was an "UnknownPrincipal" error returned in the response.

I believe we are using the standard v3 transient ID generation.</pre>
    </blockquote>
    <br>
    Maybe crypto transient is the default now, rather than transient. I
    don't remember.  Scott or Tom probably knows.<br>
    <br>
    <blockquote type="cite">
      <pre wrap="">

Any ideas on what the problem is here, or what additional config we
may be missing?</pre>
    </blockquote>
    <br>
    <br>
    I have a suspicion that there might be a bug here.  The NameID types
    like transient/cryptotransient and persistent are explicitly
    associated with the RP to whom the NameID was issued, and I believe
    have to be looked up on that basis during SAML Subject c14n.  I
    suspect that the RP in effect for the Assertion Subject c14n here is
    erroneously the current requesting RP (i.e. the Liberty SSOS RP),
    and not the SP to whom the assertion was issued (based on Assertion
    data, etc).  So there is a mismatch and the lookup fails, as in the
    crypto transient decoder WARN message above.<br>
    <br>
    I don't think I ever tested the transient NameID case for the SSOS
    flow, and I'm not that familiar with the c14n impls. (I think we did
    say upfront that due to the low use it gets there's probably bugs in
    the new delegation support... :-) )<br>
    <br>
    For purposes of note taking and the dev team: I think during
    Assertion Subject c14n the
    SubjectCanonicalizationContext#requesterId in this case needs to
    hold the entityID of the RP to whom the transient/persistent was
    issued.  Correct?  But right now in ProcessDelegatedAssertion it's
    doing what the original regular c14n action code from which it was
    copied does:
c14n.setRequesterId(requesterLookupStrategy.apply(profileRequestContext)). 
    And I think that's wrong, it should be (somehow) obtaining the
    entityID of the RP to whom the NameID was originally issued and use
    that as the c14n context requesterId.  Scott/Tom/Rod: does this
    sound correct?  If so I'll open a Jira issue.<br>
    <br>
    Assuming a bug: As far as a temporary workaround, I know that this
    all works for cases where the NameID isn't pairwise with an RP and
    doesn't need to be "reversed", e.g. where it's a "direct" transform,
    like unspecified (i.e with the principal name), emailAddress, etc. 
    So you could configure the IdP to issue Assertions with one of those
    sorts of NameIDs to the initial SSO SP, and that would I think avoid
    the problem.<br>
    <br>
    --Brent<br>
    <br>
    <br>
    <br>
    <br>
  </body>
</html>