diff --git a/UPGRADE-4.3.md b/UPGRADE-4.3.md
index bee2a00302..5f3bd82dcb 100644
--- a/UPGRADE-4.3.md
+++ b/UPGRADE-4.3.md
@@ -45,6 +45,41 @@ HttpFoundation
* The `FileinfoMimeTypeGuesser` class has been deprecated,
use `Symfony\Component\Mime\FileinfoMimeTypeGuesser` instead.
+Security
+--------
+
+ * The `AbstractToken::serialize()`, `AbstractToken::unserialize()`,
+ `AuthenticationException::serialize()` and `AuthenticationException::unserialize()`
+ methods are now final, use `getState()` and `setState()` instead.
+
+ Before:
+ ```php
+ public function serialize()
+ {
+ return [$this->myLocalVar, parent::serialize()];
+ }
+
+ public function unserialize($serialized)
+ {
+ [$this->myLocalVar, $parentSerialized] = unserialize($serialized);
+ parent::unserialize($parentSerialized);
+ }
+ ```
+
+ After:
+ ```php
+ protected function getState(): array
+ {
+ return [$this->myLocalVar, parent::getState()];
+ }
+
+ protected function setState(array $data)
+ {
+ [$this->myLocalVar, $parentData] = $data;
+ parent::setState($parentData);
+ }
+ ```
+
Yaml
----
diff --git a/UPGRADE-5.0.md b/UPGRADE-5.0.md
index d11420af46..58bb2035bc 100644
--- a/UPGRADE-5.0.md
+++ b/UPGRADE-5.0.md
@@ -232,6 +232,37 @@ Security
* `SimpleAuthenticatorInterface`, `SimpleFormAuthenticatorInterface`, `SimplePreAuthenticatorInterface`,
`SimpleAuthenticationProvider`, `SimpleAuthenticationHandler`, `SimpleFormAuthenticationListener` and
`SimplePreAuthenticationListener` have been removed. Use Guard instead.
+ * `\Serializable` interface has been removed from `AbstractToken` and `AuthenticationException`,
+ thus `serialize()` and `unserialize()` aren't available.
+ Use `getState()` and `setState()` instead.
+
+ Before:
+ ```php
+ public function serialize()
+ {
+ return [$this->myLocalVar, parent::serialize()];
+ }
+
+ public function unserialize($serialized)
+ {
+ [$this->myLocalVar, $parentSerialized] = unserialize($serialized);
+ parent::unserialize($parentSerialized);
+ }
+ ```
+
+ After:
+ ```php
+ protected function getState(): array
+ {
+ return [$this->myLocalVar, parent::getState()];
+ }
+
+ protected function setState(array $data)
+ {
+ [$this->myLocalVar, $parentData] = $data;
+ parent::setState($parentData);
+ }
+ ```
SecurityBundle
--------------
diff --git a/src/Symfony/Component/Security/CHANGELOG.md b/src/Symfony/Component/Security/CHANGELOG.md
index ac3024c481..23d3ea43be 100644
--- a/src/Symfony/Component/Security/CHANGELOG.md
+++ b/src/Symfony/Component/Security/CHANGELOG.md
@@ -1,6 +1,12 @@
CHANGELOG
=========
+4.3.0
+-----
+
+* Made the `serialize()` and `unserialize()` methods of `AbstractToken` and
+ `AuthenticationException` final, use `getState()`/`setState()` instead
+
4.2.0
-----
diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php
index e8546788d5..f879cf8a87 100644
--- a/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php
+++ b/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php
@@ -133,20 +133,67 @@ abstract class AbstractToken implements TokenInterface
/**
* {@inheritdoc}
+ *
+ * @final since Symfony 4.3, use getState() instead
+ *
+ * @internal since Symfony 4.3, use getState() instead
*/
public function serialize()
{
- $serialized = [$this->user, $this->authenticated, $this->roles, $this->attributes];
-
- return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null);
+ return $this->doSerialize($this->getState(), \func_num_args() ? \func_get_arg(0) : null);
}
/**
* {@inheritdoc}
+ *
+ * @final since Symfony 4.3, use setState() instead
+ *
+ * @internal since Symfony 4.3, use setState() instead
*/
public function unserialize($serialized)
{
- list($this->user, $this->authenticated, $this->roles, $this->attributes) = \is_array($serialized) ? $serialized : unserialize($serialized);
+ $this->setState(\is_array($serialized) ? $serialized : unserialize($serialized));
+ }
+
+ /**
+ * Returns all the necessary state of the object for serialization purposes.
+ *
+ * There is no need to serialize any entry, they should be returned as-is.
+ * If you extend this method, keep in mind you MUST guarantee parent data is present in the state.
+ * Here is an example of how to extend this method:
+ *
+ * protected function getState(): array
+ * {
+ * return [$this->childAttribute, parent::getState()];
+ * }
+ *
+ *
+ * @see setState()
+ */
+ protected function getState(): array
+ {
+ return [$this->user, $this->authenticated, $this->roles, $this->attributes];
+ }
+
+ /**
+ * Restores the object state from an array given by getState().
+ *
+ * There is no need to unserialize any entry in $data, they are already ready-to-use.
+ * If you extend this method, keep in mind you MUST pass the parent data to its respective class.
+ * Here is an example of how to extend this method:
+ *
+ * protected function setState(array $data)
+ * {
+ * [$this->childAttribute, $parentData] = $data;
+ * parent::setState($parentData);
+ * }
+ *
+ *
+ * @see getState()
+ */
+ protected function setState(array $data)
+ {
+ [$this->user, $this->authenticated, $this->roles, $this->attributes] = $data;
}
/**
diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/AnonymousToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/AnonymousToken.php
index 328d3043d2..18b2481330 100644
--- a/src/Symfony/Component/Security/Core/Authentication/Token/AnonymousToken.php
+++ b/src/Symfony/Component/Security/Core/Authentication/Token/AnonymousToken.php
@@ -57,19 +57,17 @@ class AnonymousToken extends AbstractToken
/**
* {@inheritdoc}
*/
- public function serialize()
+ protected function getState(): array
{
- $serialized = [$this->secret, parent::serialize(true)];
-
- return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null);
+ return [$this->secret, parent::getState()];
}
/**
* {@inheritdoc}
*/
- public function unserialize($serialized)
+ protected function setState(array $data)
{
- list($this->secret, $parentStr) = \is_array($serialized) ? $serialized : unserialize($serialized);
- parent::unserialize($parentStr);
+ [$this->secret, $parentData] = $data;
+ parent::setState($parentData);
}
}
diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php
index bc6c0ce522..733f29159a 100644
--- a/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php
+++ b/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php
@@ -77,19 +77,17 @@ class PreAuthenticatedToken extends AbstractToken
/**
* {@inheritdoc}
*/
- public function serialize()
+ protected function getState(): array
{
- $serialized = [$this->credentials, $this->providerKey, parent::serialize(true)];
-
- return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null);
+ return [$this->credentials, $this->providerKey, parent::getState()];
}
/**
* {@inheritdoc}
*/
- public function unserialize($str)
+ protected function setState(array $data)
{
- list($this->credentials, $this->providerKey, $parentStr) = \is_array($str) ? $str : unserialize($str);
- parent::unserialize($parentStr);
+ [$this->credentials, $this->providerKey, $parentData] = $data;
+ parent::setState($parentData);
}
}
diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/RememberMeToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/RememberMeToken.php
index 21a190d6b3..40daa68923 100644
--- a/src/Symfony/Component/Security/Core/Authentication/Token/RememberMeToken.php
+++ b/src/Symfony/Component/Security/Core/Authentication/Token/RememberMeToken.php
@@ -92,19 +92,17 @@ class RememberMeToken extends AbstractToken
/**
* {@inheritdoc}
*/
- public function serialize()
+ protected function getState(): array
{
- $serialized = [$this->secret, $this->providerKey, parent::serialize(true)];
-
- return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null);
+ return [$this->secret, $this->providerKey, parent::getState()];
}
/**
* {@inheritdoc}
*/
- public function unserialize($serialized)
+ protected function setState(array $data)
{
- list($this->secret, $this->providerKey, $parentStr) = \is_array($serialized) ? $serialized : unserialize($serialized);
- parent::unserialize($parentStr);
+ [$this->secret, $this->providerKey, $parentData] = $data;
+ parent::setState($parentData);
}
}
diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/UsernamePasswordToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/UsernamePasswordToken.php
index 8a70047a48..d731906eb7 100644
--- a/src/Symfony/Component/Security/Core/Authentication/Token/UsernamePasswordToken.php
+++ b/src/Symfony/Component/Security/Core/Authentication/Token/UsernamePasswordToken.php
@@ -89,19 +89,17 @@ class UsernamePasswordToken extends AbstractToken
/**
* {@inheritdoc}
*/
- public function serialize()
+ protected function getState(): array
{
- $serialized = [$this->credentials, $this->providerKey, parent::serialize(true)];
-
- return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null);
+ return [$this->credentials, $this->providerKey, parent::getState()];
}
/**
* {@inheritdoc}
*/
- public function unserialize($serialized)
+ protected function setState(array $data)
{
- list($this->credentials, $this->providerKey, $parentStr) = \is_array($serialized) ? $serialized : unserialize($serialized);
- parent::unserialize($parentStr);
+ [$this->credentials, $this->providerKey, $parentData] = $data;
+ parent::setState($parentData);
}
}
diff --git a/src/Symfony/Component/Security/Core/Exception/AccountStatusException.php b/src/Symfony/Component/Security/Core/Exception/AccountStatusException.php
index cb91b42364..4d707c07d1 100644
--- a/src/Symfony/Component/Security/Core/Exception/AccountStatusException.php
+++ b/src/Symfony/Component/Security/Core/Exception/AccountStatusException.php
@@ -42,20 +42,17 @@ abstract class AccountStatusException extends AuthenticationException
/**
* {@inheritdoc}
*/
- public function serialize()
+ protected function getState(): array
{
- $serialized = [$this->user, parent::serialize(true)];
-
- return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null);
+ return [$this->user, parent::getState()];
}
/**
* {@inheritdoc}
*/
- public function unserialize($str)
+ protected function setState(array $data)
{
- list($this->user, $parentData) = \is_array($str) ? $str : unserialize($str);
-
- parent::unserialize($parentData);
+ [$this->user, $parentData] = $data;
+ parent::setState($parentData);
}
}
diff --git a/src/Symfony/Component/Security/Core/Exception/AuthenticationException.php b/src/Symfony/Component/Security/Core/Exception/AuthenticationException.php
index a8989c0687..2ee412bfd1 100644
--- a/src/Symfony/Component/Security/Core/Exception/AuthenticationException.php
+++ b/src/Symfony/Component/Security/Core/Exception/AuthenticationException.php
@@ -40,18 +40,67 @@ class AuthenticationException extends RuntimeException implements \Serializable
/**
* {@inheritdoc}
+ *
+ * @final since Symfony 4.3, use getState() instead
+ *
+ * @internal since Symfony 4.3, use getState() instead
*/
public function serialize()
{
- $serialized = [
- $this->token,
- $this->code,
- $this->message,
- $this->file,
- $this->line,
- ];
+ return $this->doSerialize($this->getState(), \func_num_args() ? \func_get_arg(0) : null);
+ }
- return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null);
+ /**
+ * {@inheritdoc}
+ *
+ * @final since Symfony 4.3, use setState() instead
+ *
+ * @internal since Symfony 4.3, use setState() instead
+ */
+ public function unserialize($serialized)
+ {
+ $this->setState(\is_array($serialized) ? $serialized : unserialize($serialized));
+ }
+
+ /**
+ * Returns all the necessary state of the object for serialization purposes.
+ *
+ * There is no need to serialize any entry, they should be returned as-is.
+ * If you extend this method, keep in mind you MUST guarantee parent data is present in the state.
+ * Here is an example of how to extend this method:
+ *
+ * protected function getState(): array
+ * {
+ * return [$this->childAttribute, parent::getState()];
+ * }
+ *
+ *
+ * @see setState()
+ */
+ protected function getState(): array
+ {
+ return [$this->token, $this->code, $this->message, $this->file, $this->line];
+ }
+
+ /**
+ * Restores the object state from an array given by getState().
+ *
+ * There is no need to unserialize any entry in $data, they are already ready-to-use.
+ * If you extend this method, keep in mind you MUST pass the parent data to its respective class.
+ * Here is an example of how to extend this method:
+ *
+ * protected function setState(array $data)
+ * {
+ * [$this->childAttribute, $parentData] = $data;
+ * parent::setState($parentData);
+ * }
+ *
+ *
+ * @see getState()
+ */
+ protected function setState(array $data)
+ {
+ [$this->token, $this->code, $this->message, $this->file, $this->line] = $data;
}
/**
@@ -67,17 +116,6 @@ class AuthenticationException extends RuntimeException implements \Serializable
return $isCalledFromOverridingMethod ? $serialized : serialize($serialized);
}
- public function unserialize($str)
- {
- list(
- $this->token,
- $this->code,
- $this->message,
- $this->file,
- $this->line
- ) = \is_array($str) ? $str : unserialize($str);
- }
-
/**
* Message key to be used by the translation component.
*
diff --git a/src/Symfony/Component/Security/Core/Exception/CustomUserMessageAuthenticationException.php b/src/Symfony/Component/Security/Core/Exception/CustomUserMessageAuthenticationException.php
index 5db47013d4..bd1b18eb32 100644
--- a/src/Symfony/Component/Security/Core/Exception/CustomUserMessageAuthenticationException.php
+++ b/src/Symfony/Component/Security/Core/Exception/CustomUserMessageAuthenticationException.php
@@ -58,20 +58,17 @@ class CustomUserMessageAuthenticationException extends AuthenticationException
/**
* {@inheritdoc}
*/
- public function serialize()
+ protected function getState(): array
{
- $serialized = [parent::serialize(true), $this->messageKey, $this->messageData];
-
- return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null);
+ return [parent::getState(), $this->messageKey, $this->messageData];
}
/**
* {@inheritdoc}
*/
- public function unserialize($str)
+ protected function setState(array $data)
{
- list($parentData, $this->messageKey, $this->messageData) = \is_array($str) ? $str : unserialize($str);
-
- parent::unserialize($parentData);
+ [$parentData, $this->messageKey, $this->messageData] = $data;
+ parent::setState($parentData);
}
}
diff --git a/src/Symfony/Component/Security/Core/Exception/UsernameNotFoundException.php b/src/Symfony/Component/Security/Core/Exception/UsernameNotFoundException.php
index b4b8047f34..155f80e357 100644
--- a/src/Symfony/Component/Security/Core/Exception/UsernameNotFoundException.php
+++ b/src/Symfony/Component/Security/Core/Exception/UsernameNotFoundException.php
@@ -49,26 +49,6 @@ class UsernameNotFoundException extends AuthenticationException
$this->username = $username;
}
- /**
- * {@inheritdoc}
- */
- public function serialize()
- {
- $serialized = [$this->username, parent::serialize(true)];
-
- return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null);
- }
-
- /**
- * {@inheritdoc}
- */
- public function unserialize($str)
- {
- list($this->username, $parentData) = \is_array($str) ? $str : unserialize($str);
-
- parent::unserialize($parentData);
- }
-
/**
* {@inheritdoc}
*/
@@ -76,4 +56,21 @@ class UsernameNotFoundException extends AuthenticationException
{
return ['{{ username }}' => $this->username];
}
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getState(): array
+ {
+ return [$this->username, parent::getState()];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setState(array $data)
+ {
+ [$this->username, $parentData] = $data;
+ parent::setState($parentData);
+ }
}
diff --git a/src/Symfony/Component/Security/Guard/Token/PostAuthenticationGuardToken.php b/src/Symfony/Component/Security/Guard/Token/PostAuthenticationGuardToken.php
index 1e75129c57..9e3646da45 100644
--- a/src/Symfony/Component/Security/Guard/Token/PostAuthenticationGuardToken.php
+++ b/src/Symfony/Component/Security/Guard/Token/PostAuthenticationGuardToken.php
@@ -74,19 +74,17 @@ class PostAuthenticationGuardToken extends AbstractToken implements GuardTokenIn
/**
* {@inheritdoc}
*/
- public function serialize()
+ protected function getState(): array
{
- $serialized = [$this->providerKey, parent::serialize(true)];
-
- return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null);
+ return [$this->providerKey, parent::getState()];
}
/**
* {@inheritdoc}
*/
- public function unserialize($serialized)
+ protected function setState(array $data)
{
- list($this->providerKey, $parentStr) = \is_array($serialized) ? $serialized : unserialize($serialized);
- parent::unserialize($parentStr);
+ [$this->providerKey, $parentData] = $data;
+ parent::setState($parentData);
}
}