암호화를 하기 전에 가입된 데이터는 패스워드가 암호화되어 있지 않습니다. 이 기능은 spring securtiy와 상관없이 암호화되지 않은 전 사원의 패스워드를 암호화하기 위해 추가한 기능입니다.

admin의 권한을 갖고 있는 사원만 접근할 수 있으며 실행하면 전사원의 비밀번호를 암호화 할 수 있는 페이지가 실행되며 패스워드를 암호화하고 싶은 사원을 체크하고 [비밀번호변경] 버튼을 누르면 선택한 사원의 패스워드가 암호화될 수 있도록 처리하도록 하겠습니다.

 

위의 작업을 수행하기 위해서는 사원 전체 목록을 출력할 수 있어야 하며 체크박스로 선택한 사원의 모든 패스워드를 암호화하여 update 할 수 있어야 합니다. 

암호화하면 문자열이 길어지므로 컬럼의 사이즈를 수정하고 작업합니다.

 

[step01 - 전체 회원목록 출력하기]

관리자 페이지 왼쪽 메뉴에서 [비밀번호변경] 을 클릭하면  전 사원의 목록이 다음과 같이 출력되어야 합니다. 

 

관리자의 기능이므로 ktds.erp.admin패키지를 추가하고 작업합니다.

 

emp.xml

전 사원을 조회할 수 있도록 emp.xml mapper에 다음과 같이 <select> 태그를 추가합니다.

<select id="selectAll" resultType="emp">
	select * from member
</select>

 

AdminDAO

package ktds.erp.admin;

import java.util.ArrayList;
import java.util.List;

import ktds.erp.emp.MemberDTO;

public interface AdminDAO {
	//전체 사원을 조회하기
	List<MemberDTO> getMemberList();
	//암호화하기 위해 체크한 사원의 목록을 조회하기
	List<MemberDTO> getCheckList(ArrayList<String> idlist);
	//암호화하기 위해 체크한 사원의 비밀번호를 암호화한 비밀번호로 업데이트하기
	int update(List<MemberDTO> userlist);
}

 

AdminDAOImpl

전체 사원 목록을 조회할 mapper의 아이디를 정의하고 실행될 수 있도록 코드를 작성합니다.

package ktds.erp.admin;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import ktds.erp.emp.MemberDTO;
@Repository
public class AdminDAOImpl implements AdminDAO {
	@Autowired
	SqlSession sqlSession;
	@Override
	public List<MemberDTO> getMemberList() {
		return sqlSession.selectList("ktds.erp.emp.selectAll");
	}
	@Override
	public List<MemberDTO> getCheckList(ArrayList<String> idlist) {
		return null;
	}
	@Override
	public int update(List<MemberDTO> userlist) {
		return 0;
	}

}

 

AdminService

DAO의 메소드를 호출할 Service를 작성합니다. 특이 사항은 DAO에는 메서드를 세 개 정의하였지만 Service에는 메서드를 두 개만 정의합니다. 패스워드 변경 기능에 조회하여 기능하는 두 가지 메서드가 포함되어 있습니다.

class Service{

     비밀번호암호화하기(){

           체크한 사원 목록 조회하기();

           조회한 사원의 비밀번호 암호화하기();

     }

}

class DAO{

     체크한 사원 목록 조회하기(){

 

     }

     조회한 사원의 비밀번호 암호화하기(){

     }

}

package ktds.erp.admin;

import java.util.List;

import ktds.erp.emp.MemberDTO;

public interface AdminService {
	//전체 사원의 목록을 조회할 서비스의 메소드
	List<MemberDTO> getMemberList();
	
	//패스워드 변경할 서비스의 메소드
	int passwordChange(String[] id);	
}

 

AdminServiceImpl

전체 사원의 목록을 조회할 수 있도록 DAO의 메서드를 호출합니다.

package ktds.erp.admin;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.encoding.ShaPasswordEncoder;
import org.springframework.stereotype.Service;

import ktds.erp.emp.MemberDTO;
@Service
public class AdminServiceImpl implements AdminService {
	@Autowired
	AdminDAO dao;
	@Autowired
	private ShaPasswordEncoder passencoder;
	@Override
	public List<MemberDTO> getMemberList() {
		return dao.getMemberList();
	}
	@Override
	public int passwordChange(String[] id) {
		return 0;
	}

}

 

AdminController

Service의 전체 사원 조회 메서드를 호출하고 뷰와 오브젝트를 공유합니다.

package ktds.erp.admin;

import java.util.ArrayList;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import ktds.erp.emp.MemberDTO;

@Controller
public class AdminController {
	@Autowired
	AdminService service;
	@RequestMapping("/admin/member/list.do")
	public ModelAndView getMemberList() {
		ArrayList<MemberDTO> memberlist = (ArrayList<MemberDTO>)service.getMemberList();
		ModelAndView mav = new ModelAndView();
		mav.addObject("memberlist", memberlist);
		mav.setViewName("admin/memberlist");
		return mav;
      }
}

 

adminleft.jsp

