1

I'm attempting to upgrade dependancies on a simple Laravel 5.7 application that authenticates the user via SimpleSAMLphp, then displays some information it gets from an external API.

It looks like something changed between version 4.3.8 and version 4.4.0 of the symfony/http-foundation library included with Laravel, because when I upgrade this dependency I get the following error:

ErrorException (E_NOTICE): Undefined offset: 0 …/vendor/symfony/http-foundation/HeaderBag.php 126

It looks like this is being triggered by requiring the SimpleSAMLphp service provider autoload file, even if I don't call any methods.

Since this is an extremely simple single page application, I'm just using middleware to handle the SimpleSAMLphp integration:

namespace App\Http\Middleware;

use Closure;

class SimpleSAMLphp
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {

        /**
         * Load SimpleSAMLphp library
         */
        require_once('redacted/path/simplesaml/lib/_autoload.php');
        $ssphp = new \SimpleSAML\Auth\Simple('service-provider-name');
        $ssphp->requireAuth();

        return $next($request);
    }
}

It looks like Symfony HTTP Foundation changed how they are checking for header information in this version (I see extensive changes here: https://github.com/symfony/http-foundation/compare/v4.3.8...v4.4.0), but I don't understand why it is blowing up when SimpleSAMLphp is in the mix.

I'm deep down the rabbit hole on this one - any guidance would be much appreciated!

Taija
  • 11
  • 4

2 Answers2

0

Duplicate the HeaderBag.php file and override it using composer. Change the get function of the duplicated file to the code below. The only changes here is the isset checker. Then http://shyammakwana.me/php/laravel-override-vendor-classes.html will show you how to override the Headerbag.php file of any vendor using composer. Tested working with SimpleSamlPHP and Laravel. Enjoy!

public function get($key, $default = null)
{
    $headers = $this->all((string) $key);
    if (2 < \func_num_args()) {
        @trigger_error(sprintf('Passing a third argument to "%s()" is deprecated since Symfony 4.4, use method "all()" instead', __METHOD__), E_USER_DEPRECATED);

        if (!func_get_arg(2)) {
            return $headers;
        }
    }

    if (!$headers || !isset($headers[0])) {
        return $default;
    }

    if (null === $headers[0]) {
        return null;
    }

    return (string) $headers[0];
}
chicha
  • 11
0

I'm getting the same issue with Laravel 5.8 and a SimpleSAMLPhp installation.

Only had a quick poke around for now, but it seems that the HeaderBag.php is called at least twice during a request. There is one particular call (where the error occurs) where it is trying to resolve a key of "Content-Type", which exists in $header as "content-type" (lowercase) but cannot be resolved due to the case difference. It has a set of other attributes such as "Cache-Control" as well in the $header. If it manages to "get" the "content-type" attribute, then header correctly has a [0] offset property attainable.

I'm just trying a clean 5.8 install without my saml auth libraries to see if its doing the same thing. But I think you're right that its something to do with the authentication/redirect back from SAML which is causing the issue.

Will report back if I find anything useful.

  • Seems to be where the include _autoload.php call is made that causes the issue. If you move just that part to somewhere a lot earlier, such as /public/index.php as a bad example ... then it works fine. Still digging - but my hunch at the moment is that the call order needs modifying somewhere. – Frank Gasking Feb 20 '20 at 12:40
  • Right, there seem to be two issues. Laravel 5.8 is fixed onto 4.2 of symfony/http-foundation (Laravel 6.2 is fixed onto 4.4.4). Firstly, for some reason (I guess a bug), for the "get" function, the parameter part has been commented out: `public function all(/*string $key = null*/)` This has been re-instated in the latest build of symfony/http-foundation. This means that the return of "get" will always be an empty array. This then further highlights the issue that "get" will error straight away with the offset error, because of the empty array. – Frank Gasking Feb 20 '20 at 15:08
  • 1
    Even if you use the latest version of HeaderBag.php, then the offset error will occur at somepoint, as the "all" function has been programmed to return an empty array as a last resort. Conclusion - Symfony devs need to add an isset() check to the "get" function to remove the offset issue. Laravel then need to use that fixed version, including the commented in parameters. For now, chicha's suggestion is a temporary work around until its fixed centrally. – Frank Gasking Feb 20 '20 at 15:08