Skip to content

Commit fcf60b1

Browse files
committed
Introduced Spring Security support.
Fixed #87
1 parent 8fa0ffd commit fcf60b1

34 files changed

+616
-581
lines changed

NEWS.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
0.2 (not released yet)
2+
- introduced Spring Security support
23
- ported DAO layer to use Spring-Data
34
- ported unit and functional tests to TestNG
45
- migrated from HSQL to H2 (in test environment)

pom.xml

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<slf4j.version>1.6.5</slf4j.version>
2020
<spring.version>3.2.0.M1</spring.version>
2121
<spring.data.version>1.1.0.RELEASE</spring.data.version>
22+
<spring.security.version>3.1.0.RELEASE</spring.security.version>
2223
<h2.version>1.3.167</h2.version>
2324
<javax.validation.version>1.1.0.Alpha1</javax.validation.version>
2425

@@ -112,6 +113,36 @@
112113
<scope>runtime</scope>
113114
</dependency>
114115

116+
<dependency>
117+
<groupId>org.springframework.security</groupId>
118+
<artifactId>spring-security-web</artifactId>
119+
<version>${spring.security.version}</version>
120+
</dependency>
121+
122+
<!--
123+
spring-security-web 3.1.0 depends from spring-aop 3.0.6,
124+
so to force application use spring-aop 3.1.1 we add this
125+
dependency explicitly. May be removed when new Spring
126+
Security will not depends from old version of Spring.
127+
-->
128+
<dependency>
129+
<groupId>org.springframework</groupId>
130+
<artifactId>spring-aop</artifactId>
131+
<version>${spring.version}</version>
132+
</dependency>
133+
134+
<dependency>
135+
<groupId>org.springframework.security</groupId>
136+
<artifactId>spring-security-config</artifactId>
137+
<version>${spring.security.version}</version>
138+
</dependency>
139+
140+
<dependency>
141+
<groupId>org.springframework.security</groupId>
142+
<artifactId>spring-security-taglibs</artifactId>
143+
<version>${spring.security.version}</version>
144+
</dependency>
145+
115146
<dependency>
116147
<groupId>org.hibernate</groupId>
117148
<artifactId>hibernate-core</artifactId>
@@ -132,12 +163,6 @@
132163
<version>3.1</version>
133164
</dependency>
134165

135-
<dependency>
136-
<groupId>commons-codec</groupId>
137-
<artifactId>commons-codec</artifactId>
138-
<version>1.6</version>
139-
</dependency>
140-
141166
<dependency>
142167
<groupId>commons-beanutils</groupId>
143168
<artifactId>commons-beanutils</artifactId>

src/env/dev/WEB-INF/web.xml

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,30 @@
1212
<param-value>dev</param-value>
1313
</context-param>
1414

