Spring boot 2.2.6을 이용한 웹 어플리케이션 기본 프로젝트로 만든 것이다. Thymeleaf 템플릿엔진을 이용하고 W3.CSS를 사용하여 html/css 퍼블리싱을 한다.
html/css, font 등 디자인 자원
W3.CSS를 이용하여 html 화면 디자인을 처리한다. Material Design 템플릿을 기본 레이아웃으로 설정하였다.
이미지를 만들 때 PNG 파일의 백그라운드를 제거하여 투명하게 만들 때는 removebg 홈페이지를 이용한다. 백그라운드를 제거하고자 하는 이미지 파일을 드래그앤드롭하여 온라인으로 바로 투명한 백그라운드 갖는 PNG 파일을 얻을 수 있어 유용하다.
폰트는 네이버에서 제공하는 나눔스퀘어라운드를 사용한다. TTF 폰트를 다운받아서 Online Font Convenverter에서 EOT
, WOFF
, WOFF2
등으로 변환하여 사용하였다.
1
2
3
4
5
6
7
8
9
10
11
12
13
@font-face {
font-family: "NanumSquareRoundR";
src: url("./fonts/NanumSquareRoundR.eot"); /* IE9 Compat Modes */
src: url("./fonts/NanumSquareRoundR.eot?#iefix") format("embedded-opentype"), /* IE6-IE8 */
url("./fonts/NanumSquareRoundR.otf") format("opentype"), /* Open Type Font */
url("./fonts/NanumSquareRoundR.svg") format("svg"), /* Legacy iOS */
url("./fonts/NanumSquareRoundR.ttf") format("truetype"), /* Safari, Android, iOS */
url("./fonts/NanumSquareRoundR.woff") format("woff"), /* Modern Browsers */
url("./fonts/NanumSquareRoundR.woff2") format("woff2"); /* Modern Browsers */
font-weight: normal;
font-style: normal;
}
body {font-family: "NanumSquareRoundR", sans-serif}
Thymeleaf 템플릿엔진 사용
Thymeleaf를 템플릿엔진으로 사용한다.
Thymeleaf Layout Dialect에서 제공하는 nz.net.ultraq.thymeleaf
라이브러리를 추가하여 레이아웃 설정을 추가하였다. 다음 디펜던시가 추가되야 한다.
1
2
3
4
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>
MVC 설정에 타임리프 템플릿엔진 설정하는 부분에 templateEngine.addDialect(new LayoutDialect());
로 layout-dialect를 추가해줘야 한다.
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
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
/**
* 타임리프 속성 생성
*/
@Bean
public SpringResourceTemplateResolver templateResolver() {
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setPrefix("classpath:templates/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode(TemplateMode.HTML);
templateResolver.setCharacterEncoding("UTF-8");
// TODO: Template cache is true by default. Set to false if you want
// templates to be automatically updated when modified.
templateResolver.setCacheable(false);
return templateResolver;
}
/**
* 타임리프 dialect 추가
*/
@Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setEnableSpringELCompiler(true); // Compiled SpringEL should speed up executions
templateEngine.setTemplateResolver(templateResolver());
templateEngine.addDialect(new LayoutDialect()); // nz.net.ultraq.thymeleaf 레이아웃 관리 추가
return templateEngine;
}
@Bean
public ThymeleafViewResolver viewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
viewResolver.setCharacterEncoding("UTF-8");
viewResolver.setOrder(0);
return viewResolver;
}
}
XSS 공격 방어 필터 적용
XSS(Cross-site-scripting) 공격에 대처하기 위하여 get/post 파라미터 및 request body에 필터를 적용한다.
GET/POST 파라미터에 XSS 공격 방어 필터 적용
많이 사용되는 네이버 lucy-xss-servlet-filter 라이브러리를 사용한다. 아래 디펜던시가 추가한다.
1
2
3
4
5
<dependency>
<groupId>com.navercorp.lucy</groupId>
<artifactId>lucy-xss-servlet</artifactId>
<version>2.0.0</version>
</dependency>
MVC 설정에 필터를 등록한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
/**
* XSS 필터 적용
*/
@Bean
public FilterRegistrationBean<XssEscapeServletFilter> getXssEscapeServletFilterRegistrationBean() {
FilterRegistrationBean<XssEscapeServletFilter> registrationBean = new FilterRegistrationBean<XssEscapeServletFilter>();
registrationBean.setFilter(new XssEscapeServletFilter());
registrationBean.setOrder(1);
registrationBean.addUrlPatterns("/*"); // filter를 거칠 url patterns
return registrationBean;
}
}
request body에 XSS 공격 방어 필터 적용
Ajax나 restful api 시에 사용되는 request body에는 lucy 필터가 적용되지 않는다고 한다. request body에 XSS 공격 방어 필터도 같이 적용한다. 필터링을 담당하는 클래스 HTMLCharacterEscapes
를 생성하고:
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
public class HTMLCharacterEscapes extends CharacterEscapes {
private final int[] asciiEscapes;
private final CharSequenceTranslator translator;
public HTMLCharacterEscapes() {
Map<CharSequence, CharSequence> customMap = new HashMap<>();
customMap.put("(", "(");
Map<CharSequence, CharSequence> CUSTOM_ESCAPE = Collections.unmodifiableMap(customMap);
// XSS 방지 처리할 특수 문자 지정
asciiEscapes = CharacterEscapes.standardAsciiEscapesForJSON();
asciiEscapes['<'] = CharacterEscapes.ESCAPE_CUSTOM;
asciiEscapes['>'] = CharacterEscapes.ESCAPE_CUSTOM;
asciiEscapes['&'] = CharacterEscapes.ESCAPE_CUSTOM;
asciiEscapes['('] = CharacterEscapes.ESCAPE_CUSTOM;
// XSS 방지 처리 특수 문자 인코딩 값 지정
translator = new AggregateTranslator(new LookupTranslator(EntityArrays.BASIC_ESCAPE), // <, >, &, " 는 여기에 포함됨
new LookupTranslator(EntityArrays.ISO8859_1_ESCAPE),
new LookupTranslator(EntityArrays.HTML40_EXTENDED_ESCAPE), new LookupTranslator(CUSTOM_ESCAPE));
}
@Override
public int[] getEscapeCodesForAscii() {
return asciiEscapes;
}
@Override
public SerializableString getEscapeSequence(int ch) {
return new SerializedString(translator.translate(Character.toString((char) ch)));
}
}
MVC 설정에 Jackson
컨버터에 등록해준다.
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
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
// request body xss 추가
converters.add(escapingConverter());
}
/**
* request body xss 적용
*/
@Bean
public HttpMessageConverter<?> escapingConverter() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.getFactory().setCharacterEscapes(new HTMLCharacterEscapes());
MappingJackson2HttpMessageConverter escapingConverter = new MappingJackson2HttpMessageConverter();
escapingConverter.setObjectMapper(objectMapper);
return escapingConverter;
}
}
프로젝트 실행 화면
기본적으로 설정된 프로젝트를 실행하면 아래와 같이 W3.CSS 템플릿이 적용된 반응형 웹페이지를 확인할 수 있다.
모바일에서는 왼쪽 네비게이션 메뉴가 좌측 상단의 메뉴 버튼으로 숨겨진다.
github 프로젝트
현재 github 프로젝트에는 spring-security 관련 작업 중인 소스도 같이 들어있으나 실행하여 기본 페이지 표시에는 아무 문제가 없는 상태이다.
Reference Documentation
For further reference, please consider the following sections:
- Spring Web 2.2.6
- W3.CSS
- 나눔스퀘어라운드
- Thymeleaf
- Official Apache Maven documentation
- Spring Boot Maven Plugin Reference Guide
- Spring Boot DevTools
- Spring Configuration Processor
Guides
The following guides illustrate how to use some features concretely: