суббота, 2 февраля 2013 г.

Spring Security - кастомизация (т.е. настройка)

Вот в этой статье написано, как использовать Spring security в GWT в самом простом варианте, нужно разобраться как использовать это технологию по-взрослому.

Решаемые вопросы:
  1. при отсутствии авторизации пользователю должен выдаваться алерт с предложением ввести логин/пароль
  2. подключение логаута
  3. получение авторизации должно проходить на основе базы данных

Авторизация в виде алерта
Редактируем тэг <http> настроечного файла applicationContext.xml

<http auto-config="true">
<intercept-url pattern="/favicon.ico" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/images/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/js/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/resources/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/securegwt/**" access="ROLE_USER" />
<intercept-url pattern="/gwt/**" access="ROLE_USER" />
<intercept-url pattern="/**/*.html" access="ROLE_USER" />
<intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />

<http-basic />
</http>

В первых четырёх строках мы предоставляем анонимный доступ на ресурсы (веб-иконку favicon.ico, рисунки, которые хранятся в папке /images проекта, ресурсы /resources и джаваскрипты /js)

В последней строке мы добавляем тег <http-basic />, который говорит Spring Security, что нужно использовать так называемую бэйсик-авторизацию, то есть авторизацию в виде алерта.

Подключение логаута
англоязыйчный источник находится здесь.
Чтобы сделать логаут, нужно добавить ссылку на УРЛ: j_spring_security_logout, например:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<body>
 <h3>messages, whatever</h3> 
 <a href="<c:url value="j_spring_security_logout" />" > Logout</a>
</body>
</html>

в терминах GWT это будет выглядеть так:

Label lbl = new Label("Logout");
lbl.addClickHandler(...);
lbl.setStyleName("hyperlink_style_label");

При использовании UIBinder в файл.ui.xml нужно добавить тэг <g:Hyperlink>

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


CREATE TABLE `users` (
  `USER_ID` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `USERNAME` VARCHAR(45) NOT NULL,
  `PASSWORD` VARCHAR(45) NOT NULL,
  `ENABLED` tinyint(1) NOT NULL,
  PRIMARY KEY (`USER_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `user_roles` (
  `USER_ROLE_ID` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `USER_ID` INT(10) UNSIGNED NOT NULL,
  `AUTHORITY` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`USER_ROLE_ID`),
  KEY `FK_user_roles` (`USER_ID`),
  CONSTRAINT `FK_user_roles` FOREIGN KEY (`USER_ID`) REFERENCES `users` (`USER_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO users (USERNAME, PASSWORD, ENABLED)
VALUES ('andrew', md5('password'), TRUE);

INSERT INTO user_roles (USER_ID, AUTHORITY)
VALUES ((select user_id from users where username='andrew'), 'ROLE_USER');

Добавим в проект библиотеки:

  • mysql-connector-java-5.1.23-bin.jar
  • spring-jdbc-3.2.1.RELEASE.jar
  • spring-tx-3.2.1.RELEASE.jar


В конфигурационном файле applicationContext.xml нужно определить бин подключения к базе данных dataSource:

   <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/mydatabase" />
 <property name="username" value="root" />
 <property name="password" value="password" />
   </bean>

И заменить authentication-manager:

 <authentication-manager>
  <authentication-provider>
      <password-encoder hash="md5"/>
   <jdbc-user-service data-source-ref="dataSource"

    users-by-username-query="
        select username,password, enabled 
        from users where username=?"

    authorities-by-username-query="
        select u.username, ur.authority from users u, user_roles ur 
        where u.user_id = ur.user_id and u.username =?  " />
  </authentication-provider>
 </authentication-manager>

Вставка в таблицу БД пароля пользователя с помощью функции md5() согласована с тегом <password-encoder hash="md5"/> в настроечном файле. Пароль будет храниться в базе в зашифрованном md5-алгоритмом виде, никто никогда не сможет расшифровать его, а можно будет только сравнивать хранимую строку с аналогичным образом зашиброванным вариантом пользователя.

После этого в вашем приложении смогут авторизовываться только пользователи, зарегистрированные в вашей базе данных.

1 комментарий: