必须保持向后兼容性中断的身份验证器类的方法


way for an authenticator class which must keep backward compability break

在Symfony 2.8之前 SimplePreAuthenticatorInterface位于以下命名空间中Symfony'Component'Security'Core'Authentication'SimplePreAuthenticatorInterface它在 2.8 中已弃用,并在 3.0 中更改为 Symfony'Component'Security'Http'Authentication'SimplePreAuthenticatorInterface

现在我正在编写一个必须在 symfony 2.7 和 symfony 3.0 中工作的捆绑包,它是一个供私人使用的 API 身份验证器捆绑包。

我想为它写一个检查接口存在的工厂

来自 FosUserBundle 的示例

if (interface_exists('Symfony'Component'Security'Core'Authentication'Token'Storage'TokenStorageInterface')) {
    $tokenStorage = $this->get('security.token_storage');
} else {
    $tokenStorage = $this->get('security.context');
}

但是我实现这个接口的类是DI中的一个服务,symfony防火墙直接使用它。

我的问题是,我怎样才能以一种最佳实践和逻辑的方式进行这种抽象。

访问令牌身份验证器类:

<?php
namespace MyCompany'SBundle'Security;
// this usage for before symfony 2.8
use Symfony'Component'Security'Core'Authentication'SimplePreAuthenticatorInterface;
/**
 * Class AccessTokenAuthenticator
 */
class AccessTokenAuthenticator implements SimplePreAuthenticatorInterface
{

服务.yml

# Authentication
mycompany_security.security.accesstoken_authenticator:
    class:     MyCompany'SBundle'Security'AccessTokenAuthenticator
    arguments: ["@mycompany_security.security.accesstoken_userprovider"]

防火墙配置 :

secure_area:
    pattern:  ^/
    stateless: true
    simple_preauth:
        authenticator: mycompany_security.security.accesstoken_authenticator

我的确切问题是,即使我定义了两个彼此相同但实现命名空间不同的类,即使我如何将其提供给防火墙?如何从防火墙中抽象出来?

任何帮助将不胜感激。

这可能不符合 PSR 标准,但(可能)有效。

文件访问令牌身份验证器.php

if (interface_exists('Symfony'Component'Security'Core'Authentication'Token'Storage'TokenStorageInterface')) {
    class AccessTokenAuthenticator implements 'Symfony'Component'Security'Core'Authentication'SimplePreAuthenticatorInterface { }
} else {
      class AccessTokenAuthenticator implements 'Symfony'Component'Security'Http'Authentication'SimplePreAuthenticatorInterface { }
}

自动加载仍然应该拾取它。

好的,我找到了答案,

当我专注于服务容器和security.yml防火墙配置时。我只是忘记了,我的防火墙配置可能与symfony2和symfony3应用程序不同。

通过这种方式,我可以为 PreSymfony28 和 Symfony30 定义一个BaseAccessTokenAuthenticatorAccessTokenAuthenticator,然后我将把所有逻辑放在BaseAccessTokenAuthenticator里面,AccessTokenAuthenticator 将是多个,并且会有 2 个不同的服务。一个用于symfony2.7防火墙配置,一个用于symfony3.0。

基类 :

<?php
namespace MyCompany'SBundle'Security;
/**
 * Abstract Class BaseAccessTokenAuthenticator
 */
abstract class BaseAccessTokenAuthenticator
{
    public function createToken(Request $request, $providerKey)
    {
      // Implementation
    }
    public function authenticateToken(
        TokenInterface $token,
        UserProviderInterface $userProvider,
        $providerKey
    ) {
      // Implementation.
    }
    public function supportsToken(TokenInterface $token, $providerKey)
    {
      // Implementation.
    }
}

Symfony 3.0 类:

<?php
namespace MyCompany'SBundle'Security;
use Symfony'Component'Security'Http'Authentication'SimplePreAuthenticatorInterface;
/**
 * Class AccessTokenAuthenticatorSf30
 */
class AccessTokenAuthenticatorSf30 extends BaseAccessTokenAuthenticator implements SimplePreAuthenticatorInterface
{
}

预科2.8类:

<?php
namespace MyCompany'SBundle'Security;
use Symfony'Component'Security'Core'Authentication'SimplePreAuthenticatorInterface;
/**
 * Class AccessTokenAuthenticatorPreSf28
 */
class AccessTokenAuthenticatorPreSf28 extends BaseAccessTokenAuthenticator implements SimplePreAuthenticatorInterface
{
}

服务业:

# Authentication
mycompany.security.accesstoken_authenticator_pre_sf28:
    class:     MyCompany'SBundle'Security'AccessTokenAuthenticatorPreSf28
    arguments: ["@mycompany.security.accesstoken_userprovider"]
# Authentication
mycompany.security.accesstoken_authenticator_sf30:
    class:     MyCompany'SBundle'Security'AccessTokenAuthenticatorSf30
    arguments: ["@mycompany.security.accesstoken_userprovider"]

Symfony 的广泛应用程序防火墙 =<2.8 :

    simple_preauth:
        authenticator: mycompany.security.accesstoken_authenticator_sf28

Symfony> = 2.8 的广泛应用程序防火墙:

    simple_preauth:
        authenticator: mycompany.security.accesstoken_authenticator_sf30