Всякий раз, когда я иду в /admin/logout
, Я правильно перенаправлен в корень моего проекта, но все еще вошел в систему, когда я посещаю /admin/
как меня не просят для учетных данных.
Вот моя конфигурация:
security.yml
security:
firewalls:
admin_area:
pattern: ^/admin
http_basic: ~
stateless: true
switch_user: { role: ROLE_SUPER_ADMIN, parameter: _want_to_be_this_user }
logout: { path: /admin/logout, target: / }
AdminBundle / Ресурсы / конфигурация / routing.yml
logout:
pattern: /logout
приложение / Config / routing.yml
admin:
resource: "@AdminBundle/Resources/config/routing.yml"prefix: /admin
Авторизация все еще на месте, поскольку состояние заголовков Authorization:Basic YWRtaW46cEAkJHcwUmQh
поэтому я предполагаю, что учетные данные все еще предоставляются приложению во время запроса.
Я знаю, что нет правильного способа выхода из HTTP Basic Auth
согласно этот вопрос но может Symfony2 это позволяет?
После входа через http auth ваш браузер будет кэшировать и добавлять ваши учетные данные для входа в каждый последующий запрос в виде заголовка, подобного следующему:
Authorization:Basic YWRtaW46YWRtaW4=
Когда вы выйдете из системы, при следующем запросе к серверу все равно будут сохранены ваши учетные данные http и вы снова войдете в систему.
Таким образом, хитрость заключается в потере учетных данных http на стороне клиента после уничтожения сеанса на стороне сервера.
В прошлом были такие хакерские методы, как отправка ложных учетных данных или какой-то непонятный метод IE для удаления кэша. Но я не думаю, что эти методы все еще работают.
Что все еще работает (я тестировал следующий метод с Symfony 2.7 и Google Chrome 45), отвечая клиенту с несанкционированным ответом HTTP 401.
Проверьте это:
Добавьте следующее в раздел выхода из системы в файле app / config / security.yml
logout:
success_handler: logout_listener
К вашим услугам конфигурация приложения / config / services.yml
logout_listener:
class: AppBundle\LogoutListener
Затем создайте прослушиватель, который ответит HTTP 401 неавторизованным
<?php
namespace AppBundle;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
class LogoutListener implements LogoutSuccessHandlerInterface
{
public function onLogoutSuccess(Request $request)
{
return new Response('', 401);
}
}
После выхода из системы ваше приложение отправит 401 в браузер, который будет считать, что аутентификация не удалась, что приводит к очистке кэша аутентификации (который в любом случае хочет запомнить неверные учетные данные) и снова запросит ваши учетные данные
Кажется, ответ @Niki Van Cleemput работает не во всех случаях. Когда я тестировал его, все было нормально на Chrome 44, но не на Firefox 48.
Вот решение, вдохновленное Выход из аутентификации HTTP через PHP:
Параметры безопасности:
security:
# ... your encoders, role_hierarchy, providers...
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
anonymous: ~
stateless: true
http_basic:
realm: "My admin area"# no logout parameter as it is handled manually
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
Контроллер с «поддельным» действием выхода из системы:
<?php
namespace Me\Bundle\CoreBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
/**
* Security stuff.
*/
class SecurityController extends Controller
{
/**
* Logout confirmation.
*
* @Route("/logout", name="logout")
*/
public function logoutAction()
{
return $this->render('@EasyAdmin/default/logout.html.twig'); // change with your template path
}
}
В вашем макете:
<script type="text/javascript">
function logout() {
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
}
// code for IE
else if (window.ActiveXObject) {
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
if (window.ActiveXObject) {
// IE clear HTTP Authentication
document.execCommand("ClearAuthenticationCache");
window.location.href='{{ path('logout') }}';
} else {
xmlhttp.open("GET", '{{ path('easyadmin') }}', true, "logout", "logout");
xmlhttp.send("");
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4) {window.location.href='{{ path('logout') }}';}
}
}
return false;
}
</script>
Добавьте ссылку выхода из системы:
<a href="#" onclick="logout()"><i class="hidden-xs fa fa-user"></i> Logout</a>
По крайней мере, это работает как в Chrome, так и в Firefox, дайте мне знать, если это не работает в других браузерах.