Intended behavior of saml:SP authentication source config options like ForceAuthn when operating an IdP Proxy

500 views
Skip to first unread message

Mike Grady

unread,
Apr 7, 2015, 3:24:02 PM4/7/15
to simple...@googlegroups.com
The documentation at:


indicates that specifying ForceAuthn, isPassive, saml:AuthnContextClassRef, etc. at "runtime" should override other configuration. But it is not entirely clear what the behavior is intended to be if one configures a saml:SP authentication source with 'ForceAuthn' => TRUE, but the external SP sending the request, and the IdP (Proxy) itself has not specified ForceAuthn. I'd argue that the saml:SP authentication source config should override, but that does not appear to be the current behavior. I think that line 200 of:


should be:

  if (isset($state['ForceAuthn']) && (bool)$state['ForceAuthn']) {

instead of:

  if (isset($state['ForceAuthn'])) {

and that the same should be true for isPassive. Any attempt to set one of those explicitly to TRUE should take precedence to defaulting to FALSE. Of course, tt gets more complicated to decide for saml:AuthnContextClassRef and saml:NameIDPolicy what to do, and knowing when it got set explicitly versus by default.

So is the current behavior actually intended?

Jaime Perez Crespo

unread,
Apr 10, 2015, 11:02:54 AM4/10/15
to simple...@googlegroups.com
Hi Mike,

> On 07 Apr 2015, at 21:24 pm, Mike Grady <mapg...@gmail.com> wrote:
> The documentation at:
>
> https://simplesamlphp.org/docs/stable/saml:sp
>
> indicates that specifying ForceAuthn, isPassive, saml:AuthnContextClassRef, etc. at "runtime" should override other configuration. But it is not entirely clear what the behavior is intended to be if one configures a saml:SP authentication source with 'ForceAuthn' => TRUE, but the external SP sending the request, and the IdP (Proxy) itself has not specified ForceAuthn.

Well, that’s also “runtime”, right?

> I'd argue that the saml:SP authentication source config should override, but that does not appear to be the current behavior.
[…]
> Any attempt to set one of those explicitly to TRUE should take precedence to defaulting to FALSE. Of course, tt gets more complicated to decide for saml:AuthnContextClassRef and saml:NameIDPolicy what to do, and knowing when it got set explicitly versus by default.

Yes, I see your point.

> So is the current behavior actually intended?

I can’t tell, but I don’t think so. I guess the explanation here is also the simplest: proxy mode is not officially supported by SimpleSAMLphp. Due to that, nobody took the work to check this before, nor to make sure that configuration parameters prevail in the way you are describing.

The problem is this is quite complicated, so it’s hard to make decisions. To me, it makes sense that the behaviour as a proxy should be: if either the SP asking you for authentication, or you by configuration, want to force authentication, then authentication should be forced. So, we would have this different combinations for ForceAuthn:

SP / Proxy config / SAML request to the IdP
<not specified> / <not specified> / <not specified>
<not specified> / true / true
<not specified> / false / <not specified>
true / <not specified> / true
false / <not specified> / <not specified>
true / true / true
true / false / true

Similar thing for IsPassive. If either the SP or the proxy want to run a passive authentication, then the SAML request sent to the IdP should have IsPassive set to true.

AuthnContextClassRef and NameIDPolicy are way more complicated. The authentication context should be parsed by the proxy, I think, to see how to meet the required class. It might be possible that you want to use one authentication source or another depending on this. However, SSP does not support this, so I guess the best approach would be to use what the SP asks for. I don’t think it makes much sense to force to use a different authentication context, since that would probably lead to the SP not authorizing the user.

As for the nameID policy, I think we should have the same approach, that meaning using whatever we get from the SP. In the end, it’s not the proxy the one consuming the NameID, so unless the proxy is doing something fancier (like adding more attributes for the user or some other “improvement” over the authentication process), it should be up to the SP.

In both last cases, we should use the values configured in the proxy if *nothing* arrives in the request received from the SP, of course. But as soon as we get something from the SP, then we should use that.

What do you think? Is this a sound behaviour? Would you be happy to provide a pull request?

--
Jaime Pérez
UNINETT / Feide
mail: jaime...@uninett.no
xmpp: ja...@jabber.uninett.no

"Two roads diverged in a wood, and I, I took the one less traveled by, and that has made all the difference."
- Robert Frost

signature.asc

Mike Grady

unread,
Apr 11, 2015, 2:49:41 PM4/11/15
to simple...@googlegroups.com

> So is the current behavior actually intended?

I can’t tell, but I don’t think so. I guess the explanation here is also the simplest: proxy mode is not officially supported by SimpleSAMLphp. Due to that, nobody took the work to check this before, nor to make sure that configuration parameters prevail in the way you are describing.

That's interesting, because I'd always assumed that was actually a prime use case that SSP was designed for. Certainly has done a great job of supporting all the SAML standards around being used in such a way. ;-)  Even though I had to disable SSP, being used as an IdP Proxy, from sending the Scoping element to proxied IdPs, because one of them is ADFS, and that out and out rejects any Authn Request with the Scoping element. (If you are interested, I could look into making that change a configurable one by SP authn source, and put in a pull request for that. For the particular service that is for, it was just simpler to disable that Scoping element all together, because none of the proxied IdPs do anything with it today anyways.) On the other hand, the fact that it exposes the Scoping element when received in an Authn Request from another IdP is quite useful, because it lets us know the originating SP, so we could label things appropriately. Because we have a use case where another Proxy is between the originating SP and our Proxy:

   External SP -> External Proxy -> Our IdP Proxy -> User/home IdP
 

The problem is this is quite complicated, so it’s hard to make decisions. To me, it makes sense that the behaviour as a proxy should be: if either the SP asking you for authentication, or you by configuration, want to force authentication, then authentication should be forced. So, we would have this different combinations for ForceAuthn:

SP / Proxy config / SAML request to the IdP
<not specified> / <not specified> / <not specified>
<not specified> / true / true
<not specified> / false / <not specified>
true / <not specified> / true
false / <not specified> / <not specified>
true / true / true
true / false / true

Similar thing for IsPassive. If either the SP or the proxy want to run a passive authentication, then the SAML request sent to the IdP should have IsPassive set to true.

AuthnContextClassRef and NameIDPolicy are way more complicated. The authentication context should be parsed by the proxy, I think, to see how to meet the required class. It might be possible that you want to use one authentication source or another depending on this. However, SSP does not support this, so I guess the best approach would be to use what the SP asks for. I don’t think it makes much sense to force to use a different authentication context, since that would probably lead to the SP not authorizing the user.

As for the nameID policy, I think we should have the same approach, that meaning using whatever we get from the SP. In the end, it’s not the proxy the one consuming the NameID, so unless the proxy is doing something fancier (like adding more attributes for the user or some other “improvement” over the authentication process), it should be up to the SP.

In both last cases, we should use the values configured in the proxy if *nothing* arrives in the request received from the SP, of course. But as soon as we get something from the SP, then we should use that.

What do you think? Is this a sound behaviour? Would you be happy to provide a pull request?


I'd hope that the admin knows what they are doing when/if they configure SP authentication sources. So, yes, I agree that if anything in the "chain" from:

  external/originating SP ->  IdP Proxy -> AuthnSource SP -> "home" IdP

sets either ForceAuthn or isPassive to TRUE, then that is what should be sent/set in the Authn Request sent to the "home" IdP. I.e TRUE should be "sticky" and trump any FALSE. And that is a simple change, as we made the change in the code I suggested in my original note in this thread, and that indeed does such for ForceAuthn, I just need to do the same thing for isPassive, and submit a pull request for that.

However, I'd also likely argue that the same thing should be true for AuthnContextClassRef and NameIDPolicy. Presumably, the SSP admin knows what they are doing if they decide to give those explicit values in the config for an Authn Source SP. I can think of several possible use cases, within the realm of IdP Proxy usage, for such:

 - external SP sends something that is considered equivalent to what the proxied IdPs do, but the proxied IdPs use a different value. Yes, you could try to get all the proxied IdPs to add this new value as equivalent, or you could just take care of it in the Proxy.

 - similarly, there are folks adding in 2/Multifactor Authn as an authn processing filter in SSP. The proxied IdP just does username/password/whatever, and then the Proxy additionally chooses to have them do an additional 'different factor" authentication at the proxy. In that case, if the originating SP requested a 2/Multifactor authn context, you would want to override that and *not* send that authn context thru to the proxied IdPs.

Of course, you'd then need authn filters to manipulate and check what happened with these authn contexts (like there already is the saml:ExpectedAuthnContextClassRef filter).

And you could make the same sort of argument around NameIDPolicy.

So I do think that ultimately that SSP should take an explicit setting for AuthnContextClassRef  and/or NameiDPolicy from a saml:SP authn source and use that in the Authn Request sent to a proxied IdP. But then clearly document that it is up to the person configuring that to then ensure there is authn filter logic to ensure that ultimately the appropriate things were done to meet the requested requirements of the originating SP's Authn Request, and if so, return the originally requested values for AuthnContextClassRef  and NameiDPolicy.

What od you think?

p.s. Now, even though that is how I'd think it should work, I don't yet have a pressing need for that behavior around those two options, so I'm not as motivated (yet) to propose code changes to "make it so".

Jaime Perez Crespo

unread,
Apr 13, 2015, 5:55:57 AM4/13/15
to simple...@googlegroups.com
Hi Mike,

> On 11 Apr 2015, at 20:49 pm, Mike Grady <mapg...@gmail.com> wrote:
> That's interesting, because I'd always assumed that was actually a prime use case that SSP was designed for. Certainly has done a great job of supporting all the SAML standards around being used in such a way. ;-)

