feature #10404 [Security] Match request based on HTTP methods in firewall config (danez)

This PR was submitted for the 2.4 branch but it was merged into the 2.5-dev branch instead (closes #10404).

Discussion
----------

[Security] Match request based on HTTP methods in firewall config

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        | symfony/symfony-docs#3681

For an api I had to work on, I was in the need to have different firewalls for different HTTP Methods. I started building my own ```RequestMatcher``` until I discovered, that the regular RequestMatcher is able to handle HTTP Methods. The only thing that is missing is the possibility to configure it in the firewall section of the configuration. (For access_control it is already possible)

With this PR it is possible to do things like this:
```yaml
security:
    firewalls:
        api_options:
            pattern:    ^/
            methods:    [OPTIONS]
            security:   false
        api:
            pattern:    ^/
            some_auth:  true
```

I think this integrates quite nicely. Or is there any downside you can think of?

If it is good to go, I'll open a PR for the docs.

Commits
-------

2878757 Make it possible to match the request based on HTTP methods in the firewall configuration
This commit is contained in:
Fabien Potencier 2014-03-14 12:27:42 +01:00
commit 1e973b2a9a
6 changed files with 10 additions and 2 deletions

View File

@ -201,6 +201,10 @@ class MainConfiguration implements ConfigurationInterface
$firewallNodeBuilder
->scalarNode('pattern')->end()
->scalarNode('host')->end()
->arrayNode('methods')
->beforeNormalization()->ifString()->then(function ($v) { return preg_split('/\s*,\s*/', $v); })->end()
->prototype('scalar')->end()
->end()
->booleanNode('security')->defaultTrue()->end()
->scalarNode('request_matcher')->end()
->scalarNode('access_denied_url')->end()

View File

@ -254,7 +254,8 @@ class SecurityExtension extends Extension
} elseif (isset($firewall['pattern']) || isset($firewall['host'])) {
$pattern = isset($firewall['pattern']) ? $firewall['pattern'] : null;
$host = isset($firewall['host']) ? $firewall['host'] : null;
$matcher = $this->createRequestMatcher($container, $pattern, $host);
$methods = isset($firewall['methods']) ? $firewall['methods'] : array();
$matcher = $this->createRequestMatcher($container, $pattern, $host, $methods);
}
// Security disabled?

View File

@ -117,6 +117,7 @@ abstract class CompleteConfigurationTest extends \PHPUnit_Framework_TestCase
array(
'/test',
'foo\\.example\\.org',
array('GET', 'POST'),
),
), $matchers);
}

View File

@ -74,6 +74,7 @@ $container->loadFromExtension('security', array(
'host' => array(
'pattern' => '/test',
'host' => 'foo\\.example\\.org',
'methods' => array('GET', 'POST'),
'anonymous' => true,
'http_basic' => true,
),

View File

@ -57,7 +57,7 @@
<logout />
</firewall>
<firewall name="host" pattern="/test" host="foo\.example\.org">
<firewall name="host" pattern="/test" host="foo\.example\.org" methods="GET,POST">
<anonymous />
<http-basic />
</firewall>

View File

@ -56,6 +56,7 @@ security:
host:
pattern: /test
host: foo\.example\.org
methods: [GET,POST]
anonymous: true
http_basic: true