1. Обзор
В этой статье будет показано, как настроить функцию «Запомнить меня» в Spring Security — используя не стандартный подход только к файлам cookie, а более безопасное решение, использующее постоянство .
В качестве краткого введения: Spring можно настроить так, чтобы он запоминал данные для входа между сеансами браузера. Это позволяет вам войти на веб-сайт, а затем автоматически войти в систему при следующем посещении сайта (даже если вы тем временем закрыли браузер).
2. Два решения «Запомнить меня»
Spring предоставляет две немного разные реализации для решения проблемы. Оба используют UsernamePasswordAuthenticationFilter
, используя ловушки для вызова реализации RememberMeServices
.
Стандартное решение «Запомнить меня», использующее только cookie, мы уже рассматривали в предыдущей статье . В этом решении использовался файл cookie с именем « запомнить меня»,
содержащий имя пользователя, время истечения срока действия и хэш MD5, содержащий пароль. Поскольку он содержит хэш пароля, это решение потенциально уязвимо , если файл cookie будет перехвачен.
Имея это в виду — давайте рассмотрим второй подход — использование PersistentTokenBasedRememberMeServices
для хранения постоянной информации для входа в таблицу базы данных между сеансами.
3. Предпосылки — создание таблицы базы данных
Во-первых, нам нужно иметь информацию для входа в базу данных — нам нужно создать таблицу для хранения данных:
create table if not exists persistent_logins (
username varchar_ignorecase(100) not null,
series varchar(64) primary key,
token varchar(64) not null,
last_used timestamp not null
);
Это создается автоматически при запуске с помощью следующей конфигурации XML (с использованием базы данных H2 в памяти):
<!-- create H2 embedded database table on startup -->
<jdbc:embedded-database id="dataSource" type="H2">
<jdbc:script location="classpath:/persisted_logins_create_table.sql"/>
</jdbc:embedded-database>
И для полноты, вот как настраивается постоянство:
@Configuration
@EnableTransactionManagement
@PropertySource({ "classpath:persistence-h2.properties" })
public class DatabaseConfig {
@Autowired private Environment env;
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
dataSource.setUrl(env.getProperty("jdbc.url"));
dataSource.setUsername(env.getProperty("jdbc.user"));
dataSource.setPassword(env.getProperty("jdbc.pass"));
return dataSource;
}
}
4. Конфигурация безопасности Spring
Первая ключевая конфигурация — это конфигурация Remember-Me Http (обратите внимание на свойство dataSource
):
<http use-expressions="true">
...
<remember-me data-source-ref="dataSource" token-validity-seconds="86400"/>
<http">
Далее нам нужно настроить фактический RememberMeService
и JdbcTokenRepository
(который также использует источник данных)
:
<!-- Persistent Remember Me Service -->
<beans:bean id="rememberMeAuthenticationProvider" class=
"org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices">
<beans:constructor-arg value="myAppKey" />
<beans:constructor-arg ref="jdbcTokenRepository" />
<beans:constructor-arg ref="myUserDetailsService" />
</beans:bean>
<!-- Uses a database table to maintain a set of persistent login data -->
<beans:bean id="jdbcTokenRepository"
class="org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl">
<beans:property name="createTableOnStartup" value="false" />
<beans:property name="dataSource" ref="dataSource" />
</beans:bean>
<!-- Authentication Manager (uses same UserDetailsService as RememberMeService)-->
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="myUserDetailsService"/>
</authentication-provider>
</authentication-manager>
5. Печенье
Как мы уже упоминали, стандартный TokenBasedRememberMeServices
хранил хешированный пароль пользователя в файле cookie.
Это решение — PersistentTokenBasedRememberMeServices
использует уникальный идентификатор серии для пользователя . Это идентифицирует первоначальный вход пользователя в систему и остается постоянным каждый раз, когда пользователь автоматически входит в систему во время этого постоянного сеанса. Он также содержит случайный токен , который обновляется каждый раз, когда пользователь входит в систему с помощью постоянных функций запоминания.
Эта комбинация случайно сгенерированных серий и токенов сохраняется, что делает атаку грубой силы маловероятной.
6. На практике
Чтобы увидеть, как работает механизм «запомнить меня» в браузере, вы можете:
- Войти с активной функцией «Запомнить меня»
- Закройте браузер
- Снова откройте браузер и вернитесь на ту же страницу. Обновить.
- Вы по-прежнему будете авторизованы
Если функция «Запомнить меня» не активна , после истечения срока действия файла cookie пользователь должен быть перенаправлен обратно на страницу входа. С функцией «Запомнить меня » пользователь теперь остается в системе с помощью нового токена/куки.
Вы также можете просматривать файлы cookie в браузере и сохраненные данные в базе данных (примечание — для этого вы можете отказаться от встроенной реализации H2).
7. Заключение
В этом учебном пособии показано, как установить и настроить функцию сохранения токена «Запомнить меня» в базе данных . Это также продолжение предыдущей статьи, в которой обсуждалась стандартная функциональность на основе токена cookie . Подход с базой данных более безопасен, поскольку сведения о пароле не сохраняются в файле cookie, но требует немного большей настройки.
Реализацию этого учебного пособия по Spring Security REST можно найти в проекте GitHub — это проект на основе Eclipse, поэтому его легко импортировать и запускать как есть.