public String doE(RedirectAttributes rttr){
//logger.info("리다이렉트.....................");
rttr.addFlashAttribute("msg", "이미 등록된 사용자 입니다.");
return "redirect:/error";
}
html을 처음 배웠을 때 div를 nav, left, content, footer 등의 id를 부여하여
페이지를 제작하는 방법을 배웠었다.
요즘에는 html5가 거의 표준으로
자리잡아가면서 저것들이 아예 태그로 만들어져 나오기까지 했다.
각 영역을 분리해서 만드는 것은 여러 태그를 관리하기는 쉽지만
파일의 line수가 많아져 태그를
찾는것도 일이 되어버리고,
변경이 많이 일어나지 않는 nav,
footer 등의 코드를 중복하여 계속 넣어주어야 하는 번거로움이 있다.
하지만 tiles를 쓰면 nav, footer등의 역할을 하는 코드를 파일로 저장하여 관리하기때문에
실제 화면의 내용을 담당하는 content
부분만 제작하고, 파일 자체에도 content만
존재하게 된다.
물론 이것을 include를 사용할
수도 있지만 include를 써넣는 것도 일이 되어버리므로..
아무튼..
여러가지 이유로 이전에 만들어두었던
spring 프로젝트에 tiles를 적용해보았다.
사용한 spring 버전은 4.1.0이고, tiles는
3.0.4 이다.
1. tiles 라이브러리 추가를 위해 pom.xml 파일에 아래의 내용을 추가한다.
<!-- tiles lib -->
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-core</artifactId>
<version>3.0.4</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-jsp</artifactId>
<version>3.0.4</version>
</dependency>
2. tiles bean 등록을 위해 servlet-context.xml 파일에 아래의 내용을 추가한다.
기본적으로
등록되어있는 org.springframework.web.servlet.view.InternalResourceViewResolver는
일반 jsp 파일로 처리할 경우에 필요하므로 남겨두었다.
<!-- tiles 리졸버 -->
<beans:bean
class="org.springframework.web.servlet.view.tiles3.TilesViewResolver"
/>
<!-- tiles 설정파일
-->
<beans:bean class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<beans:property
name="definitions">
<beans:list>
<beans:value>/resources/tiles/*.xml</beans:value>
</beans:list>
</beans:property>
</beans:bean>
3. tiles의 레이아웃을 정의한다.
2번에서 tiles
bean 등록시 사용한 경로인 /resources/tiles/ 밑에 tiles.xml 파일을 생성하고
자신이 사용하고자 하는 layout을 정의한다.
<?xml
version="1.0" encoding="utf-8" ?>
<!DOCTYPE
tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration
3.0//EN"
"http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
<!-- Definitions for
Tiles documentation -->
<tiles-definitions>
<!-- Doc index page
description -->
<definition
name="layout" template="/WEB-INF/jsp/layout/layout.jsp">
<put-attribute
name="top" value="/WEB-INF/jsp/layout/top.jsp"/>
<put-attribute
name="left" value="/WEB-INF/jsp/layout/left.jsp"/>
<put-attribute
name="content" value=""/>
</definition>
<definition
name="*" extends="layout">
<put-attribute
name="content" value="/WEB-INF/jsp/{1}.jsp"/>
</definition>
<definition
name="*/*" extends="layout">
<put-attribute
name="content" value="/WEB-INF/jsp/{1}/{2}.jsp"/>
</definition>
<definition
name="*/*/*" extends="layout">
<put-attribute
name="content" value="/WEB-INF/jsp/{1}/{2}/{3}.jsp"/>
</definition>
</tiles-definitions>
나의 경우에는 top, left 네비게이션과
content를 구성할 목적으로 설정을 해주었다.
definition name에는
controller에서 return하는 string을
적어주는 것으로
예를 들어 controller의 return 값이 "user"일 경우라면, /WEB-INF/jsp/user.jsp를 찾아 화면에 표시한다.
따라서 원래의 사용법은 아래와 같다.
<definition
name="user" extends="layout">
<put-attribute name="content"
value="//WEB-INF/jsp/user.jsp"/>
</definition>
그러나 definition name을 위와 같이 '*'로 설정하게 되면 attribute의 value에서
'{1}'과 같이 사용할 수가 있다.
*의 갯수만큼 {1},
{2} 등으로 사용하게 되는데 이를 '와일드카드'라고
한다.
tiles의 장점은 여러개의 layout을 만들어서 필요에 맞게 사용할 수 있다는 점이다.
또한 특정 layout을 사용하지 않을수도 있는데
그런 경우에는 아래와 같이 작성하면 된다.
<definition
name="user/login"
template="/WEB-INF/jsp/user/login.jsp"/>
4. layout.jsp 파일 구성
definition 파일 구성에 제작한 대로 layout.jsp, top.jsp, left.jsp 를 생성해준다.
top.jsp와 left.jsp는
자신의 웹프로젝트에서 사용하고자하는 내용을 넣어서 제작하면 되므로 여기서는 생략하고 layout.jsp만
만들어보도록 하겠다.
layout.jsp에서는 각 페이지들에서 공통으로 사용할 css, js 파일등을 포함시켜준다.
또한 파일 상단에 taglib를 추가해준다.
<%@ taglib
prefix="t" uri="http://tiles.apache.org/tags-tiles"
%>
layout파일에는 html,
head, body 태그를 포함시켜서 만들어주고
top, left, content 등의 파일에서는 바로 내용을 작성하면 된다.
<body>
<div class="navbar
navbar-fixed-top navbar-inverse" role="navigation">
<t:insertAttribute
name="top"/>
</div>
<div
class="container">
<t:insertAttribute
name="left"/>
<t:insertAttribute
name="content"/>
</div>
</body>
위와 같이 작성된 jsp를 포함시킬때에는 <t:inserAttribute>태그를 사용하면 된다.
> 5. 결과보기
5. 결과보기
모든 설정을 마치고나서 css를 적용시키면 페이지 layout이 완성된다.
css를 잘 모르거나, 마땅한것이
없다 싶으면 부트스트랩을 적용하면 된다.
아래는 부트스트랩에서 제공하는 상단과 왼쪽 네비게이션을 적용한 화면이다.
스프링 프레임워크만으로 권한
처리를 하려면 꽤 골치가 아프다.
사용자의 role을 조회해서 사용자VO에 넣어주고, 또 페이지마다 권한이 있는지 없는지 체크해줘야하고
신경써야할것이 매우 많다!
그러나 Spring
security는 로그인시 인증과 권한 처리를 도와준다.
인증이라 함은 해당 사용자가 등록된 사용자인지 아닌지를 가려주는 것을 말하고
권한 처리는 사용자의 역할별로 연결되는 페이지를 다르게 해주는 것이다.
그래서 오늘은 spring security를
이용한 login 처리를 해보도록 하겠다.
먼저 spring security의
버전을 선택해야 한다.
나의 경우에는 spring security는 3.2.6.RELEASE 버전을 사용했고
spring은 4.0.2.RELEASE 버전을 사용했다.
1. spring security 라이브러리 추가
1. pom.xml에 spring security 라이브러리를 추가한다.
1.1 dependency 추가
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>3.2.6.RELEASE</version>
</dependency>
1.2 dependencyManagement
추가 (충돌방지를 위하여 추가함)
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>4.0.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2. 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>
3.1
security-context.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"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/m ··· -4.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/s ··· -3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/b ··· eans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/c ··· -4.1.xsd">
<mvc:annotation-driven/>
<security:http
auto-config="true">
<security:intercept-url pattern="/teacher/*"
access="ROLE_USER" />
<security:form-login login-page="/login"
default-target-url="/teacher/main"
authentication-failure-url="/loginFail"/>
<security:logout logout-success-url="/logout"/>
</security:http>
<security:authentication-manager>
<security:authentication-provider user-service-ref="memberService"
/>
</security:authentication-manager>
<context:component-scan
base-package="com.spring" />
</beans>
intercept-url : 권한적용할 곳 정보
- access : 접근가능한 권한
login-page : 로그인 페이지
default-target-url
: 로그인 후 이동할 페이지
authentication-failure-url
: 로그인 실패시 이동할 페이지
logout-success-url
: 로그아웃시 이동할 페이지
3.2 web.xml의 context-param value에 security-context.xml 등록한다.
나같은 경우에는 param-value를 /WEB-INF/spring/*-context.xml 로 변경해주었다.
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/*-context.xml
</param-value>
</context-param>
4. UserDetailsService 구현
4. UserDetailsService를 구현한다.
DB에 등록된 role 정보가
ROLE_USER일 경우 ROLE_USER로, 아닌경우 ROLE_USER2로 생성하기 위하여 아래와 같이 작성하였다.
@Service
public class
MemberService implements UserDetailsService{
@Autowired
private UserDaoMapper userdao;
@Override
public UserDetails loadUserByUsername(String
username)
throws UsernameNotFoundException {
UserVO vo = userdao.findUser(username);
String userPwd = vo.getUserPwd();
String role = vo.getUserType();
System.out.println("userPwd : " +
userPwd);
System.out.println("role : " +
role);
Collection<SimpleGrantedAuthority>
roles = new ArrayList<SimpleGrantedAuthority>();
if("ROLE_USER".equals(role))
roles.add(new
SimpleGrantedAuthority("ROLE_USER"));
else
roles.add(new SimpleGrantedAuthority("ROLE_USER2"));
UserDetails user = new User(username,
userPwd, roles);
return user;
}
}
여기까지 마쳤으면 사용자
정보를 가져오기 위한 dao와 sql을 작성하고,
로그인, 로그아웃, 로그인 실패 페이지를 각각 작성해주면 spring security 적용이
완료된다.
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |