Browse Source

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 năm trước cách đây
mục cha
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', ''));
     }
 
     /**