Forráskód Böngészése

Merge remote branch 'schmittjoh/security'

* schmittjoh/security:
  [Security] forward the entire access denied exception instead of only the message
  [Security] changed defaults for MessageDigestEncoder
  TICKET #9557: session isn't required when using http basic authentification mecanism for example
  [Security] improved entropy to make collision attacks harder
  [Security] added the 'key' attribute of RememberMeToken to serialized string to be stored in session
  Fix the Acl schema generator script.
Fabien Potencier 14 éve
szülő
commit
1e996901f5

+ 3 - 3
src/Symfony/Bundle/SecurityBundle/DependencyInjection/Configuration.php

@@ -237,9 +237,9 @@ class Configuration
                     ->performNoDeepMerging()
                     ->beforeNormalization()->ifString()->then(function($v) { return array('algorithm' => $v); })->end()
                     ->scalarNode('algorithm')->cannotBeEmpty()->end()
-                    ->booleanNode('ignore_case')->end()
-                    ->booleanNode('encode_as_base64')->end()
-                    ->scalarNode('iterations')->end()
+                    ->booleanNode('ignore_case')->defaultFalse()->end()
+                    ->booleanNode('encode_as_base64')->defaultTrue()->end()
+                    ->scalarNode('iterations')->defaultValue(5000)->end()
                     ->scalarNode('id')->end()
                 ->end()
             ->end()

+ 6 - 19
src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php

