phpCAS icon indicating copy to clipboard operation
phpCAS copied to clipboard

Prioritize HTTP-HOST header over SERVER-NAME when getting clientUrl (?)

Open Golho opened this issue 7 years ago • 3 comments

Hi!

I've tried setting up phpCAS to a Docker container with the romeoz/docker-nginx-php image hosting and serving the service. When trying the simple example from /docs, the redirect URL created by the CAS_Client class is faulty, causing me to be redirected to a 404 when I'd entered my credentials to the CAS server.

I should have been redirected to the HTTP-HOST, http://192.168.99.100:8080/docs/examples/example_simple.php?ticket=XXX (for me it is this as I run docker-machine and set up the docker container to port 8080), but the URL became http://app/docs/examples/example_simple.php?ticket=XXX.

After "debugging" I found out that the _getClientUrl-function gave me the wrong url. The client url is determined by this snippet (source/CAS/Client.php:3594):

if (empty($_SERVER['SERVER_NAME'])) {
  $server_url = $_SERVER['HTTP_HOST'];
} else {
  $server_url = $_SERVER['SERVER_NAME'];
}

Here the server name is prioritzed over the http host, but this resulted in the problem stated above. In my application the http host should be used instead, every time. Is there a reason for this logic or is this a simple mistake?

Golho avatar Jun 24 '17 23:06 Golho

Server_Name ist configured server side and host_name is client defined... This is one of the most important reasons for this priority. Since all webservers and proxies handle these variables a bit different it's hard to have one automatic solution for everyone.

You can always override the automatic url detection with your own code. Any such automatic configuration will only work in 95% of the setups out there. I suggest that you override the url generation with the available setter function. Please have a look at the code docs:

https://developer.jasig.org/cas-clients/php/current/docs/api/index.html

jfritschi avatar Jun 25 '17 15:06 jfritschi

Yes, the host_name is defined client side, and shouldn't the client url be the one entered by the user in the browser?

From https://apereo.github.io/cas/4.2.x/protocol/CAS-Protocol-Specification.html#211-parameters:

service [OPTIONAL] - the identifier of the application the client is trying to access. In almost all cases, this will be the URL of the application.

The URL the CAS server directs to (the service parameter) should be the same as the original one the user tried to enter before being redirected to the CAS server, am I right?

Golho avatar Jun 25 '17 16:06 Golho

It's not as simple as that. Yes it should be, but only in a very basic setup.

The service is a parameter is part of the authentication and is validated as the CAS server. So you have to be sure it "predictable" in the sense that only URLs that are configured in the CAS server as service are used. With http_host the service becomes very "variable" and as soon as you have any kind of catchall domains, or things like www.domain.com that are redirected to domain.com, multiple domains on one host things get really messy. This usually results in broken authentication.

Another reason is security: We try to use server side variable as much as possible. This is simply a precaution.

We know that our automagic configuration is not the best in all situations but it works in many cases. If not you can simply define it yourself: phpCAS::setFixedServiceURL()

jfritschi avatar Jun 25 '17 18:06 jfritschi