15+
<context-param>
16+
<param-name>contextClass</param-name>
17+
<param-value>
18+
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
19+
</param-value>
20+
</context-param>
21+
22+
<context-param>
23+
<param-name>contextConfigLocation</param-name>
24+
<param-value>
25+
ru.mystamps.web.config.ApplicationContext,
26+
ru.mystamps.web.config.DevDataSource
27+
</param-value>
28+
</context-param>
29+
30+
<listener>
31+
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
32+
</listener>
33+
34+
<!-- To expose user's request to AuthenticationFailureListener where we need it for logging -->
35+
<listener>
36+
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
37+
</listener>
38+
1539
<servlet>
1640
<servlet-name>spring</servlet-name>
1741
<servlet-class>
@@ -26,8 +50,7 @@
2650
<init-param>
2751
<param-name>contextConfigLocation</param-name>
2852
<param-value>
29-
ru.mystamps.web.config.DispatcherServletContext,
30-
ru.mystamps.web.config.DevDataSource
53+
ru.mystamps.web.config.DispatcherServletContext
3154
</param-value>
3255
</init-param>
3356
<load-on-startup>1</load-on-startup>
@@ -71,4 +94,16 @@
7194
<url-pattern>/*</url-pattern>
7295
</filter-mapping>
7396

97+
<filter>
98+
<filter-name>springSecurityFilterChain</filter-name>
99+
<filter-class>
100+
org.springframework.web.filter.DelegatingFilterProxy
101+
</filter-class>
102+
</filter>
103+
104+
<filter-mapping>
105+
<filter-name>springSecurityFilterChain</filter-name>
106+
<url-pattern>/*</url-pattern>
107+
</filter-mapping>
108+
74109
</web-app>

src/env/test/WEB-INF/classes/spring/test-credentials.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ valid_user_login = coder
77
valid_user_name = Test Suite
88
valid_user_password = test
99

10-
# Auto-calculated by SELECT SHA1(CONCAT('${salt}', '${password}'));
10+
# Auto-calculated by SELECT SHA1(CONCAT('${salt}', '{', '${password}', '}'));
1111
valid_user_password_salt = cEjinQJY3v
12-
valid_user_password_hash = 9a08f1a38b780eaa610e72c01db055ebee6e9d85
12+
valid_user_password_hash = 27e04fc489395d3167d8dd71fc47e466ee190aee
1313

1414
# this user should always NOT exist
1515
invalid_user_login = test

src/env/test/WEB-INF/web.xml

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,30 @@
1212
<param-value>test</param-value>
1313
</context-param>
1414

15+
<context-param>
16+
<param-name>contextClass</param-name>
17+
<param-value>
18+
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
19+
</param-value>
20+
</context-param>
21+
22+
<context-param>
23+
<param-name>contextConfigLocation</param-name>
24+
<param-value>
25+
ru.mystamps.web.config.ApplicationContext,
26+
ru.mystamps.web.config.TestDataSource
27+
</param-value>
28+
</context-param>
29+
30+
<listener>
31+
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
32+
</listener>
33+
34+
<!-- To expose user's request to AuthenticationFailureListener where we need it for logging -->
35+
<listener>
36+
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
37+
</listener>
38+
1539
<servlet>
1640
<servlet-name>spring</servlet-name>
1741
<servlet-class>
@@ -26,8 +50,7 @@
2650
<init-param>
2751
<param-name>contextConfigLocation</param-name>
2852
<param-value>
29-
ru.mystamps.web.config.DispatcherServletContext,
30-
ru.mystamps.web.config.TestDataSource
53+
ru.mystamps.web.config.DispatcherServletContext
3154
</param-value>
3255
</init-param>
3356
<load-on-startup>1</load-on-startup>
@@ -88,4 +111,16 @@
88111
<url-pattern>/*</url-pattern>
89112
</filter-mapping>
90113

114+
<filter>
115+
<filter-name>springSecurityFilterChain</filter-name>
116+
<filter-class>
117+
org.springframework.web.filter.DelegatingFilterProxy
118+
</filter-class>
119+
</filter>
120+
121+
<filter-mapping>
122+
<filter-name>springSecurityFilterChain</filter-name>
123+
<url-pattern>/*</url-pattern>
124+
</filter-mapping>
125+
91126
</web-app>

src/main/config/checkstyle-suppressions.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,5 @@
2424
<suppress checks="WhitespaceAround" files="ru.mystamps.web.validation.jsr303.FieldsMismatch" />
2525
<suppress checks="WhitespaceAround" files="ru.mystamps.web.validation.jsr303.UniqueCountryName" />
2626
<suppress checks="WhitespaceAround" files="ru.mystamps.web.validation.jsr303.UniqueLogin" />
27-
<suppress checks="WhitespaceAround" files="ru.mystamps.web.validation.jsr303.ValidCredentials" />
2827

2928
</suppressions>

src/main/java/ru/mystamps/web/Url.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,14 @@ public final class Url {
3535
public static final String SUCCESSFUL_ACTIVATION_PAGE = "/successful/activation";
3636

3737
public static final String REGISTRATION_PAGE = "/account/register";
38+
39+
// defined at src/main/resources/spring/security.xml
3840
public static final String AUTHENTICATION_PAGE = "/account/auth";
41+
public static final String LOGIN_PAGE = "/account/login";
42+
public static final String LOGOUT_PAGE = "/account/logout";
43+
3944
public static final String ACTIVATE_ACCOUNT_PAGE = "/account/activate";
4045
public static final String ACTIVATE_ACCOUNT_PAGE_WITH_KEY = "/account/activate/key/{key}";
41-
public static final String LOGOUT_PAGE = "/account/logout";
4246

4347
public static final String ADD_SERIES_PAGE = "/series/add";
4448

Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2009-2012 Slava Semushin <slava.semushin@gmail.com>
2+
* Copyright (C) 2012 Slava Semushin <slava.semushin@gmail.com>
33
*
44
* This program is free software; you can redistribute it and/or modify
55
* it under the terms of the GNU General Public License as published by
@@ -8,33 +8,27 @@
88
*
99
* This program is distributed in the hope that it will be useful,
1010
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1212
* GNU General Public License for more details.
1313
*
1414
* You should have received a copy of the GNU General Public License
1515
* along with this program; if not, write to the Free Software
1616
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1717
*/
1818

