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

时间:2016-04-25 08:41:37

标签: php authentication symfony

在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防火墙直接使用它。

我的问题是如何以最佳实践和逻辑方式进行抽象。

AccessTokenAuthenticator类:

<?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
{

services.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

我的确切问题是,即使我定义了两个相同的类,但实现名称空间不同甚至我怎么能将它提供给防火墙?如何从防火墙中抽象出来?

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:0)

This is probably non-PSR compliant but will work (probably).

File AccessTokenAuthenticator.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 { }
}

Autoloading should still pick it up.

答案 1 :(得分:0)

OK I find the answer,

When I focus the service container and security.yml firewall configurations. I just forget, my firewall configuration can be different from symfony2 and symfony3 application.

In that manner I can would define a BaseAccessTokenAuthenticator and AccessTokenAuthenticator for either PreSymfony28 and Symfony30 and then I will put all the logic inside BaseAccessTokenAuthenticator and AccessTokenAuthenticator would be multiple and there would be 2 different service. One for symfony2.7 firewall configuration one for symfony3.0.

Base Class :

<?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 class :

<?php

namespace MyCompany\SBundle\Security;

use Symfony\Component\Security\Http\Authentication\SimplePreAuthenticatorInterface;

/**
 * Class AccessTokenAuthenticatorSf30
 */
class AccessTokenAuthenticatorSf30 extends BaseAccessTokenAuthenticator implements SimplePreAuthenticatorInterface
{
}

Pre Symfony 2.8 class :

<?php

namespace MyCompany\SBundle\Security;

use Symfony\Component\Security\Core\Authentication\SimplePreAuthenticatorInterface;

/**
 * Class AccessTokenAuthenticatorPreSf28
 */
class AccessTokenAuthenticatorPreSf28 extends BaseAccessTokenAuthenticator implements SimplePreAuthenticatorInterface
{
}

Services :

# 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"]

wide application firewall for symfony =< 2.8 :

    simple_preauth:
        authenticator: mycompany.security.accesstoken_authenticator_sf28

wide application firewall for symfony >= 2.8 :

    simple_preauth:
        authenticator: mycompany.security.accesstoken_authenticator_sf30