default_target_path如何在Silex防火墙中运行?

I have setup a firewall in Silex as follows:

$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')
    )
));

This works in that when I hit a page in the 'admin' area I get redirected to my login page. However I have started to do some authorization in my custom AuththenticationSuccess handler. I want to use the built in method determineTargeUrl to redirect on success but it keeps redirecting to '/'.

After some debugging I have found that the options in the object that the method uses has the following:

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

Clearly this is not what I have set in my firewall. It is my understanding that this should match what it is in the firewall that I have used when accessing the system. The URL I used was 'http://localhost/admin'.

So how do I make it so that the options I have set in my firewall appear in the object so that I can use the determineTargetUrl?

Thanks lots, Russell

It looks like your problem is that your login route is inside your secured area. You've defined your access rule as ^/admin.*$. This means that any route starting with /admin requires ROLE_ADMIN including your login route. To fix this you need to remove security from your login route.

Add a new access rule above your admin rule.

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

Edit: After reading your question again, I may have misunderstood you. it sounds like you can successfully log in but are redirected to the wrong place after a successful login. Is that correct? If so I will remove this answer.

This was my mistake. I am using custom AuthenticationSuccess and AuthenticationFailure handlers and i neglected to pass any options into them when I was declaring them:

    $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);
    });

So the options array that is used in determineTargetUrl on authentication success was empty and thus had default values.

By adding an array of options to the AuthenticationSuccessHandler it works. This is OK as each custom handler is linked to a different firewall.