19-
package ru.mystamps.web.controller;
19+
package ru.mystamps.web.config;
2020

21-
import javax.servlet.http.HttpSession;
21+
import org.springframework.context.annotation.ComponentScan;
22+
import org.springframework.context.annotation.Configuration;
23+
import org.springframework.context.annotation.Import;
2224

23-
import org.springframework.stereotype.Controller;
24-
import org.springframework.web.bind.annotation.RequestMapping;
25-
import org.springframework.web.bind.annotation.RequestMethod;
26-
27-
import ru.mystamps.web.Url;
28-
29-
@Controller
30-
@RequestMapping(Url.LOGOUT_PAGE)
31-
public class LogoutAccountController {
32-
33-
@RequestMapping(method = RequestMethod.GET)
34-
public String logout(final HttpSession session) {
35-
session.invalidate();
36-
return "redirect:" + Url.INDEX_PAGE;
37-
}
38-
25+
@Configuration
26+
@Import({
27+
DbConfig.class,
28+
SecurityConfig.class
29+
})
30+
@ComponentScan(basePackages = {
31+
"ru.mystamps.web.service"
32+
})
33+
public class ApplicationContext {
3934
}
40-

src/main/java/ru/mystamps/web/config/DispatcherServletContext.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@
2222
import org.springframework.context.annotation.Import;
2323

2424
@Configuration
25-
@Import({
26-
DbConfig.class,
27-
MvcConfig.class
28-
})
25+
@Import(MvcConfig.class)
2926
public class DispatcherServletContext {
3027
}

src/main/java/ru/mystamps/web/config/MvcConfig.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,15 @@
1818

1919
package ru.mystamps.web.config;
2020

21+
import java.util.List;
22+
2123
import org.springframework.context.annotation.Bean;
2224
import org.springframework.context.annotation.ComponentScan;
2325
import org.springframework.context.annotation.Configuration;
2426
import org.springframework.context.MessageSource;
2527
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
2628
import org.springframework.scheduling.annotation.EnableScheduling;
29+
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
2730
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
2831
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
2932
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
@@ -32,14 +35,14 @@
3235
import org.springframework.web.servlet.view.InternalResourceViewResolver;
3336
import org.springframework.web.servlet.ViewResolver;
3437

38+
import ru.mystamps.web.support.spring.security.CustomUserDetailsArgumentResolver;
3539
import ru.mystamps.web.Url;
3640

3741
@Configuration
3842
@EnableWebMvc
3943
@EnableScheduling
4044
@ComponentScan(basePackages = {
41-
"ru.mystamps.web.controller",
42-
"ru.mystamps.web.service"
45+
"ru.mystamps.web.controller"
4346
})
4447
public class MvcConfig extends WebMvcConfigurerAdapter {
4548

@@ -50,6 +53,7 @@ public void configureDefaultServletHandling(final DefaultServletHandlerConfigure
5053

5154
@Override
5255
public void addViewControllers(final ViewControllerRegistry registry) {
56+
registry.addViewController(Url.AUTHENTICATION_PAGE);
5357
registry.addViewController(Url.INDEX_PAGE).setViewName("site/index");
5458
registry.addViewController(Url.RESTORE_PASSWORD_PAGE);
5559
registry.addViewController(Url.SUCCESSFUL_ACTIVATION_PAGE);
@@ -61,6 +65,11 @@ public void addResourceHandlers(final ResourceHandlerRegistry registry) {
6165
registry.addResourceHandler("/static/**").addResourceLocations("/WEB-INF/static/*");
6266
}
6367

68+
@Override
69+
public void addArgumentResolvers(final List<HandlerMethodArgumentResolver> argumentResolvers) {
70+
argumentResolvers.add(new CustomUserDetailsArgumentResolver());
71+
}
72+
6473
@Bean
6574
public ViewResolver getViewResolver() {
6675
final InternalResourceViewResolver viewResolver =

0 commit comments

Comments
 (0)