JavaEE: Пример использования Spring Security.
UPDATE: Возможно вам будет интересен пример использования Spring Security 4 и AngularJS.
Spring Security - фреймворк, предоставляющий удобную реализацию механизмов аутентификации и авторизации в Java EE приложениях. Раньше был известен как Acegi Security, а в 2008 году был включен в проект Spring. Является стандартом де-факто для веб-приложений Spring MVC. Использовать Spring Security очень удобно и просто - без особых усилий можно создать гибкую систему управления правами в вашем веб-приложении.
Для того, чтобы показать как это работает - приведу простой, но подробный пример приложения, которое использует Spring Securtiy. Приложение будет состоять из страницы входа и закрытой страницы, доступ к которой имеет только один пользователь. Как нетрудно догадаться, это будет веб-приложение Spring MVC. Итак, цель поставлена, инструменты определены, приступаем к делу!
Для примера создаем шаблонный проект веб-приложения Spring MVC, используя Spring Tool Suite (File > New > Spring Template Project > Spring MVC Project ).
После этого у нас уже есть простое веб-приложение, которое можно запустить на сервере (ссылку на полный код примера можно найти в конце поста). Первое что необходимо сделать - добавить в pom.xml необходимые зависимости:
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-core</artifactId> <version>${org.springframework-version}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>${org.springframework-version}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>${org.springframework-version}</version> </dependency>
Потом удалим класс контоллера, и .jsp страницы, которые были автоматически созданы Spring Tool Suite, и добавим свои. Создадим две .jsp страницы - login.jsp и admin.jsp. Первая - это страница входа, которая в данном случае будет и главной страницей, а вторая - это страница, которая будет доступна только авторизованному пользователю.
login.jsp:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" language="java" %> <%@ page session="false"%> <!doctype html> <html lang="ru"> <head> <meta charset="utf-8"> <title>Вход</title> <link rel="stylesheet" href="${pageContext.request.contextPath}/resources/css/style.css" /> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" /> </head> <body onload='document.f.j_username.focus();'> <form name='f' action="<c:url value='/j_spring_security_check' />" method='POST'> <div class="logincontainer"> <div class="login"> <table> <tr> <td>Имя <input type='text' name='j_username'> </td> </tr> <tr> <td>Пароль <input type='password' name='j_password' /> </td> </tr> </table> <br /> <input class="btn btn-primary" name="submit" type="submit" value="Вход" /> <br /> </div> <c:if test="${not empty error}"> <div class="alert alert-danger" style="width: 285px; margin: 0px auto;" role="alert"> ${error}</div> </c:if> </div> </form> </body> </html>
Как видно, здесь есть есть форма для ввода имени пользователя и пароля, для отправки которой указан cпециальный URL j_spring_security_check.
admin.jsp:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" language="java"%> <%@ page session="false"%> <!doctype html> <html lang="ru"> <head> <meta charset="utf-8"> <title>Вход</title> <link rel="stylesheet" href="${pageContext.request.contextPath}/resources/css/style.css" /> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" /> </head> <body> <div id="admin-section"> <h3>Поздравляем, вы на закрытой странице!</h3> <a class="btn btn-primary" href="j_spring_security_logout">Выход</a> </div> </body> </html>
Здесь аналогично, специальный URL для выхода пользователя из системы j_spring_security_logout. Страницы, которые должны быть закрытыми рекомендуется размещать в отдельной директории, в этом примере страница admin.jsp находится в директории views/private. Теперь необходимо создать файл конфигурации spring-security.xml:
В этом файле во первых указываются правила, согласно которым будет осуществляться доступ к определенным URL. Здесь указываются URL паттерны и роль/роли, которая соответствует этим паттернам:
<http auto-config="true"> <intercept-url pattern="/admin" access="ROLE_ADMIN" /> <intercept-url pattern="/admin/*" access="ROLE_ADMIN" /> <intercept-url pattern="/admin*" access="ROLE_ADMIN" /> <form-login login-page="/login" default-target-url="/admin" authentication-failure-url="/loginfailed" /> <logout logout-success-url="/logout" /> </http>
Это означает, что перейти по URL, который соответствует одному из указанных паттернов может только пользователь, который соответствует роли ROLE_ADMIN. Ниже в этом файле указана конфигурация и самой роли:
<authentication-manager> <authentication-provider> <password-encoder hash="sha" /> <user-service> <user name="admin" password="40bd001563085fc35165329ea1ff5c5ecbdbbeef" authorities="ROLE_ADMIN" /> </user-service> </authentication-provider> </authentication-manager>
В данном случае, таким образом задан один пользователь admin, с паролем 123. Пароли по известным соображениям не должны храниться в открытом виде, поэтому здесь указывается хеш код пароля SHA1. Теперь нужно добавить добавить spring-security.xml в web.xml:
<context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/spring/root-context.xml /WEB-INF/spring/spring-security.xml </param-value> </context-param>
Таже в web.xml нужно добавить фильтр для включения Spring Security:
<filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
Осталось создать классы контроллеров. Создадим два отдельных класса, один для страницы входа (LoginController.java), другой - для закрытой страницы (AdminController.java). В LoginConroller.java добавлен маппинг для перехода по URL “/” так как домашней страницей в нашем примере является страница входа.
LoginController:
@Controller public class LoginController { private final String ERROR_MESSAGE = "Неправильные имя/пароль"; @RequestMapping(value = "/", method = RequestMethod.GET) public String home() { return "login"; } @RequestMapping(value = "/login", method = RequestMethod.GET) public String login() { return "login"; } @RequestMapping(value = "/loginfailed", method = RequestMethod.GET) public String loginerror(ModelMap model) { model.addAttribute("error", ERROR_MESSAGE); return "login"; } @RequestMapping(value = "/logout", method = RequestMethod.GET) public String logout() { return "login"; } }
AdminController:
@Controller public class AdminController { @RequestMapping(value = "/admin", method = RequestMethod.GET) public String home() { return "private/admin"; } }
Запустим приложение на Java EE сервере или в контейнере сервлетов (например Apache Tomcat):
Перенаправление на страницу входа осуществляется при переходе на целевую страницу, а также с домашней страницы. Неправильный ввод пароля/имени пользователя даст такой результат:
А в случае успеха мы попадаем на целевую закрытую страницу:
Мы рассмотрели элементарный пример использования Spring Securtiy. Как видно, использовать его достаточно просто и удобно. Нет никакой необходимости беспокоиться о сессиях и прочих деталях - достаточно указать соответствующие правила для пользователей в конфигурации, а о всем остальном позаботится фреймворк.
Теги: programming Spring javaEE
comments powered by Disqus