add security
This commit is contained in:
parent
95e7df1a9b
commit
69930ac3d6
5
.env
5
.env
@ -17,3 +17,8 @@ DATABASE_URL="postgresql://${DB_USER:-db}:${DB_PW:-db}@${DB_HOST:-db}:${DB_PORT:
|
|||||||
STRIPE_PUBLIC_KEY=${STRIPE_PUBLIC_KEY}
|
STRIPE_PUBLIC_KEY=${STRIPE_PUBLIC_KEY}
|
||||||
STRIPE_SECRET_KEY=${STRIPE_PUBLIC_KEY}
|
STRIPE_SECRET_KEY=${STRIPE_PUBLIC_KEY}
|
||||||
###
|
###
|
||||||
|
|
||||||
|
### ADMIN PANEL
|
||||||
|
USER_PASSWORD=${USER_PASSWORD}
|
||||||
|
ADMIN_PASSWORD=${ADMIN_PASSWORD}
|
||||||
|
###
|
4
.env.dev
4
.env.dev
@ -1,4 +1,6 @@
|
|||||||
|
|
||||||
###> symfony/framework-bundle ###
|
###> symfony/framework-bundle ###
|
||||||
APP_SECRET=5a866a6ab3ce4ef99240ba643868b123
|
APP_SECRET=5a866a6ab3ce4ef99240ba643868b123
|
||||||
###< symfony/framework-bundle ###
|
###< symfony/framework-bundle ###
|
||||||
|
|
||||||
|
USER_PASSWORD=\$2y\$13\$z/XlUykvakLzDR8TeFrQk.jmGuOKOcULlMY/m17aWmkY4f4NrIaam
|
||||||
|
ADMIN_PASSWORD=\$2y\$13\$z/XlUykvakLzDR8TeFrQk.jmGuOKOcULlMY/m17aWmkY4f4NrIaam
|
@ -7,8 +7,8 @@ security:
|
|||||||
users_in_memory:
|
users_in_memory:
|
||||||
memory:
|
memory:
|
||||||
users:
|
users:
|
||||||
user: { password: '123', roles: ['ROLE_ADMIN'] }
|
user: { password: '%env(USER_PASSWORD)%', roles: ['ROLE_ADMIN'] }
|
||||||
admin: { password: '123', roles: ['ROLE_SUPER_ADMIN'] }
|
admin: { password: '%env(ADMIN_PASSWORD)%', roles: ['ROLE_SUPER_ADMIN'] }
|
||||||
|
|
||||||
firewalls:
|
firewalls:
|
||||||
dev:
|
dev:
|
||||||
@ -20,7 +20,10 @@ security:
|
|||||||
custom_authenticator: App\Security\AdminPanelAuthenticator
|
custom_authenticator: App\Security\AdminPanelAuthenticator
|
||||||
form_login:
|
form_login:
|
||||||
login_path: /admin/login
|
login_path: /admin/login
|
||||||
|
check_path: /admin/login
|
||||||
|
logout:
|
||||||
|
path: /admin/logout
|
||||||
|
target: /admin/login
|
||||||
# activate different ways to authenticate
|
# activate different ways to authenticate
|
||||||
# https://symfony.com/doc/current/security.html#the-firewall
|
# https://symfony.com/doc/current/security.html#the-firewall
|
||||||
|
|
||||||
@ -29,6 +32,10 @@ security:
|
|||||||
|
|
||||||
# Easy way to control access for large sections of your site
|
# Easy way to control access for large sections of your site
|
||||||
# Note: Only the *first* access control that matches will be used
|
# Note: Only the *first* access control that matches will be used
|
||||||
|
|
||||||
|
role_hierarchy:
|
||||||
|
ROLE_SUPER_ADMIN: ROLE_ADMIN
|
||||||
|
|
||||||
access_control:
|
access_control:
|
||||||
- { path: ^/admin/login, roles: PUBLIC_ACCESS }
|
- { path: ^/admin/login, roles: PUBLIC_ACCESS }
|
||||||
- { path: ^/admin, roles: ROLE_ADMIN }
|
- { path: ^/admin, roles: ROLE_ADMIN }
|
||||||
|
@ -7,12 +7,16 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Routing\Attribute\Route;
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
|
||||||
|
|
||||||
class SecurityController extends AbstractController
|
class SecurityController extends AbstractController
|
||||||
{
|
{
|
||||||
#[Route(path: '/admin/login', name: 'admin_login', methods: Request::METHOD_GET)]
|
#[Route(path: '/admin/login', name: 'admin_login', methods: [Request::METHOD_GET, Request::METHOD_POST])]
|
||||||
public function login(): Response
|
public function login(AuthenticationUtils $authenticationUtils): Response
|
||||||
{
|
{
|
||||||
return $this->render('admin/login.html.twig');
|
return $this->render('admin/login.html.twig', [
|
||||||
|
'last_username' => $authenticationUtils->getLastUsername(),
|
||||||
|
'error' => $authenticationUtils->getLastAuthenticationError(),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
23
src/DataObjects/LoginData.php
Normal file
23
src/DataObjects/LoginData.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\DataObjects;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
|
class LoginData
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ?string $username = '',
|
||||||
|
public ?string $password = ''
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function fromRequest(Request $request): self
|
||||||
|
{
|
||||||
|
return new self(
|
||||||
|
$request->get('_username'),
|
||||||
|
$request->get('_password'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -2,29 +2,41 @@
|
|||||||
|
|
||||||
namespace App\Security;
|
namespace App\Security;
|
||||||
|
|
||||||
|
use App\DataObjects\LoginData;
|
||||||
|
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||||
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||||
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
|
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
|
||||||
use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
|
use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
|
||||||
|
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\RememberMeBadge;
|
||||||
|
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
|
||||||
|
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
|
||||||
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
|
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
|
||||||
|
|
||||||
class AdminPanelAuthenticator extends AbstractAuthenticator
|
class AdminPanelAuthenticator extends AbstractAuthenticator
|
||||||
{
|
{
|
||||||
public function supports(Request $request): ?bool
|
public function supports(Request $request): ?bool
|
||||||
{
|
{
|
||||||
return str_starts_with($request->getRequestUri(), '/admin');
|
return str_starts_with($request->getRequestUri(), '/admin') && $request->isMethod(Request::METHOD_POST);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function authenticate(Request $request): Passport
|
public function authenticate(Request $request): Passport
|
||||||
{
|
{
|
||||||
|
$data = LoginData::fromRequest($request);
|
||||||
|
|
||||||
|
if ($request->isMethod(Request::METHOD_POST) && (!$data->password || !$data->username)) {
|
||||||
|
dd($data);
|
||||||
throw new CustomUserMessageAuthenticationException();
|
throw new CustomUserMessageAuthenticationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return new Passport(new UserBadge($data->username), new PasswordCredentials($data->password), [new RememberMeBadge()]);
|
||||||
|
}
|
||||||
|
|
||||||
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
|
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
|
||||||
{
|
{
|
||||||
return null;
|
return new RedirectResponse('/admin');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
|
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
|
||||||
|
@ -4,10 +4,14 @@
|
|||||||
<div class="min-h-screen flex items-center justify-center bg-[#0a0a0a] px-4 sm:px-6 lg:px-8">
|
<div class="min-h-screen flex items-center justify-center bg-[#0a0a0a] px-4 sm:px-6 lg:px-8">
|
||||||
<div class="w-full max-w-[90%] sm:max-w-md">
|
<div class="w-full max-w-[90%] sm:max-w-md">
|
||||||
<div class="text-center mb-8">
|
<div class="text-center mb-8">
|
||||||
<h2 class="text-xl sm:text-2xl font-medium text-gray-200">Administration</h2>
|
<h2 class="text-xl sm:text-2xl font-medium text-gray-200">Abiball Admin Panel</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form method="post" class="space-y-4 sm:space-y-6">
|
{% if error %}
|
||||||
|
{{ error.message }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<form method="post" class="space-y-4 sm:space-y-6" action="{{ path('admin_login') }}">
|
||||||
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}" />
|
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}" />
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
@ -21,7 +25,7 @@
|
|||||||
name="_username"
|
name="_username"
|
||||||
required
|
required
|
||||||
class="block w-full pl-9 sm:pl-10 py-2 sm:py-2.5 text-sm sm:text-base bg-[#2a2a2a] border border-[#333333] text-gray-200 rounded-md focus:ring-2 focus:ring-orange-500/20 focus:border-orange-500 transition-colors"
|
class="block w-full pl-9 sm:pl-10 py-2 sm:py-2.5 text-sm sm:text-base bg-[#2a2a2a] border border-[#333333] text-gray-200 rounded-md focus:ring-2 focus:ring-orange-500/20 focus:border-orange-500 transition-colors"
|
||||||
placeholder="admin@example.com" />
|
placeholder="username" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -40,15 +44,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center">
|
<hr>
|
||||||
<input type="checkbox"
|
|
||||||
id="remember_me"
|
|
||||||
name="_remember_me"
|
|
||||||
class="h-3.5 w-3.5 sm:h-4 sm:w-4 bg-[#2a2a2a] border-[#333333] rounded text-orange-500 focus:ring-orange-500/20" />
|
|
||||||
<label for="remember_me" class="ml-2 block text-xs sm:text-sm text-gray-300">
|
|
||||||
Angemeldet bleiben
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<button type="submit"
|
<button type="submit"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user