I guess that was user-driven. Even though we don’t support proxy mode, there’s plenty of people using it that way, just because it is easy and convenient. I’ve used it like that myself. However, that’s also the reason why some simple things do not work when SSP acts as a proxy, such as this or SLO, for instance. Logout messages are correctly propagated upstream, just because when you receive a logout request, you know you need to logout from the authentication source you used too, and if that’s a SAML SP, then you will also initiate logout towards the IdP. On the other hand, if you get a logout request from an IdP, you really need to be conscious of your condition as a proxy to propagate logout downstream. But SSP is not, it will only see itself as an SP, so logout will end in there and any other SP connected to the proxy will keep their sessions.

> Even though I had to disable SSP, being used as an IdP Proxy, from sending the Scoping element to proxied IdPs, because one of them is ADFS, and that out and out rejects any Authn Request with the Scoping element.

That’s interesting. Never heard of that issue before.

> (If you are interested, I could look into making that change a configurable one by SP authn source, and put in a pull request for that. For the particular service that is for, it was just simpler to disable that Scoping element all together, because none of the proxied IdPs do anything with it today anyways.) On the other hand, the fact that it exposes the Scoping element when received in an Authn Request from another IdP is quite useful, because it lets us know the originating SP, so we could label things appropriately. Because we have a use case where another Proxy is between the originating SP and our Proxy:
>
> External SP -> External Proxy -> Our IdP Proxy -> User/home IdP

