Имеем
- Eclipse IDE for java EE developers 4.2.1
- apache tomcat 7.0.35
Project name = springsecurity
Чего хотим в конце? -
По этой ссылке скачиваем Spring security, распаковываем архив и в папке dist видим там около 11 jar-файлов библиотек и такое же количество соответствующих им source.jar и javadoc.jar. Кроме того в этой папке должна быть пара war-архивов. Мы будем пользоваться архивом spring-security-samples-tutorial-3.1.2.RELEASE.war (ваша версия может быть другой).
Вообще-то это вполне законченное web-приложение. Этот архив можно положить в папку webapps своего томката, запустить его и посмотреть на результат в браузере по адресу:
http://localhost:8080/spring-security-samples-tutorial-3.1.2.RELEASE
Но поскольку мы хотим всё сделать сами, мы воспользуемся этим архивом, чтобы вытащить из него всё самое ценное, а потом сверху поместить свой логотип.
- страничку авторизации на основе jsp, чтобы в наше приложение могли зайти только правильные пользователи, и чтобы каждому зашедшему мы могли выдать его информацию и ничью больше.
- на всех защищённых страницах должна быть ссылка логаута, после клика по которой клиентский компьютер и сервер должны забыть, кто только что был авторизован.
В этом примере не будет ни одного java-класса, здесь рассматриваются только вопросы конфигурирования приложения с помощью xml-файлов и некоторые
Эта статья является упрощением англоязычной статьи, находящейся здесь.
По этой ссылке скачиваем Spring security, распаковываем архив и в папке dist видим там около 11 jar-файлов библиотек и такое же количество соответствующих им source.jar и javadoc.jar. Кроме того в этой папке должна быть пара war-архивов. Мы будем пользоваться архивом spring-security-samples-tutorial-3.1.2.RELEASE.war (ваша версия может быть другой).
Вообще-то это вполне законченное web-приложение. Этот архив можно положить в папку webapps своего томката, запустить его и посмотреть на результат в браузере по адресу:
http://localhost:8080/spring-security-samples-tutorial-3.1.2.RELEASE
Но поскольку мы хотим всё сделать сами, мы воспользуемся этим архивом, чтобы вытащить из него всё самое ценное, а потом сверху поместить свой логотип.
Поэтому разархивируем вышеуказанный war-архив и из папки WEB-INF/lib забираем все jar-ы в аналогичную папку своего проекта:
В папке WEB-INF создаём файл web.xml:
Поскольку мы в web.xml объявили сервлет bank, мы обязаны создать в той же папке /war/WEB-INF конфигурационный файл для него bank-servlet.xml (имя этого конфигурационного файла формируется путём дописывания к имени сервлета строки "-servlet.xml"):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
В папку src кладём xml-файл:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!-- тег, ответственный за очень подробное логирование при использовании spring security -->
<debug />
<global-method-security pre-post-annotations="enabled" />
<http pattern="/static/**" security="none"/>
<http pattern="/loggedout.jsp" security="none"/>
<http use-expressions="true">
<intercept-url pattern="/secure/extreme/**" access="hasRole('supervisor')"/>
<intercept-url pattern="/secure/**" access="isAuthenticated()" />
<!--
Allow all other requests. In a real application you should
adopt a whitelisting approach where access is not allowed by default
-->
<intercept-url pattern="/**" access="permitAll" />
<form-login />
<logout logout-success-url="/loggedout.jsp" delete-cookies="JSESSIONID"/>
<remember-me />
<!--
Uncomment to enable X509 client authentication support
<x509 />
-->
<!-- Uncomment to limit the number of sessions a user can have -->
<!--
<session-management invalid-session-url="/timeout.jsp">
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
</session-management>
-->
</http>
<!--
Usernames/Passwords are
rod/koala
dianne/emu
scott/wombat
peter/opal
-->
<beans:bean id="encoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder"/>
<authentication-manager>
<authentication-provider>
<password-encoder ref="encoder"/>
<user-service>
<user name="rod" password="4efe081594ce25ee4efd9f7067f7f678a347bccf2de201f3adf2a3eb544850b465b4e51cdc3fcdde" authorities="supervisor, user, teller" />
<user name="dianne" password="957ea522524a41cbfb649a3e293d56268f840fd5b661b499b07858bc020d6d223f912e3ab303b00f" authorities="user,teller" />
<user name="scott" password="fb1f9e48058d30dc21c35ab4cf895e2a80f2f03fac549b51be637196dfb6b2b7276a89c65e38b7a1" authorities="user" />
<user name="peter" password="e175750688deee19d7179d444bfaf92129f4eea8b4503d83eb8f92a7dd9cda5fbae73638c913e420" authorities="user" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
Так же из этого проекта из папки \war возьмём jsp-файлы и css, считая, что их кастомизация - это отдельная деятельность, которая мало связана с настройкой безопасности. Копируем файлы:
index.jsp
<%@ page session="false" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="<c:url value='/static/css/tutorial.css'/>" type="text/css" />
<title>Home Page</title>
</head>
<body>
<div id="content">
<h1>Home Page</h1>
<p>
Anyone can view this page.
</p>
<p>
While anyone can also view the <a href="listAccounts.html">list accounts</a> page, you must be authorized to post to an Account from the list accounts page.
</p>
<p>
Your principal object is....: <%= request.getUserPrincipal() %>
</p>
<sec:authorize url='/secure/index.jsp'>
<p>
You can currently access "/secure" URLs.
</p>
</sec:authorize>
<sec:authorize url='/secure/extreme/index.jsp'>
<p>
You can currently access "/secure/extreme" URLs.
</p>
</sec:authorize>
<p>
<a href="secure/index.jsp">Secure page</a></p>
<p><a href="secure/extreme/index.jsp">Extremely secure page</a></p>
</div>
</body>
</html>
Итоговая структура файлов и папок должна выглядеть так:
- aopalliance-1.0.jar
- jcl-over-slf4j-1.6.1.jar
- jstl-1.2.jar
- logback-classic-0.9.29.jar
- logback-core-0.9.29.jar
- slf4j-api-1.6.1.jar
- spring-aop-3.0.7.RELEASE.jar
- spring-asm-3.0.7.RELEASE.jar
- spring-beans-3.0.7.RELEASE.jar
- spring-context-3.0.7.RELEASE.jar
- spring-context-support-3.0.7.RELEASE.jar
- spring-core-3.0.7.RELEASE.jar
- spring-expression-3.0.7.RELEASE.jar
- spring-security-config-3.1.2.RELEASE.jar
- spring-security-core-3.1.2.RELEASE.jar
- spring-security-crypto-3.1.2.RELEASE.jar
- spring-security-taglibs-3.1.2.RELEASE.jar
- spring-security-web-3.1.2.RELEASE.jar
- spring-web-3.0.7.RELEASE.jar
- spring-webmvc-3.0.7.RELEASE.jar
В папке WEB-INF создаём файл web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
В папку src кладём xml-файл:
- applicationContext-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!-- тег, ответственный за очень подробное логирование при использовании spring security -->
<debug />
<global-method-security pre-post-annotations="enabled" />
<http pattern="/static/**" security="none"/>
<http pattern="/loggedout.jsp" security="none"/>
<http use-expressions="true">
<intercept-url pattern="/secure/extreme/**" access="hasRole('supervisor')"/>
<intercept-url pattern="/secure/**" access="isAuthenticated()" />
<!--
Allow all other requests. In a real application you should
adopt a whitelisting approach where access is not allowed by default
-->
<intercept-url pattern="/**" access="permitAll" />
<form-login />
<logout logout-success-url="/loggedout.jsp" delete-cookies="JSESSIONID"/>
<remember-me />
<!--
Uncomment to enable X509 client authentication support
<x509 />
-->
<!-- Uncomment to limit the number of sessions a user can have -->
<!--
<session-management invalid-session-url="/timeout.jsp">
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
</session-management>
-->
</http>
<!--
Usernames/Passwords are
rod/koala
dianne/emu
scott/wombat
peter/opal
-->
<beans:bean id="encoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder"/>
<authentication-manager>
<authentication-provider>
<password-encoder ref="encoder"/>
<user-service>
<user name="rod" password="4efe081594ce25ee4efd9f7067f7f678a347bccf2de201f3adf2a3eb544850b465b4e51cdc3fcdde" authorities="supervisor, user, teller" />
<user name="dianne" password="957ea522524a41cbfb649a3e293d56268f840fd5b661b499b07858bc020d6d223f912e3ab303b00f" authorities="user,teller" />
<user name="scott" password="fb1f9e48058d30dc21c35ab4cf895e2a80f2f03fac549b51be637196dfb6b2b7276a89c65e38b7a1" authorities="user" />
<user name="peter" password="e175750688deee19d7179d444bfaf92129f4eea8b4503d83eb8f92a7dd9cda5fbae73638c913e420" authorities="user" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
Так же из этого проекта из папки \war возьмём jsp-файлы и css, считая, что их кастомизация - это отдельная деятельность, которая мало связана с настройкой безопасности. Копируем файлы:
- index.jsp - стартовая страница приложения
- loggedout.jsp - страница, куда будет перенаправлен пользователь после логаута
- timeout.jsp - страница, куда будет перенаправлен пользователь после истечения времени жизни сессии (и какой-то другой недействительности сессии)
- secure/index.jsp - безопасная страница, доступ к ней предоставляется только когда метод isAuthenticated() возвращает true
- secure/extreme/index.jsp - особо безопасная страница для пользователей с заданной ролью supervisor
- static/css/tutorial.css - файл стилей приложения
index.jsp
<%@ page session="false" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="<c:url value='/static/css/tutorial.css'/>" type="text/css" />
<title>Home Page</title>
</head>
<body>
<div id="content">
<h1>Home Page</h1>
<p>
Anyone can view this page.
</p>
<p>
While anyone can also view the <a href="listAccounts.html">list accounts</a> page, you must be authorized to post to an Account from the list accounts page.
</p>
<p>
Your principal object is....: <%= request.getUserPrincipal() %>
</p>
<sec:authorize url='/secure/index.jsp'>
<p>
You can currently access "/secure" URLs.
</p>
</sec:authorize>
<sec:authorize url='/secure/extreme/index.jsp'>
<p>
You can currently access "/secure/extreme" URLs.
</p>
</sec:authorize>
<p>
<a href="secure/index.jsp">Secure page</a></p>
<p><a href="secure/extreme/index.jsp">Extremely secure page</a></p>
</div>
</body>
</html>
loggedout.jsp
<%@page session="false" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="<c:url value='/static/css/tutorial.css'/>" type="text/css" />
<title>Logged Out</title>
</head>
<body>
<div id="content">
<h2>Logged Out</h2>
<p>
You have been logged out. <a href="<c:url value='/'/>">Start again</a>.
</p>
</div>
</body>
</html>
timeout.jsp
<%@page session="false" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="<c:url value='/static/css/tutorial.css'/>" type="text/css" />
<title>Session Timeout</title>
</head>
<body>
<div id="content">
<h2>Invalid Session</h2>
<p>
Your session appears to have timed out. Please <a href="<c:url value='/'/>">start again</a>.
</p>
</div>
</body>
</html>
secure/index.jsp
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="<c:url value='/static/css/tutorial.css'/>" type="text/css" />
<title>Secure Page</title>
</head>
<body>
<div id="content">
<h1>Secure Page</h1>
<p>
This is a protected page. You can get to me if you've been remembered,
or if you've authenticated this session.
</p>
<p>
<sec:authorize access="hasRole('supervisor')">
You are a supervisor! You can therefore see the <a href="extreme/index.jsp">extremely secure page</a>.<br/><br/>
</sec:authorize>
</p>
<h3>Properties obtained using <sec:authentication /> tag</h3>
<table border="1">
<tr><th>Tag</th><th>Value</th></tr>
<tr>
<td><sec:authentication property='name' /></td><td><sec:authentication property="name"/></td>
</tr>
<sec:authorize access="isAuthenticated()">
<tr>
<td><sec:authentication property='principal.username' /></td><td><sec:authentication property="principal.username"/></td>
</tr>
<tr>
<td><sec:authentication property='principal.enabled' /></td><td><sec:authentication property="principal.enabled"/></td>
</tr>
<tr>
<td><sec:authentication property='principal.accountNonLocked' /></td><td><sec:authentication property="principal.accountNonLocked"/></td>
</tr>
</sec:authorize>
</table>
<p><a href="../">Home</a></p>
<p><a href="../j_spring_security_logout">Logout</a></p>
</div>
</body>
</html>
secure/extreme/index.jsp
<%@ taglib prefix="authz" uri="http://www.springframework.org/security/tags" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="<c:url value='/static/css/tutorial.css'/>" type="text/css" />
<title>Secure Page</title>
</head>
<body>
<div id="content">
<h1>VERY Secure Page</h1>
This is a protected page. You can only see me if you are a supervisor.
<authz:authorize access="hasRole('supervisor')">
You have authority "supervisor" (this text is surrounded by <authz:authorize> tags).
</authz:authorize>
<p><a href="../../">Home</a></p>
<p><a href="../../j_spring_security_logout">Logout</a></p>
</div>
</body>
</html>
static/css/tutorial.css
body {
font-family:"Palatino Linotype","Book Antiqua",Palatino,serif;
}
#content {
margin: 5em auto;
width: 40em;
}
.securityHiddenUI, .securityHiddenUI * {
background-color: #ff4500;
}
Итоговая структура файлов и папок должна выглядеть так:
