如果我向安全区域发出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();
});
default
是security.firewalls
中密钥的名称。仍然得到302。
答案 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
],
],
]);