PHPUnit - Symfony authorization with x-api-key - php

I am using PHPUnit test to write functional test for specific endpoint.
Problem with it is that for the authorization process I have to set X-API-KEY in headers section of the request.
I keep getting an error:
Authentication Required
I am using an valid api key form my test database table and it return this specific error I mentioned above.
public function testDoItSuccessful()
{
$client = static::createClient(
[],
['HTTP_x-api-key' => 'clWD0ggquG1Ok2xOVLIcMmPJtu1uYWG']
);
$client->request(
Request::METHOD_POST,
'/api/v1/do-it',
[],
[],
[
'CONTENT_TYPE' => 'application/json',
'ACCEPT' => 'application/json',
],
json_encode($myArray)
);
return $client;
}
As I am new, primarily with authorization process in test env any help is highly appreciated.
Note: I am using Symfony 4.4
I tried THIS.
Error is coming for these two functions in TokenAuthenticator class.
public function supports(Request $request)
{
$hasApiKey = true;
$requestHeaders = $this->getLowerCasedHeaders();
if (!isset($requestHeaders['x-api-key'])) {
$hasApiKey = false;
}
return $hasApiKey;
}
private function getLowerCasedHeaders()
{
$requestHeaders = getallheaders();
return array_change_key_case($requestHeaders, CASE_LOWER);
}
public function getCredentials(Request $request)
{
$requestHeaders = $this->getLowerCasedHeaders();
return $requestHeaders['x-api-key'];
}
public function getUser($credentials, UserProviderInterface $userProvider)
{
if (null === $credentials) {
// Code 401 "Unauthorized"
return null;
}
return $this->entityManager->getRepository(Client::class)->findOneBy(['apiKey' => $credentials]);
}
public function checkCredentials($credentials, UserInterface $user)
{
if ($user->getStatus() != Client::STATUS_ACTIVE) {
throw new AuthenticationException("USER_NOT_ACTIVE", 403);
}
$user->setLastSeen(new DateTime('now'));
$this->entityManager->persist($user);
$this->entityManager->flush();
return true;
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
return null;
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
$data = [
'message' => 'Authentication failed, wrong api key'
];
if ($exception->getCode() == 403) {
$data = ['message' => $exception->getMessage()];
}
return new JsonResponse($data, Response::HTTP_UNAUTHORIZED);
}
public function start(Request $request, AuthenticationException $authException = null)
{
$data = [
// you might translate this message
'message' => 'Authentication Required'
];
return new JsonResponse($data, Response::HTTP_UNAUTHORIZED);
}
public function supportsRememberMe()
{
return false;
}
I have changed apache_request_headers() to getallheaders() and tests are passing with Authentication Required message.
When print_r() the:
$requestHeaders = $this->getLowerCasedHeaders();
I can not see my defined headers from request? It returns Array()..

You need to check how the Client Class parse the headers, specially on the test, there is a part where the code execute a search for the word HTTP_ for the custom header. So basically on your test instead of call only x-api-key you need to add the prefix HTTP_. Try with this:
TokenAuthenticator
public function supports(Request $request)
{
return $request->headers->has('x-api-key');
}
On your test:
public function testDoItSuccessful()
{
crawler = $this->client->request(
Request::METHOD_POST,
'/api/v1/do-it',
[],
[],
['HTTP_x-api-key' => self::TOKEN, 'CONTENT_TYPE' => 'application/json', 'ACCEPT' => 'application/json']
);
$status = $this->client->getResponse()->getStatusCode();
}

For me what worked is to return a UserInterface with the role defined in your security:
access_control:
- { path: ^/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api, roles: ROLE_API }
My firewall:
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
api:
pattern: ^/api/
custom_authenticators:
- App\CrediFastCore\Infrastructure\Security\ApiKeyAuthenticator
Since we need ROLE_API
public function authenticate(Request $request): Passport
{
$apiToken = $request->headers->get('X-AUTH-TOKEN');
if (null === $apiToken) {
throw new CustomUserMessageAuthenticationException('No API token provided');
}
if ($this->parameters->get('api_key') != $apiToken) {
//I compare api token with the one I've set on my parameters.yaml
throw new CustomUserMessageAuthenticationException('Wrong API token provided');
}
$user = new User();
$user->setName('api');
$user->setRoles(['ROLE_API']);
return new SelfValidatingPassport(
new UserBadge($apiToken, function () use ($user, $apiToken) {
return $user;
})
);
}
This part was the "fix"
return new SelfValidatingPassport(
new UserBadge($apiToken, function () use ($user, $apiToken) {
return $user;
})
);

