AccessDeniedHttpException 是在 Symfony 5 中抛出而不是重定向。

huangapple go评论49阅读模式
英文:

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: &#39;auto&#39;
    # 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    &lt;?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 = &#39;app_login&#39;;

    public function __construct(private UrlGeneratorInterface $urlGenerator)
    {
    }

    public function authenticate(Request $request): Passport
    {
        $username = $request-&gt;request-&gt;get(&#39;username&#39;, &#39;&#39;);

        $request-&gt;getSession()-&gt;set(Security::LAST_USERNAME, $username);

        return new Passport(
            new UserBadge($username),
            new PasswordCredentials($request-&gt;request-&gt;get(&#39;password&#39;, &#39;&#39;)),
            [
                new CsrfTokenBadge(&#39;authenticate&#39;, $request-&gt;request-&gt;get(&#39;_csrf_token&#39;)),
            ]
        );
    }

    public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
    {
        if ($targetPath = $this-&gt;getTargetPath($request-&gt;getSession(), $firewallName)) {
            return new RedirectResponse($targetPath);
        }

        return new RedirectResponse($this-&gt;urlGenerator-&gt;generate(&#39;homepage&#39;));
    }

    protected function getLoginUrl(Request $request): string
    {
        return $this-&gt;urlGenerator-&gt;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-&gt;urlGenerator = $urlGenerator;
}

public function handle(Request $request, AccessDeniedException $accessDeniedException): ?Response
{
    return new RedirectResponse($this-&gt;urlGenerator-&gt;generate(&#39;app_login&#39;));
}

}
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

    &lt;?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-&gt;urlGenerator = $urlGenerator;
    }

    public function handle(Request $request, AccessDeniedException $accessDeniedException): ?Response
    {
        return new RedirectResponse($this-&gt;urlGenerator-&gt;generate(&#39;app_login&#39;));
    }
}

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

huangapple
  • 本文由 发表于 2023年6月6日 01:29:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76408749.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定