Since we were unaware of this, it’s really up to you. If at some point you need to fix it and you submit a pull request, we’ll be glad to merge it.

> I'd hope that the admin knows what they are doing when/if they configure SP authentication sources.

But if we want them to know what they are doing, we should probably have some documentation explaining how things work and why they work like that, which we haven’t today, since we don’t support proxy mode. So now there’s room for plenty of mistakes, I think.

> So, yes, I agree that if anything in the "chain" from:
>
> external/originating SP -> IdP Proxy -> AuthnSource SP -> "home” IdP
>
> sets either ForceAuthn or isPassive to TRUE, then that is what should be sent/set in the Authn Request sent to the "home" IdP. I.e TRUE should be "sticky" and trump any FALSE. And that is a simple change, as we made the change in the code I suggested in my original note in this thread, and that indeed does such for ForceAuthn, I just need to do the same thing for isPassive, and submit a pull request for that.

Good, thanks!

> However, I'd also likely argue that the same thing should be true for AuthnContextClassRef and NameIDPolicy. Presumably, the SSP admin knows what they are doing if they decide to give those explicit values in the config for an Authn Source SP. I can think of several possible use cases, within the realm of IdP Proxy usage, for such:
>
> - external SP sends something that is considered equivalent to what the proxied IdPs do, but the proxied IdPs use a different value. Yes, you could try to get all the proxied IdPs to add this new value as equivalent, or you could just take care of it in the Proxy.
>
> - similarly, there are folks adding in 2/Multifactor Authn as an authn processing filter in SSP. The proxied IdP just does username/password/whatever, and then the Proxy additionally chooses to have them do an additional 'different factor" authentication at the proxy. In that case, if the originating SP requested a 2/Multifactor authn context, you would want to override that and *not* send that authn context thru to the proxied IdPs.
>
> Of course, you'd then need authn filters to manipulate and check what happened with these authn contexts (like there already is the saml:ExpectedAuthnContextClassRef filter).
>
> And you could make the same sort of argument around NameIDPolicy.
>
> So I do think that ultimately that SSP should take an explicit setting for AuthnContextClassRef and/or NameiDPolicy from a saml:SP authn source and use that in the Authn Request sent to a proxied IdP. But then clearly document that it is up to the person configuring that to then ensure there is authn filter logic to ensure that ultimately the appropriate things were done to meet the requested requirements of the originating SP's Authn Request, and if so, return the originally requested values for AuthnContextClassRef and NameiDPolicy.
>
> What od you think?