Related

TwoFactorsAuthenticator not connect after second authenticate

here is my problem, I have to put a two-factor authentication. When I fill the first form no worries in the profiler I find my user connected, but when I scan the qrcode of the second form it tells me that the code provided is good but it sends me back to the first page of connection without user in the profiler as if I was disconnected
Could you help me
My Class LOGIN with email & password
class AppCustomAuthenticator extends AbstractLoginFormAuthenticator
{
use TargetPathTrait;
public const LOGIN_ROUTE = 'app_login';
public function __construct(private readonly UrlGeneratorInterface $urlGenerator){}
public function authenticate(Request $request): Passport
{
$email = $request->get('login')['email'];
$request->getSession()->set(Security::LAST_USERNAME, $email);
return new Passport(
new UserBadge($email),
new PasswordCredentials($request->get('login')['password']),
[
new CsrfTokenBadge('authenticate', $request->request->get('_csrf_token')),
]
);
}
/**
* #throws Exception
*/
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
return new RedirectResponse($this->urlGenerator->generate('app_security_setup_fa'));
}
protected function getLoginUrl(Request $request): string
{
return $this->urlGenerator->generate(self::LOGIN_ROUTE);
}
}
My Class TwoFactorsAuthenticator
class TwoFactorsAuthenticator extends AbstractLoginFormAuthenticator
{
use TargetPathTrait;
public const LOGIN_ROUTE = 'app_security_setup_fa';
public function __construct(private TokenStorageInterface $tokenStorage, private UrlGeneratorInterface $urlGenerator)
{
}
public function supports(Request $request): bool
{
return parent::supports($request)
&& $request->getSession()->has(SecurityController::QR_CODE_KEY);
}
/**
* #throws IncompatibleWithGoogleAuthenticatorException
* #throws SecretKeyTooShortException
* #throws InvalidCharactersException
*/
public function authenticate(Request $request): Passport
{
//Get user from login form
$existingToken = $this->tokenStorage->getToken();
if (null === $existingToken || $existingToken instanceof NullToken) {
throw new UserNotFoundException();
}
$user = $existingToken->getUser();
$qrCode = $request->request->get('qrCode', '');
$secretKey = $request->getSession()->get(SecurityController::QR_CODE_KEY);
$google2fa = new Google2FA();
$google2fa->setSecret($secretKey);
$google2fa->setWindow(1);
if (true !== $google2fa->verifyKey($google2fa->getSecret(), $qrCode)) {
throw new CustomUserMessageAuthenticationException('This code is not valid');
}
$email = $user->getUserIdentifier();
return new SelfValidatingPassport(
new UserBadge($email)
);
}
public function createToken(Passport $passport, string $firewallName): TokenInterface
{
$currentToken = parent::createToken($passport, $firewallName);
$roles = array_merge($currentToken->getRoleNames(), [DoubleAuthentificationSubscriber::ROLE_2FA_SUCCEED]);
return new PostAuthenticationToken(
$currentToken->getUser(),
$currentToken->getFirewallName(),
$roles
);
}
protected function getLoginUrl(Request $request): string
{
return $this->urlGenerator->generate(self::LOGIN_ROUTE);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
if ($targetPath = $this->getTargetPath($request->getSession(), $firewallName)) {
$this->removeTargetPath($request->getSession(), $firewallName);
}
return new RedirectResponse($this->urlGenerator->generate('app_security_authentification_protected'));
}
}
My Class DoubleAuthentificationSubscriber
class DoubleAuthentificationSubscriber implements EventSubscriberInterface
{
public const ROLE_2FA_SUCCEED = 'ROLE_2FA_SUCCEED';
public const FIREWALL_NAME = 'main';
public function __construct(private RouterInterface $router, private TokenStorageInterface $tokenStorage)
{
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::REQUEST => ['onKernelRequest', -10],
];
}
public function onKernelRequest(RequestEvent $event)
{
if (!$event->isMainRequest()) {
return;
}
$route = $event->getRequest()->attributes->get('_route');
if (!in_array($route, ['app_security_authentification_protected'], true)) {
return;
}
$currentToken = $this->tokenStorage->getToken();
if (!$currentToken instanceof PostAuthenticationToken) {
$response = new RedirectResponse($this->router->generate('app_login'));
$event->setResponse($response);
return;
}
if (null === $currentToken->getUser() || self::FIREWALL_NAME !== $currentToken->getFirewallName()) {
return;
}
if ($this->hasRole($currentToken, self::ROLE_2FA_SUCCEED)) {
return;
}
$response = new RedirectResponse($this->router->generate('app_security_setup_fa'));
$event->setResponse($response);
}
private function hasRole(TokenInterface $token, string $role): bool
{
return in_array($role, $token->getRoleNames(), true);
}
}
My security.yaml
security:
enable_authenticator_manager: true
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
password_hashers:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
providers:
# used to reload user from session & other features (e.g. switch_user)
app_user_provider:
entity:
class: App\Entity\User
property: email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
lazy: true
provider: app_user_provider
entry_point: App\Security\AppCustomAuthenticator
custom_authenticator:
- App\Security\AppCustomAuthenticator
- App\Security\TwoFactorsAuthenticator
logout:
path: app_logout
# where to redirect after logout
target: app_login
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#the-firewall
# https://symfony.com/doc/current/security/impersonating_user.html
# switch_user: true
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
- { path: ^/login, roles: PUBLIC_ACCESS }
- { path: ^/logout, roles: PUBLIC_ACCESS }
- { path: ^/setup-2FA, roles: ROLE_USER }
when#test:
security:
password_hashers:
# By default, password hashers are resource intensive and take time. This is
# important to generate secure password hashes. In tests however, secure hashes
# are not important, waste resources and increase test times. The following
# reduces the work factor to the lowest possible values.
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface:
algorithm: auto
cost: 4 # Lowest possible value for bcrypt
time_cost: 3 # Lowest possible value for argon
memory_cost: 10 # Lowest possible value for argon
I've tried removing the double authentication and I'm able to log in.
But as soon as I put it back on, it loops on the authentication.

