default_target_path如何在Silex防火墙中工作


How does the default_target_path work in a Silex Firewall?

我在Silex中设置了一个防火墙,如下所示:

$this -> register(new SecurityServiceProvider(), array(
    'security.firewalls' => array(
        'login' => array(
            'pattern' => '^/admin/login$'
        ),
        'admin' => array(
            'pattern' => '^/admin.*$',
            'form' => array(
                'login_path' => '/admin/login',
                'check_path' => '/admin/security/validate',
                'default_target_path' => "/admin",
                'always_use_default_target_path' => true
            ),
            'logout' => array(
                'logout_path' => '/admin/security/logout'
            ),
            'users' => $app -> share(function () use ($app) {
                return new 'Turtle'Providers'UserProvider($app);
            })
        )
    ),
    'security.access_rules' => array(
        array('^/admin.*$', 'ROLE_ADMIN')
    )
));

这是因为当我在"管理"区域点击一个页面时,我会被重定向到我的登录页面。然而,我已经开始在我的自定义AuthenticationSuccess处理程序中进行一些授权。我想使用内置的方法determineTargeUrl在成功时重定向,但它一直重定向到"/"。

经过一些调试,我发现该方法使用的对象中的选项如下:

array (size=5)
  'always_use_default_target_path' => boolean false
  'default_target_path' => string '/' (length=1)
  'login_path' => string '/login' (length=6)
  'target_path_parameter' => string '_target_path' (length=12)
  'use_referer' => boolean false

很明显,这不是我在防火墙中设置的。我的理解是,这应该与我访问系统时使用的防火墙中的内容相匹配。我使用的URL是'http://localhost/admin"。

那么,我如何使我在防火墙中设置的选项显示在对象中,以便我可以使用determineTargetUrl呢?

非常感谢,Russell

您的问题似乎是登录路由在您的安全区域内。您已将访问规则定义为^/admin.*$。这意味着任何以/admin开始的路由都需要ROLE_ADMIN,包括您的登录路由。要解决此问题,您需要从登录路由中删除安全性。

在管理规则之上添加一个新的访问规则。

'security.access_rules' => array(
    array('^/admin/login$', 'IS_AUTHENTICATED_ANONYMOUSLY'),
    array('^/admin.*$', 'ROLE_ADMIN')
)

编辑:再读一遍你的问题后,我可能误解了你。听起来你可以成功登录,但在成功登录后会被重定向到错误的地方。这是正确的吗?如果是这样,我将删除这个答案。

这是我的错误。我使用自定义AuthenticationSuccess和AuthenticationFailure处理程序,在声明它们时,我忽略了将任何选项传递给它们:

    $app['security.authentication.success_handler.admin'] = $app -> share(function() use ($app) {
        return new AuthenticationSuccessHandler($app['security.http_utils'], array(), $app);
    });
    $app['security.authentication.failure_handler.admin'] = $app -> share(function() use ($app) {
        return new AuthenticationFailureHandler($app['kernel'], $app['security.http_utils'], array(), $app);
    });

因此,身份验证成功时determineTargetUrl中使用的选项数组为空,因此具有默认值。

通过向AuthenticationSuccessHandler添加一组选项,它就可以工作了。这是可以的,因为每个自定义处理程序都链接到不同的防火墙。