英文:
AccessDeniedHttpException is throw instead of redirect Symfony 5
问题
I want to be redirected when the user do not have the admin role.
当用户没有管理员角色时,我希望被重定向。
I try to set access on every page that have /users in the url.
我尝试在URL中包含/users的每个页面上设置访问权限。
If the user is not connected the redirection is working but if I'm connected with ROLE_USER and I want to access /users page it's throw me an "Access Denied" Exception.
如果用户未连接,则重定向起作用,但如果我连接并且希望访问/users页面,它会抛出一个"拒绝访问"异常。
Packages/Security.yaml
包/Security.yaml
AppAuthenticator
AppAuthenticator
英文:
I want to be redirected when the user do not have the admin role. <br>
I try to set access on every page that have /users in the url. <br>
If the user is not connected the redirection is working but if I'm connected with ROLE_USER and I want to access /users page it's throw me an "Access Denied" Exception.
Packages/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:
app_user_provider:
entity:
class: App\Entity\User
property: username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
lazy: true
provider: app_user_provider
custom_authenticator: App\Security\AppAuthenticator
logout:
path: app_logout
# where to redirect after logout
# target: app_any_route
# 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: ^/users, roles: ROLE_ADMIN }
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
AppAuthenticator
enter code here <?php
namespace App\Security;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;
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\Util\TargetPathTrait;
class AppAuthenticator extends AbstractLoginFormAuthenticator
{
use TargetPathTrait;
public const LOGIN_ROUTE = 'app_login';
public function __construct(private UrlGeneratorInterface $urlGenerator)
{
}
public function authenticate(Request $request): Passport
{
$username = $request->request->get('username', '');
$request->getSession()->set(Security::LAST_USERNAME, $username);
return new Passport(
new UserBadge($username),
new PasswordCredentials($request->request->get('password', '')),
[
new CsrfTokenBadge('authenticate', $request->request->get('_csrf_token')),
]
);
}
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('homepage'));
}
protected function getLoginUrl(Request $request): string
{
return $this->urlGenerator->generate(self::LOGIN_ROUTE);
}
}
答案1
得分: 0
I found my way there : <br> https://symfony.com/doc/5.4/security/access_denied_handler.html#customize-the-forbidden-response <br>
I created
<?php
// src/Security/AccessDeniedHandler.php
namespace App\Security;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface;
class AccessDeniedHandler implements AccessDeniedHandlerInterface
{
private $urlGenerator;
public function __construct(UrlGeneratorInterface $urlGenerator)
{
$this->urlGenerator = $urlGenerator;
}
public function handle(Request $request, AccessDeniedException $accessDeniedException): ?Response
{
return new RedirectResponse($this->urlGenerator->generate('app_login'));
}
}
then added this in my security.yaml
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
lazy: true
provider: app_user_provider
custom_authenticator: App\Security\AppAuthenticator
access_denied_handler: App\Security\AccessDeniedHandler
英文:
I found my way there : <br> https://symfony.com/doc/5.4/security/access_denied_handler.html#customize-the-forbidden-response <br>
I created
<?php
// src/Security/AccessDeniedHandler.php
namespace App\Security;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface;
class AccessDeniedHandler implements AccessDeniedHandlerInterface
{
private $urlGenerator;
public function __construct(UrlGeneratorInterface $urlGenerator)
{
$this->urlGenerator = $urlGenerator;
}
public function handle(Request $request, AccessDeniedException $accessDeniedException): ?Response
{
return new RedirectResponse($this->urlGenerator->generate('app_login'));
}
}
then added this in my security.yaml
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
lazy: true
provider: app_user_provider
custom_authenticator: App\Security\AppAuthenticator
access_denied_handler: App\Security\AccessDeniedHandler
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论