Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7434265
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 29, 20262026-05-29T09:48:28+00:00 2026-05-29T09:48:28+00:00

I’m working on a Symfony2 application with an API available for other applications. I

  • 0

I’m working on a Symfony2 application with an API available for other applications.
I want to secure the access to the API. For this part I have no problem.

But I have to make this connection available not with the usual login/password couple but just with an API key.

So I went to the official site and its awesome cookbook for creating a custom authentication provider, just what I need I said to myself.

The example was not what I needed but I decided to adapt it to my needs.

Unfortunately I didn’t succeed.

I’ll give you my code and I will explain my problem after.

Here is my Factory for creating the authentication provider and the listener:

<?php

namespace Pmsipilot\UserBundle\DependencyInjection\Security\Factory;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SecurityFactoryInterface;

class ApiFactory implements SecurityFactoryInterface
{
  /**
   * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
   * @param string $id
   * @param aray $config
   * @param string $userProvider
   * @param string $defaultEntryPoint
   * @return array
   */
  public function create(ContainerBuilder $container, $id, $config, $userProvider, $defaultEntryPoint)
  {
    $providerId = 'security.authentification.provider.api.'.$id;
    $container
      ->setDefinition($providerId, new DefinitionDecorator('api.security.authentification.provider'))
      ->replaceArgument(0, new Reference($userProvider))
    ;

    $listenerId = 'security.authentification.listener.api.'.$id;
    $listener = $container->setDefinition($listenerId, new DefinitionDecorator('api.security.authentification.listener'));

    return array($providerId, $listenerId, $defaultEntryPoint);
  }

  /**
   * @return string
   */
  public function getPosition()
  {
    return 'http';
  }

  /**
   * @return string
   */
  public function getKey()
  {
    return 'api';
  }

  /**
   * @param \Symfony\Component\Config\Definition\Builder\NodeDefinition $node
   * @return void
   */
  public function addConfiguration(NodeDefinition $node)
  {
  }
}

Next my listener code:

<?php

namespace Pmsipilot\UserBundle\Security\Firewall;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Http\Firewall\ListenerInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Pmsipilot\UserBundle\Security\WsseUserToken;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;

class ApiListener implements ListenerInterface
{
  protected $securityContext;
  protected $authenticationManager;

  /**
   * Constructor for listener. The parameters are defined in services.xml.
   *
   * @param \Symfony\Component\Security\Core\SecurityContextInterface $securityContext
   * @param \Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface $authenticationManager
   */
  public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager)
  {
    $this->securityContext = $securityContext;
    $this->authenticationManager = $authenticationManager;
  }

  /**
   * Handles login request.
   *
   * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
   * @return void
   */
  public function handle(GetResponseEvent $event)
  {
    $request = $event->getRequest();

    $securityToken = $this->securityContext->getToken();

    if($securityToken instanceof AuthenticationToken)
    {
      try
      {
        $this->securityContext->setToken($this->authenticationManager->authenticate($securityToken));
      }
      catch(\Exception $exception)
      {
        $this->securityContext->setToken(null);
      }
    }
  }
}

My authentication provider code:

<?php

namespace Pmsipilot\UserBundle\Security\Authentication\Provider;

use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface;
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\UserCheckerInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Exception\AuthenticationServiceException;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;

class ApiProvider implements AuthenticationProviderInterface
{
  private $userProvider;

  /**
   * Constructor.
   *
   * @param \Symfony\Component\Security\Core\User\UserProviderInterface $userProvider An UserProviderInterface instance
   */
  public function __construct(UserProviderInterface $userProvider)
  {
    $this->userProvider = $userProvider;
  }

  /**
   * @param string $username
   * @param \Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken $token
   * @return mixed
   * @throws \Symfony\Component\Security\Core\Exception\AuthenticationServiceException|\Symfony\Component\Security\Core\Exception\UsernameNotFoundException
   */
  protected function retrieveUser($username, UsernamePasswordToken $token)
  {
    $user = $token->getUser();
    if($user instanceof UserInterface)
    {
      return $user;
    }

    try
    {
      $user = $this->userProvider->loadUserByApiKey($username, $token->getCredentials());

      if(!$user instanceof UserInterface)
      {
        throw new AuthenticationServiceException('The user provider must return a UserInterface object.');
      }

      return $user;
    }
    catch (\Exception $exception)
    {
      throw new AuthenticationServiceException($exception->getMessage(), $token, 0, $exception);
    }
  }

