Add json token login
This commit is contained in:
1
.env
1
.env
@@ -2,6 +2,7 @@ APP_ENV=prod
|
||||
DEFAULT_LOCALE=en
|
||||
APP_SECRET=CHANGEME
|
||||
TZ=America/New_York
|
||||
LOGIN_JSON_AES_KEY=
|
||||
###> symfony/lock ###
|
||||
# Choose one of the stores below
|
||||
# postgresql+advisory://db_user:db_password@localhost/db_name
|
||||
|
||||
15
README.md
15
README.md
@@ -101,6 +101,21 @@ This is a web panel to allow roleplay server to have an common interface for all
|
||||
php bin/console cache:clear
|
||||
```
|
||||
|
||||
## Login with json token
|
||||
|
||||
|
||||
you need to encode a json string like this :
|
||||
```php
|
||||
openssl_encrypt('{"email":"test@test.fr"}', 'aes-256-cbc', 'LOGIN_JSON_AES_KEY', 0)
|
||||
```
|
||||
and then use the token with url :
|
||||
|
||||
/login/json?token=YOUR_ENCRYPTED_TOKEN_HERE
|
||||
|
||||
If the email exist on user list, the user is connected, if not, and error page is displayed
|
||||
|
||||
You need to setup the decryption key by env : LOGIN_JSON_AES_KEY
|
||||
|
||||
## Scalability
|
||||
|
||||
Vision is ready to be used in scaled architecture :
|
||||
|
||||
@@ -20,7 +20,9 @@ security:
|
||||
lazy: true
|
||||
provider: app_user_provider
|
||||
switch_user: { role: ROLE_ADMIN, parameter: _want_to_be_this_user }
|
||||
custom_authenticator: App\Security\FormAuthenticator
|
||||
custom_authenticator:
|
||||
- App\Security\FormAuthenticator
|
||||
- App\Security\JsonAesAuthenticator
|
||||
user_checker: App\Security\UserChecker
|
||||
login_throttling:
|
||||
max_attempts: 3
|
||||
|
||||
@@ -138,4 +138,15 @@ class SecurityController extends AbstractController
|
||||
{
|
||||
throw new \LogicException('Something goes wrong if you see this');
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/login/json", name="app_login_json")
|
||||
*/
|
||||
public function loginJson()
|
||||
{
|
||||
|
||||
return $this->render(
|
||||
'security/json.html.twig'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
71
src/Security/JsonAesAuthenticator.php
Normal file
71
src/Security/JsonAesAuthenticator.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Security;
|
||||
|
||||
use App\Repository\UserRepository;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\Security\Http\Util\TargetPathTrait;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
|
||||
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
|
||||
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
|
||||
|
||||
class JsonAesAuthenticator extends AbstractAuthenticator
|
||||
{
|
||||
use TargetPathTrait;
|
||||
|
||||
private UserRepository $userRepository;
|
||||
private UrlGeneratorInterface $urlGenerator;
|
||||
|
||||
public function __construct(UrlGeneratorInterface $urlGenerator, UserRepository $userRepository)
|
||||
{
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
$this->userRepository = $userRepository;
|
||||
}
|
||||
|
||||
|
||||
public function supports(Request $request): ?bool
|
||||
{
|
||||
return ($request->attributes->get('_route') == 'app_login_json')
|
||||
&& $request->query->has('token')
|
||||
&& null != $_ENV['LOGIN_JSON_AES_KEY']
|
||||
&& !empty($_ENV['LOGIN_JSON_AES_KEY']);
|
||||
}
|
||||
|
||||
public function authenticate(Request $request): Passport
|
||||
{
|
||||
|
||||
$apiToken = $request->query->get('token');
|
||||
if (null === $apiToken) {
|
||||
throw new AccessDeniedHttpException('No API token provided');
|
||||
}
|
||||
|
||||
$tokenDecoded = openssl_decrypt($apiToken, 'aes-256-cbc', $_ENV['LOGIN_JSON_AES_KEY'], 0);
|
||||
$tokenInfos = json_decode($tokenDecoded);
|
||||
|
||||
return new SelfValidatingPassport(new UserBadge($tokenInfos->email, function (string $userIdentifier) {
|
||||
return $this->userRepository->findOneBy(['email' => $userIdentifier]);
|
||||
}));
|
||||
}
|
||||
|
||||
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
|
||||
{
|
||||
|
||||
if ($targetPath = $this->getTargetPath($request->getSession(), $firewallName)) {
|
||||
return new RedirectResponse($targetPath);
|
||||
}
|
||||
|
||||
return new RedirectResponse($this->urlGenerator->generate('home'));
|
||||
}
|
||||
|
||||
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
|
||||
{
|
||||
return new RedirectResponse($this->urlGenerator->generate('app_login_json'));
|
||||
}
|
||||
}
|
||||
29
templates/security/json.html.twig
Normal file
29
templates/security/json.html.twig
Normal file
@@ -0,0 +1,29 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}{% trans %}title_login{% endtrans %}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
<!-- [ auth-signin ] start -->
|
||||
<div class="auth-wrapper">
|
||||
<div class="auth-content">
|
||||
<div class="card">
|
||||
<div class="row align-items-center text-center">
|
||||
<div class="col-md-12">
|
||||
<div class="card-body">
|
||||
<img src="{{ asset('img/vision_long_2100x250.svg') }}" alt="" class="img-fluid mb-4">
|
||||
<h4 class="mb-3 f-w-400">{% trans %}title_login{% endtrans %}</h4>
|
||||
|
||||
<p>{% trans %}text_login_json_fail{% endtrans %}</p>
|
||||
|
||||
<p class="mb-0 text-muted">{% trans %}no_account{% endtrans %} ? <a href="{{ path('app_register') }}" class="f-w-400">{% trans %}button_register{% endtrans %}</a></p>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- [ auth-signin ] end -->
|
||||
{% endblock %}
|
||||
@@ -619,6 +619,7 @@ subtitle_administration_watchdog: View entities modifications
|
||||
subtitle_administration: The BOSS
|
||||
subtitle_home: Homepage
|
||||
subtitle_management: Administration of your group
|
||||
text_login_json_fail: Automatic login failed, contact your administrator
|
||||
text_reset_password_explanation: If an account is linked to this address, you will receive an email with a reset link
|
||||
title_accessorySentence: Accessory penalty
|
||||
title_actions: Actions
|
||||
|
||||
@@ -618,6 +618,7 @@ subtitle_administration_watchdog: Voir les modifications des entités
|
||||
subtitle_administration: Les BOSS
|
||||
subtitle_home: Accueil
|
||||
subtitle_management: Gestion de votre groupe
|
||||
text_login_json_fail: La connexion automatique à échouée, merci de contacter l'équipe technique
|
||||
text_reset_password_explanation: Si un compte est lié à cette adresse, vous allez recevoir un email avec un lien de réinitialisation
|
||||
title_accessorySentence: Peine Accessoire
|
||||
title_actions: Actions
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"version": "0.2.18"
|
||||
"version": "0.2.19"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user