<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>