Programowe wykorzystanie Spring Security

Używam Wicket z projektem Wicket Auth dla mojej warstwy prezentacji i dlatego zintegrowałem go z Spring Security. Jest to metoda, która jest wywoływana przez Wicket do uwierzytelniania dla mnie:

@Override
public boolean authenticate(String username, String password) {
    try {
        Authentication request = new UsernamePasswordAuthenticationToken(
                username, password);
        Authentication result = authenticationManager.authenticate(request);
        SecurityContextHolder.getContext().setAuthentication(result);
    } catch (AuthenticationException e) {
        return false;
    }
    return true;
}

Zawartość (wewnątrz ) mojej konfiguracji Spring Security XML to:

<http path-type="regex">
    <form-login login-page="/signin"/>
<logout logout-url="/logout" />
</http>
<global-method-security secured-annotations="enabled" />
<authentication-manager alias="authenticationManager"/>
<authentication-provider user-service-ref="userService">
    <password-encoder ref="bcryptpasswordencoder" />
</authentication-provider>

Sekcja 2.3.6. Ochrona przed atakiem utrwalania sesji z dokumentacji referencyjnej mówi:

Ataki fiksacji sesji są potencjalnym ryzykiem, gdy jest to możliwe aby złośliwy atakujący stworzył sesji poprzez dostęp do witryny, a następnie przekonaj innego użytkownika do zalogowania się z tej samej sesji (wysyłając im link zawierający identyfikator sesji jako parametr, na przykład). Wiosna Bezpieczeństwo chroni przed tym automatycznie tworząc nowy sesji po zalogowaniu się użytkownika. Jeśli nie wymagają tej ochrony, lub to konflikt z innym wymogiem, możesz kontrolować zachowanie za pomocą na sesja-utrwalenie-Ochrona atrybut na, który ma trzy opcje:

  • migrateSession-tworzy nową sesję i kopiuje istniejącą atrybuty sesji do nowej sesji. Jest to wartość domyślna.
  • brak-nic nie rób. Oryginalna sesja zostanie zachowana.
  • newSession-Utwórz nową" czystą " sesję, bez kopiowania istniejące dane sesji.

Uwierzytelnianie działa, ale jestem dość nowy na wiosnę Bezpieczeństwo mam kilka pytań, na które też potrzebuję odpowiedzi:

  • normalnie dla logowania, dodałbym informacje uwierzytelniające do j_spring_security_check i pozwoliłbym Spring Security wykonać rzeczywisty kod uwierzytelniający. Chciałbym mieć ochronę przed atakami fiksacji sesji, czy otrzymam ją podczas wykonywania logowania programowego tak jak to robię? A jeśli nie, to co muszę zrobić, żeby go zdobyć?
  • Jak wykonać programowe wylogowanie?
  • ponieważ użyję logowania programowego i wylogowania, jak wyłączyć Spring z przechwytywania tych adresów URL?

Aktualizacja: Dla ochrony przed atakiem utrwalania sesji wydaje się, że muszę wywołać metodę w klasie SessionUtils z podpisem startNewSessionIfRequired(HttpServletRequest request, boolean migrateAttributes, SessionRegistry sessionRegistry).

Jak uzyskać instancję SessionRegistry, którą muszę przekazać? Nie mogę znaleźć sposobu, aby utworzyć dla niego alias ID lub jak uzyskać jego identyfikator lub nazwę.

Author: Grzegorz Oledzki, 2009-06-18

6 answers

Może to nie jest pełna odpowiedź na twoje pytania, ale może Ci pomoże.

Kod jest wywoływany, gdy nie używasz loginu programowego, ale standardowego znajdziesz tutaj:

org.springframework.security.ui.webapp.AuthenticationProcessingFilter

Chyba zainspirowało cię to w swoim kodzie. Wygląda bardzo podobnie.

Podobnie kod wykonywany przy dostępie do /j_spring_security_logout w podejściu standardowym znajduje się tutaj:

org.springframework.security.ui.logout.LogoutFilter

LogoutFilter wywołuje wiele programów obsługi. The handler we are używanie nazywa się: org.springframework.security.ui.logout.SecurityContextLogoutHandler, więc możesz wywołać ten sam kod w swoim podejściu.

 22
Author: Grzegorz Oledzki,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-19 11:12:44

Będziesz rzeczywiście otwarty na ataki fiksacji sesji. Aby temu zaradzić, możesz ponownie zostać "zainspirowany" kodem Spring. Aby utworzyć nową sesję, musisz oczywiście uzyskać dostęp do httpsession, więc być może będziesz musiał dokonać refaktoryzacji.

Jeśli widzisz metodę SessionUtils.startNewSessionIfRequired.

Spowoduje migrację uwierzytelniania do nowej sesji. Możesz być w stanie wywołać tę metodę bezpośrednio lub po prostu trochę refaktorować kod.

Co do logowania programowego to nie mozna za bardzo źle, po prostu wywołując session.invalidate(), gdy musisz wylogować tę osobę. Zrobi to wszystko, co niezbędne z ogólnego punktu widzenia bezpieczeństwa, ale pamiętaj, że może być konieczne wyczyszczenie niektórych rzeczy w sesji. Jeśli masz bardzo skomplikowany zestaw filtrów itp. i musisz upewnić się, że użytkownik jest wylogowany na resztę żądania, wtedy możesz dodać:

SecurityContextHolder.getContext().setAuthentication(null);

Jeśli chodzi o przechwytywanie adresów URL, możesz po prostu ustawić je na coś nieużywanego i zignorować! Nie jestem oczywiście, jeśli możesz wyłączyć przechwytywanie w konfiguracji - jeśli naprawdę chcesz go usunąć, spójrz na AuthenticationProcessingFilter - możesz to dostosować. Jeśli to zrobisz, będziesz musiał ręcznie skonfigurować Spring security xml i nie używać podanych przestrzeni nazw. Nie jest to jednak zbyt trudne - spójrz na starszą dokumentację, a zobaczysz, jak to zrobić.

Mam nadzieję, że to pomoże!
 8
Author: Pablojim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-09 13:58:12

1) Programmatic Logout

  1. wywołanie HttpServletRequest.getSession (false).invalidate
  2. Zadzwoń do SecurityContextHolder.clearContext ()

2) Powiedz Spring Security, aby nie przechwytywała pewnych adresów URL, Ten jeden rodzaj zależy od konfiguracji przestrzeni URL aplikacji. Jeśli wszystkie Twoje strony (z wyjątkiem /logIn i /wyloguj) żyły w context / myApp, możesz to zrobić:

<http ....>
  <intercept-url pattern="/myApp/**" ..>
 ....
</http>
 6
Author: Gandalf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-23 22:26:27

Miałem problem z logowaniem programowym. Wywołałem wszystkie metody authenticationManager.authenticate(...) i SecurityContextHolder.getContext().setAuthentication(...), ale miałem pewne problemy z sesją. Musiałem dodać następujące linie, aby poprawnie zarządzać sesją:

HttpSession session = request.getSession();
session.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext());

Nie było to jasne z przykładowego kodu zamieszczonego powyżej. Więcej na http://forum.springsource.org/showthread.php?t=69761

 1
Author: velaia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-03 13:51:40

Aby wykonać programowy wylogowanie można również rzucić org.springframework.security.core.AuthenticationException. Na przykład SessionAuthenticationException. W tym przypadku ExceptionTranslationFilter zainicjuj wylogowanie.

 0
Author: viator,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-15 09:18:47

Możesz spróbować tego

    try {
        HttpSession session = request.getSession(false);
        if (session != null) {
            session.invalidate();
        }

        SecurityContextHolder.clearContext();

    } catch (Exception e) {
        logger.log(LogLevel.INFO, "Problem logging out.");
    }
 0
Author: Chandra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-19 14:53:22