  /**
   * @param TokenInterface $token
   * @return null|\Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken
   * @throws \Symfony\Component\Security\Core\Exception\AuthenticationServiceException|\Symfony\Component\Security\Core\Exception\BadCredentialsException|\Symfony\Component\Security\Core\Exception\UsernameNotFoundException
   */
  function authenticate(TokenInterface $token)
  {
    $username = $token->getUsername();
    if(empty($username))
    {
      throw new AuthenticationServiceException('No username given.');
    }

    try
    {
      $user = $this->retrieveUser($username, $token);

      if(!$user instanceof UserInterface)
      {
        throw new AuthenticationServiceException('retrieveUser() must return a UserInterface.');
      }

      $authenticatedToken = new UsernamePasswordToken($user, null, 'api', $user->getRoles());
      $authenticatedToken->setAttributes($token->getAttributes());

      return $authenticatedToken;
    }
    catch(\Exception $exception)
    {
      throw $exception;
    }
  }

  /**
   * @param TokenInterface $token
   * @return bool
   */
  public function supports(TokenInterface $token)
  {
    return true;
  }
}

To use these two objects I used a yml file to configure them:

<container xmlns="http://symfony.com/schema/dic/services"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

  <services>
    <service id="pmsipilot.api.security.authentication.factory" class="Pmsipilot\UserBundle\DependencyInjection\Security\Factory\ApiFactory" public="false">
      <tag name="security.listener.factory" />
    </service>
  </services>
</container>

Now the authentication provider code:

<?php

namespace Pmsipilot\UserBundle\Security\Authentication\Provider;

use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface;
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\UserCheckerInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Exception\AuthenticationServiceException;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;

class ApiProvider implements AuthenticationProviderInterface
{
  private $userProvider;

  /**
   * Constructor.
   *
   * @param \Symfony\Component\Security\Core\User\UserProviderInterface $userProvider An UserProviderInterface instance
   */
  public function __construct(UserProviderInterface $userProvider)
  {
    $this->userProvider = $userProvider;
  }

  /**
   * @param string $username
   * @param \Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken $token
   * @return mixed
   * @throws \Symfony\Component\Security\Core\Exception\AuthenticationServiceException|\Symfony\Component\Security\Core\Exception\UsernameNotFoundException
   */
  protected function retrieveUser($username, UsernamePasswordToken $token)
  {
    $user = $token->getUser();
    if($user instanceof UserInterface)
    {
      return $user;
    }

    try
    {
      $user = $this->userProvider->loadUserByApiKey($username, $token->getCredentials());

      if(!$user instanceof UserInterface)
      {
        throw new AuthenticationServiceException('The user provider must return a UserInterface object.');
      }

      return $user;
    }
    catch (\Exception $exception)
    {
      throw new AuthenticationServiceException($exception->getMessage(), $token, 0, $exception);
    }
  }

  /**
   * @param TokenInterface $token
   * @return null|\Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken
   * @throws \Symfony\Component\Security\Core\Exception\AuthenticationServiceException|\Symfony\Component\Security\Core\Exception\BadCredentialsException|\Symfony\Component\Security\Core\Exception\UsernameNotFoundException
   */
  function authenticate(TokenInterface $token)
  {
    $username = $token->getUsername();
    if(empty($username))
    {
      throw new AuthenticationServiceException('No username given.');
    }

    try
    {
      $user = $this->retrieveUser($username, $token);

      if(!$user instanceof UserInterface)
      {
        throw new AuthenticationServiceException('retrieveUser() must return a UserInterface.');
      }

      $authenticatedToken = new UsernamePasswordToken($user, null, 'api', $user->getRoles());
      $authenticatedToken->setAttributes($token->getAttributes());

      return $authenticatedToken;
    }
    catch(\Exception $exception)
    {
      throw $exception;
    }
  }

