简体   繁体   English

Symfony2防火墙:重定向到注册表单而不是登录

[英]Symfony2 Firewall: Redirect to registration form instead of login

I am working on a simple shop (to compile offers) based on Symfony2. 我正在开发一个基于Symfony2的简单商店(编译商品)。

After adding items to his cart, a user can proceed to a summary of his offer and then request the compiled offer. 在将商品添加到购物车后,用户可以继续查看其商品摘要,然后请求编辑的商品。

The summary page is protected by the following firewall: 摘要页面受以下防火墙保护:

security:
firewalls:
    secured_area:
        pattern: ^/
        anonymous: ~
        provider: default
        form_login:
            login_path: acme_security_login_route
            check_path: acme_security_login_check_route
            csrf_provider: form.csrf_provider
        logout: ~

    default:
        anonymous: ~

access_control:
    - { path: ^/request-offer, roles: ROLE_CLIENT }

providers:
    default:
        entity: { class: AcmeShopBundle:User }

encoders:
    Symfony\Component\Security\Core\User\User: plaintext
    Acme\ShopBundle\Entity\User:
        algorithm: bcrypt
        cost:      15

This means that if the client is logged in, he will directly get to the summary, and if not, he is redirected to the login page. 这意味着如果客户端已登录,他将直接进入摘要,如果没有,则会被重定向到登录页面。

Now as it is more probable for the client to be a new customer I would like to redirect to the registration form, instead. 现在,由于客户更有可能成为新客户,我希望将其重定向到注册表单。

The options described in the SecurityBundle Configuration Reference don't allow this. SecurityBundle配置参考中描述的选项不允许这样做。 Of course changing the login_path is also not a solution. 当然,更改login_path也不是解决方案。

What would be the nicest possible solution for that? 那个最好的解决方案是什么?

In my opinion a nice solution is to add an own AccessDeniedExceptionHandler, how to do this is explained here. 在我看来一个很好的解决方案是添加一个自己的AccessDeniedExceptionHandler,这里解释如何做到这一点。

Using Symfony2's AccessDeniedHandlerInterface 使用Symfony2的AccessDeniedHandlerInterface

Further more, you could made the service configurable via the Configuration Component, so that you pass as argument the route to redirect. 此外,您可以通过配置组件使服务可配置,以便将路由作为参数传递给重定向。

http://symfony.com/doc/current/components/config/definition.html http://symfony.com/doc/current/components/config/definition.html

If you do this you can change, if you got more users, to redirect back to login page without editing any class. 如果您这样做,您可以更改,如果您有更多用户,重定向回登录页面而不编辑任何类。

Nextar's answer lead me to the solution. Nextar的回答引导我找到解决方案。

Quoting this question : 引用这个问题

the service pointed by access_denied_handler is only called if the user has unsufficient privilege to access the resource. 只有在用户具有访问资源的权限不足时,才会调用access_denied_handler指向的服务。 If the user is not authenticated at all access_dened_handler is never called. 如果用户未经过身份验证,则永远不会调用access_dened_handler。 Providing a service to entry_point in security.yml did actually solve the problem 在security.yml中为entry_point提供服务确实解决了这个问题

So I ended up with this: 所以我最终得到了这个:

#services.yml
acme.security.entry_point.class: ArtCube\ShopBundle\Service\EntryPointHandler

services:
    acme.security.entry_point_handler:
        class: %acme.security.entry_point.class%
        arguments:
            router:      @router

Then I added this service to my security.yml , right after logout: ~ line (see initial question): 然后我在logout: ~后立即将此服务添加到我的security.yml logout: ~ line(参见初始问题):

entry_point: art_cube_shop.security.entry_point_handler

And created the service: 并创建了服务:

// Acme/ShopBundle/Service/EntryPointHandler.php

use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Router;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Exception\InsufficientAuthenticationException;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;

class EntryPointHandler implements AuthenticationEntryPointInterface {

    protected $router;

    public function __construct(Router $router)
    {
        $this->router = $router;
    }

    public function start(Request $request, AuthenticationException $authException = null)
    {
        if($authException instanceof InsufficientAuthenticationException)
        {
            return new RedirectResponse($this->router->generate('acme_security_registration_route'));
        } 
        else
        {
            return new RedirectResponse($this->router->generate('acme_security_login_route'));
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM