2015-03-24 14 views
7

Ilekroć odwiedzam numer /admin/logout, jestem poprawnie przekierowywany do katalogu głównego mojego projektu, ale nadal jestem zalogowany, gdy odwiedzam /admin/, ponieważ nie jestem pytany o dane uwierzytelniające.Wylogowanie się z http_basic auth w Symfony2

Oto moja konfiguracja:

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/Resources/config/routing.yml

logout: 
    pattern: /logout 

app/config/routingu. yml

admin: 
    resource: "@AdminBundle/Resources/config/routing.yml" 
    prefix: /admin 

Autoryzacja nadal obowiązuje jako nagłówek: Authorization:Basic YWRtaW46cEAkJHcwUmQh, więc domyślnie poświadczenia są nadal dostarczane do aplikacji podczas żądania.

Wiem, że nie ma właściwego sposobu na wylogowanie się z HTTP Basic Auth jak na this question, ale może Symfony2 na to pozwala?

+1

możliwy duplikat [problemu konfiguracji Symfony2 http \ _basic security] (http://stackoverflow.com/questions/5989201/symfony2-http-basic-security-configuration-problem) –

+0

spróbuj zmienić wzór wylogowania na '/ admin/logout', więc jest pod firewallem możesz również sprawdzić, czy nie zaznaczyłeś 'remember me' - spróbuj usunąć pliki cookie, a następnie zaloguj się i wyloguj – Vardius

+0

Dzięki @Vardius za komentarz, ale mój wzorzec jest ** już **'/admin/logout', ponieważ jestem poprawnie przekierowywany. Ponadto nie zaimplementowałem opcji 'remember_me' (jeszcze). – D4V1D

Odpowiedz

11

Po zalogowaniu się za pośrednictwem protokołu HTTP auth, przeglądarka cache i dodać swoje dane logowania do każdego kolejnego wniosku w postaci nagłówka jak poniżej:

Authorization:Basic YWRtaW46YWRtaW4= 

Po wykonaniu wylogowania, następne żądania do serwer nadal będzie przechowywać twoje poświadczenia http i zaloguje się ponownie.

Sztuką jest utrata poświadczeń http po stronie klienta po zniszczeniu sesji po stronie serwera.

W przeszłości tam, gdzie niektóre hackidy metody jak przedkładanie fałszywych poświadczeń lub jakiejś niejasnej metody IE do usuwania pamięci podręcznej. Ale nie sądzę, że te metody nadal działają.

Co dalej działa (testowałem następującą metodę z Symfony 2.7 i google chrome 45) odpowiada na klienta za pomocą nieautoryzowanej odpowiedzi HTTP 401.

Sprawdź:

Dodaj poniższe linie do sekcji wylogowania w app/config/security.yml

logout: 
    success_handler: logout_listener 

Do Twoich usług app konfiguracji/config/services.yml

logout_listener: 
    class: AppBundle\LogoutListener 

Następnie utwórz odbiornik, który odpowiada za pomocą HTTP 401 nieautoryzowanym

<?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); 
    } 
} 

Po zalogowaniu się swoją aplikację wyśle ​​401 do przeglądarki, które będą myśleć uwierzytelnianie nie powiodło się w wyniku cache auth przejaśniały (kto chce pamiętać wadliwych poświadczeń i tak po prawej) i poprosi o podanie poświadczeń ponownie

+1

Przyjemny pomysł, ale nie działa na Firefox – caponica

+0

Jednak odskakiwanie do 'http: // logout @ www.twojadomena.pl/ twoja/strona' działa (tj. próbuje zalogować się z fałszywymi danymi uwierzytelniającymi w adresie URL) . Nie wiem, dlaczego to wyczyści buforowane uwierzytelnienie, ale prosta odpowiedź 401 nie, ale proszę. – caponica

+1

Po prostu wypróbowałem sztuczkę "wylogowanie @" na Chromium 56, to nie działa –

0

Odpowiedź @Niki Van Cleemput nie wydaje się działać we wszystkich przypadkach. Kiedy go przetestowałem, było dobrze w Chrome 44, ale nie w Firefoksie 48. Oto rozwiązanie inspirowane HTTP authentication logout via PHP:

Parametry bezpieczeństwa:

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 } 

Kontroler z "fałszywych" działania wylogowania:

<?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 
    } 
} 

w układzie:

<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> 

Dodaj link wylogowania:

<a href="#" onclick="logout()"><i class="hidden-xs fa fa-user"></i> Logout</a> 

Przynajmniej działa zarówno w przeglądarce Chrome, jak i Firefox, daj mi znać, jeśli nie działa w innych przeglądarkach.

+0

To wygląda paskudnie ... lepiej i czysto, aby odrzucić użytkownika do 'http: // logout @ www.yourdomain.com/your/page' (gdzie "wylogowanie" jest nieprawidłową nazwą użytkownika). To powinno zawieść uwierzytelnianie i wyczyścić powiązaną pamięć podręczną. – caponica

+0

Zgadzam się, całkiem nieprzyjemny. Ale dla mnie jest to jedyne rozwiązanie, które działało w każdej przeglądarce bez konieczności wywoływania "fałszywego" użytkownika do wylogowania. – COil

+0

imho, prawdopodobnie lepiej/czystsze jest wywoływanie fałszywego użytkownika, aby wymusić wylogowanie zamiast całego tego kodu (wszystko czego potrzebujesz to link wylogowania). – caponica