전 사원의 목록을 출력할 수 있는 컨트롤러를 요청할 수 있도록 href속성을 추가합니다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<div>
		<h4>관리자페이지</h4>
		<h5><a href="/kimsaemERP/admin/member/list.do">비밀번호변경</a></h5>
		<h5><a href="#">매출분석</a></h5>
		<h5><a href="#">쇼핑몰로그분석</a></h5>
		<h5><a href="#">소셜분석</a></h5>
	
	</div>
</body>
</html>

 

/WEB-INF/에 admin폴더를 추가합니다.

 

admin-tiles.xml

admin페이지의 디자인을 추가할 수 있도록 tiles설정 파일을 추가합니다.

<?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">
<tiles-definitions>
	<definition name="admin/memberlist" extends="adminTemplate">
		<put-attribute name="content" 
				value="/WEB-INF/admin/memberlist.jsp"/>
	</definition>
	
</tiles-definitions>

 

memberlist.jsp

DB에서 조회한 데이터를 출력할 수 있도록 다음과 같이 JSTL을 이용하여 작업합니다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<title>Bootstrap Example</title>
<meta charset="UTF-8">
</head>
<body>
	<h3>회원목록</h3>
	<div style="padding-top: 30px">
	<form action="/kimsaemERP/board/search.do">
		<select name="tag">
			<option value="deptno">부서</option>
			<option value="name">성명</option>
			<option value="group">그룹</option>
			<option value="startday">입사일</option>
		</select> <input type="text" name="search" /> <input type="submit" value="검색">
		<input type="button" value="비밀번호변경" id="passmodify">
		
	</form>
	<br/>
		<table class="table">
			<thead>
				<tr>
					<th><input type="checkbox" id="all"/></th>
					<th>아이디</th>
					<th>성명</th>
					<th>부서코드</th>
					<th>입사일</th>
				</tr>
			</thead>
			<tbody>
				<c:forEach var="member" items="${memberlist}">
					<tr>
						<td><input type="checkbox" name="member" id="chk${member.id}"/></td>
						<td><input type="text" value="${member.id}" name="id" disabled="disabled"/></td>
						<td><a
							href="/kimsaemERP/board/user/read.do?board_no=${member.name}&state=READ">${member.name}</a></td>
						<%-- <td><a
							href="/kimsaemERP/board/${board.category}/${board.board_no }?state=READ">${board.title}</a></td> --%>
						<td>${member.deptno}</td>
						<td>${member.startday}</td>
					</tr>
				</c:forEach>
			</tbody>
		</table>
		
	</div>
	
</body>
</html>

 

[step02 - 체크박스에서 선택한 사용자를 조회하기]

이제 전체 목록에서 체크한 사용자의 패스워드를 암호화할 수 있도록 처리해야 합니다. 그러나 이 기능에는 db에서 처리하는 기능이 두 가지입니다. 체크한 목록 조회하기, 조회한 사원의 모든 패스워드 데이터를 변경하기

이런 작업이 무결하게 처리될 수 있도록 하는 것이 트랜잭션 처리겠지요?

 

memberlist.jsp

jQuery를 이용하여 체크된 사용자의 아이디를 모두 파라미터로 전송할 수 있도록 처리합니다. <head></head> 태그 안에 <script> 태그를 추가하고 아래와 같이 jQuery코드를 추가합니다.

$("#all")에 대한 처리는 모두 선택 기능을 정의한 것이고 $("#passmodify")의 [비밀번호변경] 버튼을 클릭하면 체크박스가 선택된 모든 사용자의 아이디를 컨트롤러를 요청하며 파라미터로 넘기는 기능을 정의한 것입니다.

<script type="text/javascript">
$(document).ready(function() {
	$("#all").on("click",function(){
		if($('input:checkbox[id="all"]').is(":checked")==true){
			$('input:checkbox[name="member"]').each(function() {
			    //현재 작업 중인 체크박스의 체크값을 true  
				this.checked = true; //checked 처리 
			 });

		}else{
			$('input:checkbox[name="member"]').each(function() {
			    //현재 작업 중인 체크박스의 체크값을 true  
				this.checked = false; //checked 처리 
			 });
		}
	})
	$("#passmodify").on("click",function(){
		paramdata=""
		$('input:checkbox[name="member"]').each(function() {
			if(this.checked){
				//alert($(this).closest("td").next().children('input:text[name="id"]').val())
				paramdata=paramdata+"id="+
					$(this).closest("td").next().children('input:text[name="id"]').val()+"&"
			}
		})
		location.href="/kimsaemERP/admin/passmodify.do?"
							+paramdata.substr(0, paramdata.length-1)
	})

})
</script>

 

AdminController

/admin/passmodify.do로 요청할 수 있도록 컨트롤러에 메서드를 추가합니다.  체크 박스가 선택된 아이디들이 여러 개 파라미터로 전송될 것이므로 id는 배열로 처리합니다.

@RequestMapping("/admin/passmodify.do")
public String modifyPassword(String[] id) {
	int result = service.passwordChange(id);
	if(result>=1) {
		System.out.println("성공변경");
	}
	return "redirect:/admin/member/list.do";
}

 

emp.xml

