silexphp / Silex

[DEPRECATED -- Use Symfony instead] The PHP micro-framework based on the Symfony Components
https://silex.symfony.com
MIT License
3.58k stars 718 forks source link

Unauthorized access results in improper HTTP status message #496

Closed ramsey closed 11 years ago

ramsey commented 12 years ago

If authorization fails, according to the Silex SecurityProvider rules, then Symfony\Component\Security\Http\Firewall\AccessListener::handle throws a Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException with the message "A Token was not found in the SecurityContext." This message is improperly being set as the HTTP status message.

For example, In making this request of a resource requiring HTTP Basic Auth authorization:

GET /foo HTTP/1.1
Host: silextest:8888
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Accept-Encoding: identity, deflate, compress, gzip
Accept: */*
User-Agent: HTTPie/0.2.0

I receive this response:

HTTP/1.0 401 A Token was not found in the SecurityContext.
Date: Thu, 20 Sep 2012 19:43:58 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.3.10-1ubuntu3.4
cache-control: no-cache
www-authenticate: Basic realm="Foo Realm"
Vary: Accept-Encoding
Content-Encoding: gzip
Connection: close
Content-Type: text/html; charset=UTF-8

However, I expect to see this status message, instead:

HTTP/1.0 401 Unauthorized

Otherwise, the security rules apply properly if providing the correct Authorization header.

Here's a simple index.php script that reproduces this issue:

<?php

require_once __DIR__.'/../vendor/autoload.php';

$app = new Silex\Application();

$app->register(new \Silex\Provider\SecurityServiceProvider());

$app['security.firewalls'] = array(
    'secured' => array(
        'pattern' => '^/',
        'http' => array('real_name' => 'Foo Realm'),
        'users' => array(
            'admin' => array('ROLE_ADMIN', '5FZ2Z8QIkA7UTZ4BYkoC+GsReLf569mSKDsfods6LYQ8t+a8EW9oaircfMpmaLbPBh4FOBiiFyLfuZmTSUwzZg==',
        ),
    ),
);

$app['security.access_rules'] = array(
    array('^/foo', 'ROLE_ADMIN'),
);

$app->get('/foo', function() {
    return 'Hello, world!';
});

$app->run();
fabpot commented 11 years ago

fixed in Symfony.