AppAuthenticator Symfony

I want to put an authenticator in my API, this anthenticator have to check if the ID given in the headers is in my database. The problem is that I don't understand how this work.
I have read the docs but keep don't understand. (Maybe because of my english).
My API don't need login and password, I just want him to check at every request.
For now I have an error :
Uncaught PHP Exception UnexpectedValueException: "The App\Security\AppAuthenticator::getUser() method must return a UserInterface. You returned boolean
But i'm sure that I have a lot of another problem in my code.
There is my AppAuthenticator :
class AppAuthenticator extends AbstractGuardAuthenticator
{
public function supports(Request $request)
{
return true;
}
public function getCredentials(Request $request)
{
return [
'token' => $request->headers->has('DDMDL-AUTH-TOKEN'),
];
}
public function getUser($credentials, UserProviderInterface $userProvider)
{
$apiToken = $credentials['token'];
if (null === $apiToken) {
return;
}
require __DIR__ . DIRECTORY_SEPARATOR . ".." . DIRECTORY_SEPARATOR . "Entity" . DIRECTORY_SEPARATOR . "sqlconnect.php";
$auth = 'SELECT ID FROM MOBILEDDMDL WHERE ID = :idtel ';
$prepauth = $pdo->prepare($auth);
$prepauth->execute(array(':idtel' => $apiToken));
$user = $prepauth->fetch();
if ($user) {
// fail authentication with a custom error
throw new CustomUserMessageAuthenticationException('Pas autorisé');
}
return $user;
//return $this->em->getRepository(User::class)->findOneBy(['apiToken' => $apiToken]);
}
public function checkCredentials($credentials, UserInterface $user)
{
// todo
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
// todo
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
return new RedirectResponse($targetPath);
}
}
public function start(Request $request, AuthenticationException $authException = null)
{
// todo
}
public function supportsRememberMe()
{
// todo
}
}
getUser() want you to return a UserInterface instead instead of your boolean. I believe your User::class extends UserInterface so the commented line was the correct variable to return:
//return $this->em->getRepository(User::class)->findOneBy(['apiToken' => $apiToken]);
My getUser looks like :
public function getUser($credentials, UserProviderInterface $userProvider)
{
$token = new CsrfToken('authenticate', $credentials['csrf_token']);
if (!$this->csrfTokenManager->isTokenValid($token)) {
throw new InvalidCsrfTokenException();
}
if(strpos($credentials['identifiant'], '#') !== false){
$user = $this->entityManager->getRepository(Utilisateur::class)->findOneBy(['email' => $credentials['identifiant']]);
} else {
$user = $this->entityManager->getRepository(Utilisateur::class)->findOneBy(['identifiant' => $credentials['identifiant']]);
}
if (!$user) {
throw new CustomUserMessageAuthenticationException('Aucun utilisateur trouvé avec ce nom de compte');
}
return $user;
}
checkCredential is the method which verify the password or whatever and this method will return true of false (if the user connexion is ok or not)
My checkCredential looks like :
public function checkCredentials($credentials, UserInterface $user)
{
$passOk1 = password_verify($credentials['password'], $user->getMdp());
$passOk = md5($credentials['password']) === $user->getMdp();
$credential = false;
if($passOk || $passOk1) {
$user->setDerniereConnexion(new DateTime(date('Y-m-d H:i:s')));
$this->entityManager->persist($user);
$this->entityManager->flush();
$this->entityManager->clear();
$credential = true;
}
return $credential;
}

