<?php
namespace App\Security;
use App\Entity\Kernel\User; // your user entity
use Doctrine\ORM\EntityManagerInterface;
use KnpU\OAuth2ClientBundle\Security\Authenticator\SocialAuthenticator;
use KnpU\OAuth2ClientBundle\Client\Provider\AzureClient;
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\RouterInterface;
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\HttpFoundation\RedirectResponse;
use App\Service\Kernel\UserService;
use App\Service\Kernel\KernelService;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class MyAzureAuthenticator extends SocialAuthenticator
{
private $clientRegistry;
private $em;
private $router;
private $userService;
private $kernelService;
private $session;
private $translator;
public function __construct(ClientRegistry $clientRegistry, EntityManagerInterface $em, RouterInterface $router, UserService $userService, KernelService $kernelService, SessionInterface $session, TranslatorInterface $translator)
{
$this->clientRegistry = $clientRegistry;
$this->em = $em;
$this->router = $router;
$this->userService = $userService;
$this->kernelService = $kernelService;
$this->session = $session;
$this->translator = $translator;
}
public function supports(Request $request)
{
// continue ONLY if the current ROUTE matches the check ROUTE
return $request->attributes->get('_route') === 'connect_azure_check';
}
public function getCredentials(Request $request)
{
// this method is only called if supports() returns true
// For Symfony lower than 3.4 the supports method need to be called manually here:
// if (!$this->supports($request)) {
// return null;
// }
return $this->fetchAccessToken($this->getAzureClient());
}
public function getUser($credentials, UserProviderInterface $userProvider)
{
/** @var FacebookUser $facebookUser */
$azureUser = $this->getAzureClient()
->fetchUserFromToken($credentials);
//$email = $azureUser->getEmail();
// 1) have they logged in with Facebook before? Easy!
$existingUser = $this->em->getRepository(User::class)
->findOneBy(['uuid' => $azureUser->getId()]);
if ($existingUser) {
return $existingUser;
}
// 2) do we have a matching user by email?
//$user = $this->em->getRepository(User::class)
// ->findOneBy(['email' => $email]);
// 3) Maybe you just want to "register" them by creating
// a User object
/*$user = new User();
$user->setUuid($azureUser->getId());
$user->setEmail($azureUser->toArray()['upn']);
$user->setFirstName($azureUser->getFirstName());
$user->setLastName($azureUser->getLastName());
$user->setPassword("?E(H+MbQeThWmZq4t7w!zPP&F)J@NcRf");
$this->em->persist($user);
$this->em->flush();*/
$defaultorg = $this->kernelService->getApplicationInfoValue("Kernel.Defaultorganization");
$defaulttimezone = $this->kernelService->getApplicationInfoValue("Kernel.Defaulttimezone");
$user = $this->userService->CreateUser($azureUser->getId(), $azureUser->toArray()['upn'], $azureUser->getFirstName(), $azureUser->getLastName(), "?E(H+MbQeThWmZq4t7w!zPP&F)J@NcRf",
"", "en-US", $defaulttimezone, null, $defaultorg,1);
return $user;
}
/**
* @return AzureClient
*/
private function getAzureClient()
{
return $this->clientRegistry
// "facebook_main" is the key used in config/packages/knpu_oauth2_client.yaml
->getClient('azure');
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
$user = $token->getUser();
if ($this->userService->CanLogin($user) == true)
{
$this->userService->Login($user);
$targetUrl = $this->router->generate('app_home', ['_locale' => "".$user->getLocale()]);
}
else
{
$token->setAuthenticated(false);
$this->session->set('error', $this->translator->trans("User.NotAllowedToLogin", [], 'messages', "en-US"));
$targetUrl = $this->router->generate('app_logout');
}
// change "app_homepage" to some route in your app
return new RedirectResponse($targetUrl);
// or, on success, let the request continue to be handled by the controller
//return null;
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
$message = strtr($exception->getMessageKey(), $exception->getMessageData());
return new Response($message, Response::HTTP_FORBIDDEN);
}
/**
* Called when authentication is needed, but it's not sent.
* This redirects to the 'login'.
*/
public function start(Request $request, AuthenticationException $authException = null)
{
return new RedirectResponse(
'/connect/azure/', // might be the site, where users choose their oauth provider
Response::HTTP_TEMPORARY_REDIRECT
);
}
// ...
}