체크 박스가 체크된 모든 아이디에 해당하는 데이터를  조회할 수 있도록 SQL문을 작성합니다. 체크된 아이디가 매번 다를 것이므로 동적 SQL로 작성합니다. 넘어온 아이디를 이용해서 in연산자를 완성할 것이므로 <foreach>를 이용합니다.

<select id="chkidselect" parameterType="Map" resultType="emp">
		select * from member
		where id in (
		<foreach collection="idlist" item="id" separator=",">
			#{id}
		</foreach>
		)
</select>

 

AdminDAOImpl

Service에서 전달받은 아이디가 담겨있는 ArrayList를 Map에 넣고 mapper의 sql문을 호출합니다.

@Override
public List<MemberDTO> getCheckList(ArrayList<String> idlist) {
	Map<String, Object> paramMap =	new HashMap<String, Object>();
	System.out.println(idlist.size());
	paramMap.put("idlist",idlist);
	return sqlSession.selectList("ktds.erp.emp.chkidselect",paramMap);
}

 

AdminServiceImpl

매개변수로 넘겨받은 id배열을 ArrayList에 담고 dao의 체크된 아이디의 정보를 조회하는 메서드를 호출합니다.

@Override
public int passwordChange(String[] id) {
	//1. 배열에 들어있는 모든 아이디를 ArrayList에 add하세요.
	ArrayList<String> idlist = new ArrayList<String>();
	for (int i = 0; i < id.length; i++) {
		idlist.add(id[i]);
	}
	//2. id가 add된 ArrayList를 이용해서 id에 해당하는 모든 데이터를 
	//   ArrayList<MemberDTO>의 값으로 조회할 수 있도록 dao의
	//   getCheckList메소드를 호출하세요.
	ArrayList<MemberDTO> userlist = (ArrayList<MemberDTO>)dao.getCheckList(idlist);
	System.out.println("service"+userlist.size());
}

 

네 개의 체크박스를 선택하고 요청하면 다음과 같이 4개가 선택되었다는 문자열이 콘솔에 출력됩니다.

 

[step03 - 체크박스에서 선택한 사용자의 패스워드를 암호화하기]

선택이 완료됐으므로 이제 선택된 아이디의 패스워드를 변경해야 합니다. SQL update문을 이용하여 수정합니다.

 

emp.xml

비밀번호를 업데이트할 수 있도록 <update> 문을 추가합니다.

<update id="passchange" parameterType="emp">
	update member
	set pass=#{pass}
	where id=#{id}
</update>

 

AdminDAOImpl

emp.xml mapper의 update SQL문을 호출합니다. 조회한 모든 사원의 비밀번호를 변경해야 하므로 for문을 실행하며 for문 안에서 호출합니다.

@Override
public int update(List<MemberDTO> userlist) {
	int result = 0;
	for (MemberDTO user : userlist) {
		sqlSession.update("ktds.erp.emp.passchange", user);
	}
	result = 1;
	return result;
}

 

AdminServiceImpl

ShaPasswordEncoder는 @autowired로 주입받고 passwordChange메서드를 완성합니다. 조회해 온 사원의 정보가 담겨있는 ArrayList를 탐색하며 패스워드를 암호화하여 setPass 합니다. 이때 아이디를 salt로 추가하기 때문에 비밀번호가 동일하다고 하더라도 모두 다른 암호화 문자열이 만들어집니다.

@Service
public class AdminServiceImpl implements AdminService {
	@Autowired
	AdminDAO dao;
	@Autowired
	private ShaPasswordEncoder passencoder;
 	@Override
	public int passwordChange(String[] id) {
		//1. 배열에 들어있는 모든 아이디를 ArrayList에 add하세요.
		ArrayList<String> idlist = new ArrayList<String>();
		for (int i = 0; i < id.length; i++) {
			idlist.add(id[i]);
		}
		//2. id가 add된 ArrayList를 이용해서 id에 해당하는 모든 데이터를 
		//   ArrayList<MemberDTO>의 값으로 조회할 수 있도록 dao의
		//   getCheckList메소드를 호출하세요.
		ArrayList<MemberDTO> userlist = (ArrayList<MemberDTO>)dao.getCheckList(idlist);
		System.out.println("service"+userlist.size());
		
		for (MemberDTO user : userlist) {
			String securitypass = passencoder.encodePassword(user.getPass(), user.getId());
			System.out.println(securitypass);
			user.setPass(securitypass);//암호화된 패스워드를 다시 패스워드로 셋팅
		}
		int result = dao.update(userlist);
		//3. 받아온 아이디의 password를 읽어서 암호화시킨 값을 update할 수 있도록 dao
		return result;
}

 

admin권한을 갖고 있는 아이디로 접속한 후 관리자 페이지를 선택합니다. 비밀번호 변경을 선택하고 체크박스를 모두 선택한 후 [비밀번호변경] 버튼을 눌러 모든 패스워드가 암호화되도록 실행합니다.

 

SQL을 이용하여 id와 pass를 조회합니다. 모든 암호가 "1234"이지만 salt를 추가했기 때문에 암호화된 문자열이 모두 다른 것을 알 수 있습니다.

+ Recent posts