Symfony2 custom authentication system passes user when it shouldn't

I'm writing a bundle for Symfony2 and I need to write a custom authentication system with guards. The whole system is based on tokens. Let's assume I need to send a POST request. In headers I have to include 'TOKEN: testtoken'.
I send a request without 'TOKEN: testtoken' in headers and I get
{ "message": "Authentication Required" }
I send a request with 'TOKEN: badtoken' and I get
{ "message": "Username could not be found." }
Don't look at 'username'. It's mistake.
I send request with 'TOKEN: testtoken' and I get
{ "token": "testtoken" }
It's just example page.
Now I delete 'TOKEN: testtoken' from headers (I use Postman for testing REST APIs) and I get
{ "token": "testtoken" }
I have no idea why. In my opinion in this case my system should return
{ "message": "Authentication Required" }
Here’s my TokenAuthenticator.php
<?php
namespace WLN\AuthTokenBundle\Security;
use Doctrine\ORM\EntityManager;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
class TokenAuthenticator extends AbstractGuardAuthenticator
{
private $em;
private $user_repository;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
public function setConfig($user_repo)
{
$this->user_repository = $user_repo;
}
public function getCredentials(Request $request)
{
if($token = $request->headers->get('WLN-AUTH-TOKEN'))
{
return [
'token' => $token
];
}
return null;
}
public function getUser($credentials, UserProviderInterface $userProvider)
{
$token = $credentials['token'];
return $this->em->getRepository($this->user_repository)
->findOneBy(array('token' => $token));
}
public function checkCredentials($credentials, UserInterface $user)
{
return true;
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
return null;
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
$data = array(
'message' => strtr($exception->getMessageKey(), $exception->getMessageData())
);
return new JsonResponse($data, 403);
}
public function start(Request $request, AuthenticationException $authException = null)
{
$data = array(
'message' => 'Authentication Required'
);
return new JsonResponse($data, 401);
}
public function supportsRememberMe()
{
return false;
}
}
P.S. My app is on shared-hosting. May caching cause it or something like that?
I've figured out what was wrong. When I was requesting valid token in my sessions formed PHPSESSID. Because of that I was getting so freaky behavior of my API. In my case the solution is to set security.firewalls.main.stateless to true :).

