delegation in IDP3
Brent Putman
putmanb at georgetown.edu
Tue Jul 26 17:08:01 EDT 2016
On 7/26/16 3:17 PM, Robert A Basch wrote:
>
> 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.
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.
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.
<bean parent="RelyingPartyByName"
c:relyingPartyIds="https://portal.example.edu/shibboleth">
<property name="profileConfigurations">
<list>
<bean parent="SAML2.SSO" p:encryptAssertions="false"
p:encryptNameIDs="false" p:allowDelegation="true"
p:maximumTokenDelegationChainLength="3" />
</list>
</property>
</bean>
<bean parent="RelyingPartyByName"
c:relyingPartyIds="https://service.example.com/shibboleth">
<property name="profileConfigurations">
<list>
<bean parent="Liberty.SSOS">
<property name="delegationPredicate">
<bean
parent="shibboleth.Conditions.AllowedSAMLPresenters"
p:allowedPresenters="https://portal.example.edu/shibboleth" />
</property>
</bean>
</list>
</property>
</bean>
Couple of things to note:
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:
"#{ {'https://portal.example.edu/shibboleth',
'https://portalXXX.bogus.com/shibboleth'} }"
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.
> 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.
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.
> 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:
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.
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.
> 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>
So I infer from this that you are indeed using the crypto transient
plugin to issue transient NameIDs here?
> The result was an "UnknownPrincipal" error returned in the response.
>
> I believe we are using the standard v3 transient ID generation.
Maybe crypto transient is the default now, rather than transient. I
don't remember. Scott or Tom probably knows.
>
> Any ideas on what the problem is here, or what additional config we
> may be missing?
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.
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... :-) )
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.
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.
--Brent
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://shibboleth.net/pipermail/users/attachments/20160726/1e4586a9/attachment-0001.html>
More information about the users
mailing list