You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
OneTimeUse is refused as of #42, on the grounds that honouring it means remembering which assertions have been spent and this SP keeps no such record. The refusal rests on a reading of SAML Core 2.5.1.5 that the text does not support. Verbatim:
For the purposes of determining the validity of the <Conditions> element, the <OneTimeUse> is considered to always be valid. That is, this condition does not affect validity but is a condition on use.
The record is a SHOULD ("a relying party should maintain a cache of the assertions it has processed containing such a condition"), and the one MUST binds implementations that retain assertions for future use, which this SP does not: it reads the assertion once, mints its own session, and drops the document. So an assertion carrying the condition is understood and Valid whatever the SP has configured, and refusing it as Indeterminate under 2.5.1.1 rule 3 (an element "not understood") is the SP getting the spec wrong.
Every peer reads it that way. Spring Security's default validator returns VALID for OneTimeUse ("applications should validate their own OneTimeUse conditions"), Shibboleth SP's default policy ignores it, Keycloak's broker checks only that there is at most one, python3-saml and passport-saml do nothing with it. ADFS 2.0 is the one refuser, and Microsoft's own remedy is to switch the condition off at the IdP.
What it should do
Accept OneTimeUse in every case.
carry the condition through the reader, as a flag on saml_assertion_t and a field on the Lua table, rather than letting it fall into unknown_condition
put it back on is_known_condition in src/xml.c
with replay_dict set, nothing more is needed: fix: let an assertion be presented only once #50 already remembers every accepted assertion, so the single use the IdP asked for is enforced for real
with replay_dict unset, let the login through and log a warning naming replay_dict, so an operator reads it as something to configure
Why it is worth doing
Keycloak emits the condition behind a per-client toggle, "Include OneTimeUse Condition" (saml.onetimeuse.condition). Before #42 those IdPs logged in and simply got no single-use enforcement. #42 turned that into an outright refusal, so an IdP that worked before stops working, and neither the APISIX nor the EE saml-auth plugin exposes replay_dict, so there is no configuration that gets past it. That regression ships the moment v0.2.6 goes out, so this lands before #39.
Refusing buys no security: the flag is the IdP's advisory to the SP, and a party replaying a captured assertion does not care whether it is present.
Notes
Raised by @jarvis9443 reviewing #42. Depends on #50, which has merged.
What
OneTimeUseis refused as of #42, on the grounds that honouring it means remembering which assertions have been spent and this SP keeps no such record. The refusal rests on a reading of SAML Core 2.5.1.5 that the text does not support. Verbatim:The record is a SHOULD ("a relying party should maintain a cache of the assertions it has processed containing such a condition"), and the one MUST binds implementations that retain assertions for future use, which this SP does not: it reads the assertion once, mints its own session, and drops the document. So an assertion carrying the condition is understood and Valid whatever the SP has configured, and refusing it as Indeterminate under 2.5.1.1 rule 3 (an element "not understood") is the SP getting the spec wrong.
Every peer reads it that way. Spring Security's default validator returns
VALIDforOneTimeUse("applications should validate their own OneTimeUse conditions"), Shibboleth SP's default policy ignores it, Keycloak's broker checks only that there is at most one, python3-saml and passport-saml do nothing with it. ADFS 2.0 is the one refuser, and Microsoft's own remedy is to switch the condition off at the IdP.What it should do
Accept
OneTimeUsein every case.saml_assertion_tand a field on the Lua table, rather than letting it fall intounknown_conditionis_known_conditioninsrc/xml.creplay_dictset, nothing more is needed: fix: let an assertion be presented only once #50 already remembers every accepted assertion, so the single use the IdP asked for is enforced for realreplay_dictunset, let the login through and log a warning namingreplay_dict, so an operator reads it as something to configureWhy it is worth doing
Keycloak emits the condition behind a per-client toggle, "Include OneTimeUse Condition" (
saml.onetimeuse.condition). Before #42 those IdPs logged in and simply got no single-use enforcement. #42 turned that into an outright refusal, so an IdP that worked before stops working, and neither the APISIX nor the EEsaml-authplugin exposesreplay_dict, so there is no configuration that gets past it. That regression ships the moment v0.2.6 goes out, so this lands before #39.Refusing buys no security: the flag is the IdP's advisory to the SP, and a party replaying a captured assertion does not care whether it is present.
Notes
Raised by @jarvis9443 reviewing #42. Depends on #50, which has merged.