Программное использование Spring Security - PullRequest
36 голосов
/ 18 июня 2009

Я использую Wicket с проектом авторизации Wicket для своего уровня презентации, и поэтому я интегрировал его со Spring Security. Это метод, который вызывается Wicket для аутентификации для меня:

@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;
}

Содержимое (внутри) моей конфигурации Spring Security XML:

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

Раздел 2.3.6. Защита от атак фиксации сеанса из справочной документации гласит:

Атаки с фиксацией сеанса представляют собой потенциальный риск там, где это возможно. злоумышленнику создать сеанс доступа к сайту, затем убедить другого пользователя войти с тот же сеанс (отправив им ссылка, содержащая идентификатор сеанса в качестве параметра, например). весна Безопасность защищает от этого автоматически путем создания нового сеанс, когда пользователь входит в систему. Если вы не требует этой защиты, или это конфликтует с некоторыми другими требованиями, Вы можете контролировать поведение, используя сеанс-фиксация-защита атрибут, который имеет три Варианты:

  • migrateSession - создает новый сеанс и копирует существующий атрибуты сеанса для нового сеанса. Это значение по умолчанию.
  • нет - ничего не делай. Первоначальный сеанс будет сохранен.
  • newSession - Создать новый "чистый" сеанс, не копируя данные существующего сеанса.

Аутентификация работает, но я, поскольку я довольно новичок в Spring Security, у меня есть несколько вопросов, на которые мне тоже нужны ответы:

  • Обычно для входа в систему я отправляю информацию аутентификации на j_spring_security_check и позволяю Spring Security выполнять фактический код аутентификации. Я хотел бы иметь защиту от атак фиксации сеанса, получу ли я это при выполнении программного входа в систему, как я? А если нет, что мне нужно сделать, чтобы получить его?
  • Как выполнить программный выход из системы?
  • Поскольку я буду использовать программный вход и выход, как отключить Spring для перехвата этих URL-адресов?

Обновление: Для защиты от атак с фиксацией сеанса мне кажется, что мне нужно вызвать метод в классе SessionUtils с подписью startNewSessionIfRequired(HttpServletRequest request, boolean migrateAttributes, SessionRegistry sessionRegistry).

Как получить экземпляр SessionRegistry, который мне нужно передать? Я не могу найти способ создать для него идентификатор псевдонима или узнать, как получить его идентификатор или имя.

Ответы [ 6 ]

22 голосов
/ 19 июня 2009

Возможно, это не полный ответ на ваши вопросы, но, возможно, это может вам помочь.

Код, вызываемый, когда вы НЕ используете программный вход в систему, но стандартный код можно найти здесь:

org.springframework.security.ui.webapp.AuthenticationProcessingFilter

Полагаю, вы вдохновились этим в своем коде. Это выглядит очень похоже.

Аналогично, код, выполняемый при доступе к /j_spring_security_logout в стандартном подходе, находится здесь:

org.springframework.security.ui.logout.LogoutFilter

LogoutFilter вызывает несколько обработчиков. Используемый нами обработчик называется: org.springframework.security.ui.logout.SecurityContextLogoutHandler, так что вы можете вызвать тот же код в вашем подходе.

8 голосов
/ 22 июня 2009

Вы действительно будете открыты для атак фиксации сеанса. Чтобы исправить это, вы снова можете быть «вдохновлены» кодом Spring. Для создания нового сеанса вам, очевидно, понадобится доступ к httpsession, поэтому вам, возможно, придется провести некоторый рефакторинг.

Если вы видите метод SessionUtils. startNewSessionIfRequired.

Это перенесет аутентификацию в новый сеанс. Возможно, вы сможете вызвать этот метод напрямую или просто немного изменить код.

Что касается программного выхода из системы, вы не можете пойти слишком далеко неправильно, просто позвонив session.invalidate(), когда вам нужно выйти из системы. Это сделает все необходимое с точки зрения общей безопасности, но имейте в виду, что вам может понадобиться очистить некоторые вещи в сеансе. Если у вас очень сложный набор фильтров и т. Д., И вы должны убедиться, что пользователь вышел из системы для оставшейся части запроса, вы можете добавить:

SecurityContextHolder.getContext().setAuthentication(null);

Что касается перехвата URL-адресов, вы можете просто установить их на что-то неиспользованное и игнорировать это! Я не уверен, что вы можете отключить перехват в конфигурации - если вы действительно хотите удалить его, посмотрите на AuthenticationProcessingFilter - вы можете настроить это. Если вы сделаете это, вам придется вручную настроить Spring Security XML и не использовать предоставленные пространства имен. Это не так уж сложно - посмотрите на некоторые старые документы, и вы увидите, как это сделать.

Надеюсь, это поможет!

6 голосов
/ 24 июня 2009

1) Программный выход из системы

  1. вызов HttpServletRequest.getSession (false) .invalidate
  2. вызов SecurityContextHolder.clearContext ()

2) Скажите Spring Security НЕ перехватывать определенные URL-адреса, этот вид зависит от того, как настроено пространство URL вашего приложения. Если все ваши страницы (кроме / logIn и / logout) живут в контексте / myApp, то вы можете сделать это:

<http ....>
  <intercept-url pattern="/myApp/**" ..>
 ....
</http>
1 голос
/ 03 ноября 2010

У меня была проблема с программным логином. Я вызвал все методы authenticationManager.authenticate(...) и SecurityContextHolder.getContext().setAuthentication(...), но у меня были некоторые проблемы с сеансом. Мне пришлось добавить следующие строки, чтобы правильно управлять сессией:

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

Это не было ясно из приведенного выше примера кода. Для более подробного ознакомления с http://forum.springsource.org/showthread.php?t=69761

0 голосов
/ 19 марта 2012

Вы можете попробовать это

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

        SecurityContextHolder.clearContext();

    } catch (Exception e) {
        logger.log(LogLevel.INFO, "Problem logging out.");
    }
0 голосов
/ 16 июля 2010

Чтобы сделать программный выход из системы, также можно выдать org.springframework.security.core.AuthenticationException. Например, SessionAuthenticationException. В этом случае ExceptionTranslationFilter инициирует выход из системы.

...