@@ -381,11 +381,7 @@ class SecurityExtension extends Extension
 
         // plaintext encoder
         if ('plaintext' === $config['algorithm']) {
-            $arguments = array();
-
-            if (isset($config['ignore_case'])) {
-                $arguments[0] = $config['ignore_case'];
-            }
+            $arguments = array($config['ignore_case']);
 
             return array(
                 'class' => new Parameter('security.encoder.plain.class'),
@@ -394,20 +390,11 @@ class SecurityExtension extends Extension
         }
 
         // message digest encoder
-        $arguments = array($config['algorithm']);
-
-        // add optional arguments
-        if (isset($config['encode_as_base64'])) {
-            $arguments[1] = $config['encode_as_base64'];
-        } else {
-            $arguments[1] = false;
-        }
-
-        if (isset($config['iterations'])) {
-            $arguments[2] = $config['iterations'];
-        } else {
-            $arguments[2] = 1;
-        }
+        $arguments = array(
+            $config['algorithm'],
+            $config['encode_as_base64'],
+            $config['iterations'],
+        );
 
         return array(
             'class' => new Parameter('security.encoder.digest.class'),

+ 1 - 1
src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/container1.php

@@ -5,7 +5,7 @@ $container->loadFromExtension('security', array(
         'JMS\FooBundle\Entity\User1' => 'plaintext',
         'JMS\FooBundle\Entity\User2' => array(
             'algorithm' => 'sha1',
-            'encode_as_base64' => true,
+            'encode_as_base64' => false,
             'iterations' => 5,
         ),
         'JMS\FooBundle\Entity\User3' => array(

+ 1 - 1
src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/container1.xml

@@ -8,7 +8,7 @@
     <config>
         <encoder class="JMS\FooBundle\Entity\User1" algorithm="plaintext" />
 
-        <encoder class="JMS\FooBundle\Entity\User2" algorithm="sha1" encode-as-base64="true" iterations="5" />
+        <encoder class="JMS\FooBundle\Entity\User2" algorithm="sha1" encode-as-base64="false" iterations="5" />
 
         <encoder class="JMS\FooBundle\Entity\User3" algorithm="md5" />
 

+ 1 - 1
src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/container1.yml

@@ -3,7 +3,7 @@ security:
         JMS\FooBundle\Entity\User1: plaintext
         JMS\FooBundle\Entity\User2:
             algorithm: sha1
-            encode_as_base64: true
+            encode_as_base64: false
             iterations: 5
         JMS\FooBundle\Entity\User3:
             algorithm: md5

+ 3 - 3
src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php

@@ -136,15 +136,15 @@ abstract class SecurityExtensionTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals(array(array(
             'JMS\FooBundle\Entity\User1' => array(
                 'class' => new Parameter('security.encoder.plain.class'),
-                'arguments' => array(),
+                'arguments' => array(false),
             ),
             'JMS\FooBundle\Entity\User2' => array(
                 'class' => new Parameter('security.encoder.digest.class'),
-                'arguments' => array('sha1', true, 5),
+                'arguments' => array('sha1', false, 5),
             ),
             'JMS\FooBundle\Entity\User3' => array(
                 'class' => new Parameter('security.encoder.digest.class'),
-                'arguments' => array('md5', false, 1),
+                'arguments' => array('md5', true, 5000),
             ),
             'JMS\FooBundle\Entity\User4' => new Reference('security.encoder.foo'),
         )), $container->getDefinition('security.encoder_factory.generic')->getArguments());

+ 1 - 1
src/Symfony/Component/Security/Acl/Resources/bin/generateSql.php

@@ -27,7 +27,7 @@ $schema = new Schema(array(
 
 $reflection = new ReflectionClass('Doctrine\\DBAL\\Platforms\\AbstractPlatform');
 $finder = new Finder();
-$finder->name('*.php')->in(dirname($reflection->getFileName()));
+$finder->name('*Platform.php')->in(dirname($reflection->getFileName()));
 foreach ($finder as $file) {
     require_once $file->getPathName();
     $className = 'Doctrine\\DBAL\\Platforms\\' . $file->getBasename('.php');

+ 17 - 0
src/Symfony/Component/Security/Core/Authentication/Token/RememberMeToken.php

@@ -66,4 +66,21 @@ class RememberMeToken extends Token
     {
         $this->persistentToken = $persistentToken;
     }
+
+
+    /**
+     * {@inheritdoc}
+     */
+    public function serialize()
+    {
+        return serialize(array($this->user, $this->credentials, $this->authenticated, $this->roles, $this->immutable, $this->providerKey, $this->attributes, $this->key));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function unserialize($serialized)
+    {
+        list($this->user, $this->credentials, $this->authenticated, $this->roles, $this->immutable, $this->providerKey, $this->attributes, $this->key) = unserialize($serialized);
+    }
 }

+ 2 - 2
src/Symfony/Component/Security/Core/Encoder/MessageDigestPasswordEncoder.php

@@ -28,7 +28,7 @@ class MessageDigestPasswordEncoder extends BasePasswordEncoder
      * @param Boolean $encodeHashAsBase64 Whether to base64 encode the password hash
      * @param integer $iterations         The number of iterations to use to stretch the password hash
      */
-    public function __construct($algorithm = 'sha256', $encodeHashAsBase64 = false, $iterations = 1)
+    public function __construct($algorithm = 'sha512', $encodeHashAsBase64 = true, $iterations = 5000)
     {
         $this->algorithm = $algorithm;
         $this->encodeHashAsBase64 = $encodeHashAsBase64;
@@ -49,7 +49,7 @@ class MessageDigestPasswordEncoder extends BasePasswordEncoder
 
         // "stretch" hash
         for ($i = 1; $i < $this->iterations; $i++) {
-            $digest = hash($this->algorithm, $digest, true);
+            $digest = hash($this->algorithm, $digest.$salted, true);
         }
 
         return $this->encodeHashAsBase64 ? base64_encode($digest) : bin2hex($digest);

+ 5 - 2
src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php

@@ -124,7 +124,7 @@ class ExceptionListener implements ListenerInterface
                         }
 
                         $subRequest = Request::create($this->errorPage);
-                        $subRequest->attributes->set(SecurityContextInterface::ACCESS_DENIED_ERROR, $exception->getMessage());
+                        $subRequest->attributes->set(SecurityContextInterface::ACCESS_DENIED_ERROR, $exception);
 
                         $response = $event->getSubject()->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true);
                         $response->setStatusCode(403);
@@ -160,7 +160,10 @@ class ExceptionListener implements ListenerInterface
             $this->logger->debug('Calling Authentication entry point');
         }
 
-        $request->getSession()->set('_security.target_path', $request->getUri());
+        // session isn't required when using http basic authentification mecanism for example
+        if ($request->hasSession()) {
+            $request->getSession()->set('_security.target_path', $request->getUri());
+        }
 
         return $this->authenticationEntryPoint->start($event, $request, $authException);
     }

+ 4 - 4
tests/Symfony/Tests/Component/Security/Core/Encoder/MessageDigestPasswordEncoderTest.php

@@ -17,21 +17,21 @@ class MessageDigestPasswordEncoderTest extends \PHPUnit_Framework_TestCase
 {
     public function testIsPasswordValid()
     {
-        $encoder = new MessageDigestPasswordEncoder();
+        $encoder = new MessageDigestPasswordEncoder('sha256', false, 1);
 
         $this->assertTrue($encoder->isPasswordValid(hash('sha256', 'password'), 'password', ''));
     }
 
     public function testEncodePassword()
     {
-        $encoder = new MessageDigestPasswordEncoder();
+        $encoder = new MessageDigestPasswordEncoder('sha256', false, 1);
         $this->assertSame(hash('sha256', 'password'), $encoder->encodePassword('password', ''));
 
-        $encoder = new MessageDigestPasswordEncoder('sha256', true);
+        $encoder = new MessageDigestPasswordEncoder('sha256', true, 1);
         $this->assertSame(base64_encode(hash('sha256', 'password', true)), $encoder->encodePassword('password', ''));
 
         $encoder = new MessageDigestPasswordEncoder('sha256', false, 2);
-        $this->assertSame(hash('sha256', hash('sha256', 'password', true)), $encoder->encodePassword('password', ''));
+        $this->assertSame(hash('sha256', hash('sha256', 'password', true).'password'), $encoder->encodePassword('password', ''));
     }
 
     /**