  /**
   * @param TokenInterface $token
   * @return bool
   */
  public function supports(TokenInterface $token)
  {
    return true;
  }
}

Just FYI my user provider:

<?php

namespace Pmsipilot\UserBundle\Security\Provider;

use Propel\PropelBundle\Security\User\ModelUserProvider;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use \Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder;

class ApiProvider extends ModelUserProvider
{
  /**
   * Constructeur
   */
  public function __construct()
  {
    parent::__construct('Pmsipilot\UserBundle\Model\User', 'Pmsipilot\UserBundle\Proxy\User', 'username');
  }

  /**
   * @param string $apikey
   * @return mixed
   * @throws \Symfony\Component\Security\Core\Exception\UsernameNotFoundException
   */
  public function loadUserByApiKey($apikey)
  {
    $queryClass = $this->queryClass;
    $query      = $queryClass::create();

    $user = $query
      ->filterByApiKey($apikey)
      ->findOne()
    ;

    if(null === $user)
    {
      throw new UsernameNotFoundException(sprintf('User with "%s" api key not found.', $apikey));
    }
    $proxyClass = $this->proxyClass;
    return new $proxyClass($user);
  }
}

And for the configuration part my security.yml:

security:
  factories:
    PmsipilotFactory: "%kernel.root_dir%/../src/Pmsipilot/UserBundle/Resources/config/security_factories.xml"

  providers:
    interface_provider:
      id: pmsipilot.security.user.provider
    api_provider:
      id: api.security.user.provider

  encoders:
    Pmsipilot\UserBundle\Proxy\User: sha512

  firewalls:
    assets:
      pattern:                ^/(_(profiler|wdt)|css|images|js|favicon.ico)/
      security:               false

    api:
      provider:               api_provider
      access_denied_url:      /unauthorizedApi
      pattern:                ^/api
      api:                    true
      http_basic:             true
      stateless:              true

    interface:
      provider:               interface_provider
      access_denied_url:      /unauthorized
      pattern:                ^/
      anonymous:              ~
      form_login:
        login_path:           /login
        check_path:           /login_check
        use_forward:          true
        default_target_path:  /
      logout:                 ~

  access_control:
    - { path: ^/api, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/, roles: SUPER_ADMIN }

Wow it’s a lot of code, I hope it’s not too boring.

My problem here is that my custom authentication provider is called by the two firewalls api and interface instead of just by the api one.
And of course they don’t behave as I wanted.

I didn’t find anything about such an issue.
I know I made a mistake, otherwise it will be working, but where and why I don’t know.

I also found this tutorial but it didn’t help much more.

Of course, don’t hesitate to suggest me if there is another solution for using another authentication provider than the default one.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-29T09:48:29+00:00Added an answer on May 29, 2026 at 9:48 am

    So I will answer my own question because I found the solution to my problem and I’ll tell you how I solved it.

    There was some mistake in my example and I understood them searching in the Symfony code.

    Like the key returned by the getKey method of the Factory class. I found that the api one I’ve created was for me not an other parameter to my security.yml file, but a replacement to the http_basic one.
    That’s why I’m having some trouble using two providers instead of just one, because I got two keys (api and http_basic) which both used a provider. In fact I think it’s the reason to that problem.

    To make it simple I follow the Symfony tutorial, except for the token class but I replaced the code of the new classes by the code of the Symfony classes.
    In a kind of way I recreated the http basic authentication of Symfony to make it posssible to overload.
    And here I am, I could do what I want, configure a different type of http authentication based on the Symfony one but with several changes.

    This story helped me because know I know that the best way to understand Symfony principles is to go deeper in the code and look after.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
this is what i have right now Drawing an RSS feed into the php,
I have a French site that I want to parse, but am running into
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I have this code: - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock { NSString *someString = [[NSString
I have this code to decode numeric html entities to the UTF8 equivalent character.
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I have just tried to save a simple *.rtf file with some websites and
I want to count how many characters a certain string has in PHP, but
For some reason, after submitting a string like this Jack’s Spindle from a text

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.