I totally agree with you. However, I think we need some infrastructure in place for that to be possible, so that’s why I was suggesting to simply pass through the values we get from the end service provider. In other words, I see two options:

- either we support this officially, add the configuration options and stuff necessary to properly configure AuthnContextClassRefs and NameIDPolicies, their mappings, equivalences, filters and so on, or
- we do not support it, in which case we should just bypass whatever the SP is asking for.

> p.s. Now, even though that is how I'd think it should work, I don't yet have a pressing need for that behavior around those two options, so I'm not as motivated (yet) to propose code changes to "make it so”.

I would really like to see some more flexibility and options in SSP regarding, at least, AuthnContextClassRefs. I think it makes sense to associate different classes with different auth sources, for example, and dynamically decide which auth source to use depending on the context class we are required. However, just like you, I have very little need for it right now, so I guess we’ll stay as we are for a while :-)
signature.asc

Steve Bagwell

unread,
Oct 19, 2015, 8:50:17 AM10/19/15
to SimpleSAMLphp
@Mike Grady,

We would like to see how you disabled the scoping element, if that's possible.

Thanks,

Steve

Michael A Grady

unread,
Oct 19, 2015, 9:49:45 AM10/19/15
to simple...@googlegroups.com
I removed it in the simplest way possible, by simply keeping it from being added to the XML message being constructed. I didn't try to disable any of the "construction" of the elements that would have gone into that element -- one could save some "unnecessary work" by doing so, but I didn't want to analyze whether there might be other ramifications to that. Partially because, at some point, I thought I would go back and make whether the Scoping element was added to the Authn Request be conditional, probably by adding another config attribute to a saml:SP authsources entry to indicate whether to add it or not. But I have yet to get around to that. Right now, it's just "disabled" completely, I never send the scoping element thru. In our use case that is fine, because I know all the IdPs on the other side are not proxies, and I know that even if they were, we don't care how many more "hops" it would take.

My change is as simple as commenting out a single line, in the file:

SSPROOT/vendor/simplesamlphp/saml2/src/SAML2/AuthnRequest.php

line 522:

//$root->appendChild($scoping);

That's within the function:

/**
* Convert this authentication request to an XML element.
*
* @return DOMElement This authentication request.
*/
public function toUnsignedXML()


I haven't checked to see if that if that file has changed at all from the version I have, which is why I didn't just give you a DIFF.

> On Oct 19, 2015, at 7:50 AM, Steve Bagwell <steve_...@sil.org> wrote:
>
> @Mike Grady,
>
> We would like to see how you disabled the scoping element, if that's possible.
>
> Thanks,
>
> Steve
>


--
Michael A Grady
mapg...@gmail.com



Steve Bagwell

unread,
Oct 19, 2015, 11:45:08 AM10/19/15
to SimpleSAMLphp
Great! Thanks!


On Tuesday, April 7, 2015 at 3:24:02 PM UTC-4, Mike Grady wrote:

Tim van Dijen

unread,
Oct 21, 2015, 4:51:00 PM10/21/15
to SimpleSAMLphp
I'm really surprised to hear proxy-mode is not officially supported too... Is this something that can change in the near future?

Peter Schober

unread,
Oct 22, 2015, 3:04:41 AM10/22/15
to SimpleSAMLphp
* Tim van Dijen <tvd...@gmail.com> [2015-10-21 22:51]:
> I'm really surprised to hear proxy-mode is not officially supported too...
> Is this something that can change in the near future?

If support for the missing pieces is contributed in the near future
the chances for that are very high. (Hint hint)
Otherwise probably not.
-peter

Tim van Dijen

unread,
Oct 22, 2015, 11:20:55 AM10/22/15
to SimpleSAMLphp, peter....@univie.ac.at
Hehe, hint noted...
I don't think I'm up for that challenge though.. I would have to learn/know more about SSP.

Op donderdag 22 oktober 2015 09:04:41 UTC+2 schreef Peter Schober:

Jaime Perez Crespo

unread,
Oct 23, 2015, 4:11:40 AM10/23/15
to simple...@googlegroups.com
Hi,

Peter is absolutely right. We would love to claim support for proxy mode in SimpleSAMLphp, but unfortunately we cannot do that until we have SLO propagated properly from the IdP down to the SPs through the proxy. That needs some work that we don’t have the resources necessary to accomplish, so any contributions are more than welcome. If anyone’s interested, please take a look at this:

https://github.com/simplesamlphp/simplesamlphp/issues/65
Reply all
Reply to author
Forward
0 new messages