Add json token login

This commit is contained in:
Xbird
2022-10-31 15:43:57 +00:00
parent 85fe815ed9
commit a4c3db0f4e
9 changed files with 133 additions and 2 deletions

1
.env
View File

@@ -2,6 +2,7 @@ APP_ENV=prod
DEFAULT_LOCALE=en DEFAULT_LOCALE=en
APP_SECRET=CHANGEME APP_SECRET=CHANGEME
TZ=America/New_York TZ=America/New_York
LOGIN_JSON_AES_KEY=
###> symfony/lock ### ###> symfony/lock ###
# Choose one of the stores below # Choose one of the stores below
# postgresql+advisory://db_user:db_password@localhost/db_name # postgresql+advisory://db_user:db_password@localhost/db_name

View File

@@ -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 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 ## Scalability
Vision is ready to be used in scaled architecture : Vision is ready to be used in scaled architecture :

View File

@@ -20,7 +20,9 @@ security:
lazy: true lazy: true
provider: app_user_provider provider: app_user_provider
switch_user: { role: ROLE_ADMIN, parameter: _want_to_be_this_user } 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 user_checker: App\Security\UserChecker
login_throttling: login_throttling:
max_attempts: 3 max_attempts: 3

View File

@@ -138,4 +138,15 @@ class SecurityController extends AbstractController
{ {
throw new \LogicException('Something goes wrong if you see this'); 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'
);
}
} }

View 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'));
}
}

View 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 %}

View File

@@ -619,6 +619,7 @@ subtitle_administration_watchdog: View entities modifications
subtitle_administration: The BOSS subtitle_administration: The BOSS
subtitle_home: Homepage subtitle_home: Homepage
subtitle_management: Administration of your group 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 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_accessorySentence: Accessory penalty
title_actions: Actions title_actions: Actions

View File

@@ -618,6 +618,7 @@ subtitle_administration_watchdog: Voir les modifications des entités
subtitle_administration: Les BOSS subtitle_administration: Les BOSS
subtitle_home: Accueil subtitle_home: Accueil
subtitle_management: Gestion de votre groupe 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 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_accessorySentence: Peine Accessoire
title_actions: Actions title_actions: Actions

View File

@@ -1,3 +1,3 @@
{ {
"version": "0.2.18" "version": "0.2.19"
} }