spring security 에서는 기본적으로 아래와 같은 암호화 모듈을 제공하고 있다.
BaseDigestPasswordEncoder BasePasswordEncoder LdapShaPasswordEncoder Md4PasswordEncoder Md5PasswordEncoder MessageDigestPasswordEncoder PlaintextPasswordEncoder ShaPasswordEncoder
이중에서 ShaPasswordEncoder 를 이용해 비밀번호를 sha256 암호화를 적용해 보도록 하겠다.
이번에는 DB insert를 위해 mybatis를 연동하였다.
1.security.xml에 ShaPasswordEncoder bean등록
<beans:bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder"> <beans:constructor-arg name="strength" value="256"></beans:constructor-arg> </beans:bean>
2.authentication-provider에 사용자 인증시 비밀번호 암호화빈 등록
<authentication-manager> <authentication-provider user-service-ref="userService"> <password-encoder ref="passwordEncoder"/> </authentication-provider> </authentication-manager>
3.회원 가입 jsp생성(귀찮아서 로그인 페이지에 폼을 두개만들어 처리함)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="http://www.springframework.org/security/tags" prefix="sec" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <link rel="stylesheet" type="text/css" href="<c:url value="/resources/css/main.css"/>"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> ${errMsg } <form action='<c:url value="/user/login"/>' method="post"> <input type="text" name="email" id="email"/> <input type="password" name="passwd" id="passwd"/> <input type="submit" value="로그인"> </form> <form action='<c:url value="/user/insertUser"/>' method="post"> <input type="text" name="email" id="email"/> <input type="password" name="passwd" id="passwd"/> <select name="authority"> <option value="ROLE_USER">사용자</option> <option value="ROLE_ADMIN">관리자</option> </select> <input type="submit" value="회원가입"> </form> </body> </html>
4.회원 가입시 비밀번호 암호화를 위한 Service class생성
package com.min.study.core.util; import javax.annotation.Resource; import org.springframework.security.authentication.encoding.ShaPasswordEncoder; import org.springframework.stereotype.Service; @Service("shaEncoder") public class ShaEncoder { @Resource(name="passwordEncoder") private ShaPasswordEncoder encoder; public String encoding(String str){ return encoder.encodePassword(str,null); } }
5.pom.xml에 mybatis추가
<!-- MyBatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.1.1</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.1.1</version> </dependency>
6.resource폴더에 sqlmap폴더 생성 후 mybatis.xml생성
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "HTTP://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <settings> <setting name="cacheEnabled" value="true"/> <setting name="lazyLoadingEnabled" value="false"/> <setting name="multipleResultSetsEnabled" value="true"/> <setting name="useColumnLabel" value="true"/> <setting name="useGeneratedKeys" value="false"/> <setting name="autoMappingBehavior" value="PARTIAL"/> <setting name="defaultExecutorType" value="SIMPLE"/> <setting name="defaultStatementTimeout" value="25"/> <setting name="safeRowBoundsEnabled" value="false"/> <setting name="mapUnderscoreToCamelCase" value="false"/> <setting name="localCacheScope" value="SESSION"/> <setting name="jdbcTypeForNull" value="OTHER"/> <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/> </settings> <typeAliases> <typeAlias type="java.util.Map" alias="map"/> </typeAliases> </configuration>
7.datasource-context.xml에 mybatis SqlSessionFactoryBean 등록 및 트랜잭션 선언
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="configLocation" value="classpath:sqlmap/mybatis.xml" /> <property name="mapperLocations" value="classpath:sqlmap/*/*.xml" /> </bean> <tx:annotation-driven transaction-manager="transactionManager"/> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean>
8.회원 가입을 위한 DAO service생성 및 impl클레스 구현
package com.min.study.user.dao; import java.util.Map; public interface UserDaoService { public int insertUser(Map<String, String> paramMap); } package com.min.study.user.dao; import java.util.Map; import org.mybatis.spring.support.SqlSessionDaoSupport; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service("userDaoService") public class UserDaoServiceImpl extends SqlSessionDaoSupport implements UserDaoService { @Override @Transactional public int insertUser(Map<String, String> paramMap) { // TODO Auto-generated method stub return getSqlSession().insert("user.insertUser",paramMap); } }
9.sql query.xml생성(예제는 sqlmap/mysql/user.xml)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="user"> <insert id="insertUser"> INSERT INTO USER VALUES(#{email},#{passwd},1,#{authority}) </insert> </mapper>
10.usercontroller에 암호화 서비스 & daoservice 주입 및 가입시 비밀번호 암호화 설정
ex)
package com.min.study.user.web; import java.util.HashMap; import java.util.Map; import javax.annotation.Resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import com.min.study.core.util.ShaEncoder; import com.min.study.user.dao.UserDaoServiceImpl; @Controller public class UserController { private static final Logger logger = LoggerFactory.getLogger(UserController.class); @Resource(name="shaEncoder") private ShaEncoder encoder; @Resource(name="userDaoService") private UserDaoServiceImpl dao; @RequestMapping("/user/loginPage") public String loginPage(){ return "/user/loginPage"; } @RequestMapping(value = "/user/insertUser",method=RequestMethod.POST) public String insertUser(@RequestParam("email")String email, @RequestParam("passwd")String passwd, @RequestParam("authority")String authority){ String dbpw = encoder.encoding(passwd); Map<String, String> paramMap = new HashMap<String, String>(); paramMap.put("email", email); paramMap.put("passwd", dbpw); paramMap.put("authority", authority); int result = dao.insertUser(paramMap); logger.info("result ===> {}", result); return "/user/loginPage"; } }
11. 회원가입 & 인증 확인.
ex)패스워드가 test인 경우 sha256 암호화를 하면 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08 이다.
------------------------------------------------------------------------------------------