Выйти из http_basic auth в Symfony2

Всякий раз, когда я иду в /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 это позволяет?

7

Решение

После входа через 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 в браузер, который будет считать, что аутентификация не удалась, что приводит к очистке кэша аутентификации (который в любом случае хочет запомнить неверные учетные данные) и снова запросит ваши учетные данные

11

Другие решения

Кажется, ответ @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, дайте мне знать, если это не работает в других браузерах.

0