Spring Security — username password remember me (сохранение пароля пользователя для автоматической аутентификации)
Пример включения функции сохранения пароля пользователя для автоматической аутентификации без повторного ввода данных (Spring Security username password remember-me example).
Используемые технологии
- Spring 4.2.2.RELEASE
- Spring Security 4.0.2.RELEASE
- MySQL 5.6.25
- JSP 1.2.1
- IntelliJ IDEA 14
- Maven 3.2.5
1. Описание задачи
Необходимо подключить функцию remember-me в Spring Security 4.0.2. Рассмотреть различные настройки, позволяющие пользователю включить возможность «запомнить меня» для дальнейшего автоматического входа в приложение без ввода пароля.
2. Структура проекта
Полностью взята из Spring Security – создание группы ролей (group authorities). Создание таблиц базы данных. Здесь будет добавлен только код в существующие классы и представления.
3. Настройка spring-security-config.xml
В первой статье уже был добавлен тег <remember-me/> и в общем случае это уже включает возможность запоминания имени пользователя и пароля. Но, скажем так, это слабенький вариант, т.к. мы совсем не можем повлиять на какие-либо параметры. Мы пойдем другим путём! Для примера рассмотрим более реальный код.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
<?xml version="1.0" encoding="UTF-8"?> <b:beans xmlns="http://www.springframework.org/schema/security" xmlns:b="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <http pattern="/favicon.ico" security="none" /> <http use-expressions="true"> <intercept-url pattern="/" access="isFullyAuthenticated() or isAnonymous()"/> <intercept-url pattern="/login.jsp*" access="isFullyAuthenticated() or isAnonymous()"/> <intercept-url pattern="/admin" access="hasRole('ADMIN')"/> <intercept-url pattern="/exitUser*" access="isFullyAuthenticated() or isAnonymous()"/> <intercept-url pattern="/**" access="hasRole('USER')"/> <form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error=1" authentication-success-handler-ref="savedRequestAwareAuthenticationSuccessHandler"/> <access-denied-handler error-page="/accessDenied.jsp"/> <http-basic/> <logout logout-success-url="/exitUser.jsp"/> <remember-me key="myAppKey" user-service-ref="jdbcGroupsImpl" token-repository-ref="tokenRepository" remember-me-cookie="remember-me-cookieName" remember-me-parameter="remember-me-parameter" token-validity-seconds="1800"/> <headers/> <csrf/> </http> <authentication-manager> <authentication-provider user-service-ref="jdbcGroupsImpl"/> </authentication-manager> <b:bean id="jdbcGroupsImpl" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl"> <b:property name="enableGroups" value="true"/> <b:property name="enableAuthorities" value="false"/> <b:property name="dataSource" ref="dataSource"/> </b:bean> <b:bean id="tokenRepository" class="org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl"> <b:property name="dataSource" ref="dataSource"/> </b:bean> </b:beans> |
В теге <remember-me> названия параметров объясняют их значение. Так же добавлен tokenRepository с ссылкой на базу данных, где будут храниться токены.
datasource-config.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:security="http://www.springframework.org/schema/security" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd"> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/users"/> <property name="username" value="root"/> <property name="password" value="admin"/> </bean> <bean id="savedRequestAwareAuthenticationSuccessHandler" class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler"> <property name="targetUrlParameter" value="targetUrl" /> </bean> </beans> |
4. Создание таблицы для хранения токенов
По соглашению требуется создать таблицу для хранения токенов. Она будет создана в той же схеме, где хранятся пользователи и группы.
1 2 3 4 5 6 7 |
Use users; create table persistent_logins ( username VARCHAR(64) NOT NULL , series VARCHAR(64) NOT NULL PRIMARY KEY, token VARCHAR(64) NOT NULL , last_used TIMESTAMP NOT NULL ) |
5. Описание представлений
Все jsp страницы остались без изменений относительно статьи, указанной вначале поста.
6. Тестирование
Входим в приложение:
Переходим на страницу для админа:
Видим сообщение, что пользователь админ вошел с помощью логина и пароля.
Для Chrome нажимаем f12 и смотрим вкладку Cookies
Видно, что у нас появилась еще одна запись относящаяся к remember-me. Чтобы проверить как отработает наша функция «запомнить меня» необходимо удалить информацию о сессии JSESSIONID.
Пробуем войти на страницу админа снова:
Аутентификация прошла с помощью токена (заметьте сессия уже другая) . Ч.Т.Д.
Исходные коды:
Spring Security RememberMe — исходные коды и создание схемы с таблицами и записями
11