Force MFA for SP requesting PasswordProtectedTransport
Cantor, Scott
cantor.2 at osu.edu
Wed Oct 25 19:26:28 UTC 2023
> I have asked the client to have the SP remove the AuthnContextClass, but
> they are hesitant to change anything on the SP side since they are close to
> go live.
The simplest answer is that you don't take no for an answer. Otherwise your configuration will be much more complex and you're accepting a pile of technical debt in exchange for being nice to them. That's why I'm not nice. Having said that...
> Regardless, I would like to prevent service providers from being able to
> bypass MFA by specifying an AuthnContextClass.
The direct way to do that is to block them from requesting it, ultimately, everything else is a workaround that's very hard to keep working long term because it requires a lot of ongoing testing and care every time you adjust anything in the MFA layer.
Since Vermont just joined the consortium (thank you), I will dive in more deeply than I otherwise would, because you're not set up for our support site yet.
Basically, the main thing you have to do first is adjust the MFA scripting so that instead of relying solely on the isAcceptable() test in the examples we show, you have to code more explicit logic that may have to take other factors into account.
Possibly you could just add specific checks for the relying party, or stick all the broken SPs into an override and check for that RelyingPartyConfiguration ID at runtime, or some other signal. It really depends on how often you expect to deal with the problem, but I can tell you that it's not rare.
The reason that isn't all you have to do is SSO. When the system runs the way it's meant to, the Subject produced by a previous non-MFA authentication will carry the Password Principals, and so the system getting a request for that context from an SP will automatically check for that and say "this is fine" and respond, thus no MFA.
You have to short-circuit that, forcing the IdP to re-run the MFA logic, by setting the reuseCondition on the MFA flow to shibboleth.Conditions.FALSE (i.e. don't ever reuse it).
At that point, the MFA flow will always run, but when your scripting runs, say, the Password flow, that will generally just reuse the embedded result of running that flow from before, and same for other methods. So while the logic runs, the user doesn't generally get bothered by it, and things mostly look the way you want them to look.
You can get more exotic by using a reuseCondition that's more fine-grained than "false", similarly checking for specific RPs, or possibly even diving into the context tree and evaluating whether the SP specifically did the dumb thing of demanding PasswordProtectedTransport.
That's all pretty high level. Actually scripting it all up is a fair bit of work and testing. That's why I don't do this specific form of workaround (I have plenty of others I have to deal with already). It's not my job to cover for bugs. It's my job to point them out. Bugs should be fixed, not worked around. And the only way you achieve that is by being deeply unpopular and calling people out when they try and punt the work to you. It is not something many people find natural, I guess I'm lucky in that regard.
-- Scott
More information about the users
mailing list