Вопрос

Я использую Калитка с проектом Wicket Auth Project для моего уровня представления, и поэтому я интегрировал его с 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;
}

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

<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.Защита от атак фиксации сеанса в справочной документации написано:

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

  • Migratessession - создает новую сессию и копирует существующие атрибуты сеанса в новую сессию.Это значение по умолчанию.
  • нет – Ничего не делайте.Исходный сеанс будет сохранен.
  • Newsession - Создайте новую «чистую» сеанс, не копируя существующие данные сеанса.

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

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

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

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

Это было полезно?

Решение

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

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

org.springframework.security.ui.webapp.AuthenticationProcessingFilter

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

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

org.springframework.security.ui.logout.LogoutFilter

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

Другие советы

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

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

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

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

SecurityContextHolder.getContext().setAuthentication(null);

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

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

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

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

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

<http ....>
  <intercept-url pattern="/myApp/**" ..>
 ....
</http>

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

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

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

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

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

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

        SecurityContextHolder.clearContext();

    } catch (Exception e) {
        logger.log(LogLevel.INFO, "Problem logging out.");
    }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top