Symfony 3 Custom Form Password Authenticator

I'm trying to authenticating via the Custom Form Password Authenticator, I follow the Symfony Example at this page: Custom Form Password Authenticator, I changed a few snippet for put my authentication logic. All seem to work perfectly... But Symfony continued telling me that I'm authenticated as anonymous... Here is the code:
My Custom Athenticator:
class SippyAuthenticator implements SimpleFormAuthenticatorInterface
{
private $sippyAccounts;
public function __construct(SippyAccounts $sippyAccounts)
{
$this->sippyAccounts = $sippyAccounts;
}
public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
{
$result = $this->sippyAccounts->login($token->getUsername(), $token->getCredentials());
if($result->isError()) {
throw new CustomUserMessageAuthenticationException('Invalid username or password');
} else {
$roles = array('ROLE_ACCOUNT');
$user = new User($token->getUsername(), $token->getCredentials(), $roles);
$tokenNew = new UsernamePasswordToken( $user, $user->getPassword(), $providerKey, $user->getRoles());
return $tokenNew;
}
}
public function supportsToken(TokenInterface $token, $providerKey)
{
return $token instanceof UsernamePasswordToken
&& $token->getProviderKey() === $providerKey;
}
public function createToken(Request $request, $username, $password, $providerKey)
{
return new UsernamePasswordToken($username, $password, $providerKey);
}
}
This is my security.yml:
security:
providers:
in_memory:
memory: ~
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
simple_form:
authenticator: sippy.authenticator
login_path: login
check_path: login
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/es/overview, roles: ROLE_ACCOUNT }
The problem was that I was generating the User object without call the $userProvider (because I didn't implement it), and symfony later use this object ($userProvider) to retrive the already autenticated user and put it in the session... Below the UserProvider class and the modified SippyAuthenticator:
class SippyUserProvider implements UserProviderInterface
{
private $sippyAccounts;
public function __construct(SippyAccounts $sippyAccounts)
{
$this->sippyAccounts = $sippyAccounts;
}
public function loadUserByUsername($username)
{
$result = $this->sippyAccounts->informationByUsername($username);
if (!$result->isError()) {
$password = null;
return new SippyUser($username, $password, null, array('ROLE_ACCOUNT'));
}
throw new UsernameNotFoundException(
sprintf('Username "%s" does not exist.', $username)
);
}
public function refreshUser(UserInterface $user)
{
if (!$user instanceof SippyUser) {
throw new UnsupportedUserException(
sprintf('Instances of "%s" are not supported.', get_class($user))
);
}
return $this->loadUserByUsername($user->getUsername());
}
public function supportsClass($class)
{
return $class === 'AppBundle\Model\SippyUser';
}
}
class SippyAuthenticator implements SimpleFormAuthenticatorInterface
{
private $sippyAccounts;
public function __construct(SippyAccounts $sippyAccounts)
{
$this->sippyAccounts = $sippyAccounts;
}
public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
{
$result = $this->sippyAccounts->login($token->getUsername(), $token->getCredentials());
if($result->isError()) {
throw new CustomUserMessageAuthenticationException('Invalid username or password');
} else {
$user = $userProvider->loadUserByUsername($token->getUsername());
$tokenNew = new UsernamePasswordToken( $user, $user->getPassword(), $providerKey, $user->getRoles());
$tokenNew->setAttributes($token->getAttributes());
return $tokenNew;
}
}
public function supportsToken(TokenInterface $token, $providerKey)
{
return $token instanceof UsernamePasswordToken
&& $token->getProviderKey() === $providerKey;
}
public function createToken(Request $request, $username, $password, $providerKey)
{
return new UsernamePasswordToken($username, $password, $providerKey);
}
}
I hope this answer helpful to someone else...

doctrine 2 - The user provider must be an instance of WebserviceUserRepository

i wanted to create an Custom EntityRepository to load a User from the Database, so i followed http://symfony.com/doc/current/cookbook/security/entity_provider.html this tutorial.
Now i get a exception and i do not know why:
{"error":{"code":500,"message":"Internal Server Error","exception":[{"message":"The user provider must be an instance of WebserviceUserRepository (Symfony\\Bridge\\Doctrine\\Security\\User\\EntityUserProvider was given)."
If I remove extends EntityRepository from my WebserviceUser repo and also change security.ml and services.yml than the authentication works and the class is an instanceof WebserviceUserRepository.
I am using Symfony 2.7
I hope somebody can help me with that i am starting to pull my hair out ;-)
My Api Key Authenticator looks like that:
class ApiKeyAuthenticator implements SimplePreAuthenticatorInterface,
AuthenticationFailureHandlerInterface {
public function createToken(Request $request, $providerKey)
{
// look for an apikey query parameter
$apiKey = $request->query->get('apikey');
// or if you want to use an "apikey" header, then do something like this:
// $apiKey = $request->headers->get('apikey');
if (!$apiKey) {
throw new BadCredentialsException('No API key found');
// or to just skip api key authentication
//return null;
}
return new PreAuthenticatedToken(
'anon.',
$apiKey,
$providerKey
);
}
public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
{
**if (!$userProvider instanceof WebserviceUserRepository) {**
throw new \InvalidArgumentException(
sprintf(
'The user provider must be an instance of WebserviceUserRepository (%s was given).',
get_class($userProvider)
)
);
}
$apiKey = $token->getCredentials();
$username = $userProvider->getUsernameForApiKey($apiKey);
if (!$username) {
throw new AuthenticationException(
sprintf('API Key "%s" does not exist.', $apiKey)
);
}
$user = $userProvider->loadUserByUsername($username);
return new PreAuthenticatedToken(
$user,
$apiKey,
$providerKey,
$user->getRoles()
);
}
public function supportsToken(TokenInterface $token, $providerKey)
{
return $token instanceof PreAuthenticatedToken && $token->getProviderKey() === $providerKey;
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
return new Response("Authentication Failed.".$exception->getMessage(), 403);
}
this is my user repo:
class WebserviceUserRepository extends EntityRepository implements UserProviderInterface {
public function getUsernameForApiKey($apiKey)
{
// Look up the username based on the token in the database, via
// an API call, or do something entirely different
$username = 'username';
return $username;
}
public function loadUserByUsername($username)
{
// make a call to your webservice here
$userData = "";
// pretend it returns an array on success, false if there is no user
if (false) {
$password = 'password';
$salt = '';
$roles = array('roles' => 'ROLE_ADMIN');
return new WebserviceUser($username, $password, $salt, $roles);
}
throw new UsernameNotFoundException(
sprintf('Username "%s" does not exist.', $username)
);
}
public function refreshUser(UserInterface $user)
{
$class = get_class($user);
if (!$this->supportsClass($class)) {
throw new UnsupportedUserException(
sprintf(
'Instances of "%s" are not supported.',
$class
)
);
}
return $this->find($user->getUsername());
}
public function supportsClass($class)
{
return $this->getEntityName() === $class
|| is_subclass_of($class, $this->getEntityName());
}
}
i also added the repository class to my entity object:
* #ORM\Table()
* #ORM\Entity(repositoryClass="Moera\RestBundle\Entity\WebserviceUserRepository")
*/
class WebserviceUser implements UserInterface, \Serializable, EquatableInterface
and i also registered bot classes in security.yml and services.yml:
services:
webservice_user_provider:
class: Moera\RestBundle\Entity\WebserviceUserRepository
apikey_authenticator:
class: Moera\RestBundle\Security\ApiKeyAuthenticator
public: false
security:
encoders:
Moera\RestBundle\Entity\WebserviceUser:
algorithm: bcrypt
providers:
webservice_user_provider:
entity:
class: MoeraRestBundle:WebserviceUser
firewalls:
secured_area:
pattern: ^/
stateless: true
simple_preauth:
authenticator: apikey_authenticator
provider: webservice_user_provider
Thank You very much!
Kind Regards,
Johannes

Categories