Всякий раз, когда я иду в /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
К настройкам вашей конфигурации app / 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, сообщите мне, если он не работает в других браузерах.