如何更改Silex中的安全重定向行为?

时间:2015-04-05 04:42:06

标签: php symfony silex

如果我向安全区域发出AJAX请求,它会发送302标头,然后重定向到该请求中的登录页面。有没有办法将防火墙配置为只提供不同的标头而不是重定向?这是我需要在->before电话中处理的事情吗?或者更好的方法是覆盖身份验证入口点,如Symfony security return 401 response instead of redirect中所述?那是Symfony所以不确定Silex是否有更好的糖。

尝试过这个和其他事情:

$app->register(new SecurityServiceProvider(), array(
    'security.firewalls' => array(
        'default' => array(
            'pattern' => '^/',
            'anonymous' => true,
            'oauth' => array(
                'failure_path' => '/login',
                'with_csrf' => true
            ),
            'logout' => array(
                'logout_path' => '/logout',
                'with_csrf' => true
            ),

        )
    ),

));

$app['security.authentication.entry_point.default.oauth'] = $app->share(function ($app) {
    return new AuthenticationEntryPointComponent();
});

$app['security.authentication.entry_point.default.form'] = $app->share(function ($app) {
    return new AuthenticationEntryPointComponent();
});

defaultsecurity.firewalls中密钥的名称。仍然得到302。

2 个答案:

答案 0 :(得分:1)

我不得不挖掘这么多代码,但得到了它:

我的控制器:

$app['security.entry_point.form._proto'] =$app->protect(function ($name, array $options) use ($app) {
  return $app->share(function () use ($app, $options) {
      $login_path = isset($options['login_path']) ? $options['login_path'] : '/login';
      return new MyCustomClass($app['security.http_utils'], $login_path);
  });
});

班级:

namespace Yours;

use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class MyCustomClass implements AuthenticationEntryPointInterface {

  protected $_login_path = '/login';

  protected $_http_tools;

  /**
   * @param string $loginPath  The path to the login form
   */
  public function __construct(HttpUtils $http_utils, $login_path = '') {
    $this->_http_tools = $http_utils;

    if ( $login_path ) {
      $this->_login_path = $login_path;
    }
  }

  /**
   * {@inheritDoc}
   */
  public function start(Request $request, AuthenticationException $authException = null) {
    if ($request->isXmlHttpRequest()) {
      $response = new Response(json_encode([]), 401);
      $response->headers->set('Content-Type', 'application/json');
      return $response;
    }

    return $this->_http_tools->createRedirectResponse($request, $this->_login_path);
  }

}

答案 1 :(得分:1)

我也遇到了这个问题,并且惊讶于SecurityServiceProvider在firewal的配置中不支持entry_point选项(就像Symfony安全配置一样)。

我以不同的方式解决了这个问题。而不是覆盖security.entry_point.form._proto我跟踪SecurityServiceProvider内置身份验证工厂,而是在我的自定义服务提供商register()中写道:

$app['security.authentication_listener.factory.MY_CUSTOM_FIREWALL'] = $app->protect(function ($name, array $options) use ($app) {
    $app['security.authentication_provider.'.$name.'.anonymous'] = $app['security.authentication_provider.anonymous._proto']($name);
    $app['security.authentication_listener.'.$name.'.anonymous'] = $app['security.authentication_listener.anonymous._proto']($name, $options);
    $app['security.entry_point.'.$name.'.MY_CUSTOM_FIREWALL'] = $app->share(function() use ($app) {
        return new MyCustomFirewallEntryPoint($app['url_generator']);
    });

    return [
        'security.authentication_provider.'.$name.'.anonymous',
        'security.authentication_listener.'.$name.'.anonymous',
        'security.entry_point.'.$name.'.MY_CUSTOM_FIREWALL',
        'anonymous'
    ];
});

然后在安全配置中:

$app->register(new Silex\Provider\SecurityServiceProvider(), [
    'security.firewalls' => [
        // All other routes require valid user
        'secured' => [
            'pattern' => '^.*$',
            'anonymous' => true,
            // It will search for custom factory
            'MY_CUSTOM_FIREWALL' => true
        ],
    ],
]);