관리 메뉴

DeseoDeSeo

[Spring] (보안1)db의 회원 비밀번호 보안 설정하기 본문

spring

[Spring] (보안1)db의 회원 비밀번호 보안 설정하기

deseodeseo 2023. 9. 25. 17:16
pom.xml 
보안 관련 api추가
		<!-- Spring Security를 하기위한 버전 추가 -->
		<org.springsecurity-version>5.0.2.RELEASE</org.springsecurity-version>

 

		<!-- Spring Security 사용하기 위한 API 추가 -->
			   <dependency>
			         <groupId>org.springframework.security</groupId>
			         <artifactId>spring-security-web</artifactId>
			         <version>${org.springsecurity-version}</version>
     		 </dependency>
     		 <!-- Spring Security 사용하기위한 설정API 추가 -->
      		<dependency>
			         <groupId>org.springframework.security</groupId>
			         <artifactId>spring-security-config</artifactId>
			         <version>${org.springsecurity-version}</version>
     		 </dependency>
     		 	<!-- Spring Security 편리하게 사용하기 위한 태그라이브러리 사용 API 추가 -->
     		 <dependency>
			         <groupId>org.springframework.security</groupId>
			         <artifactId>spring-security-taglibs</artifactId>
			         <version>${org.springsecurity-version}</version>
   			</dependency>
src/main/java > kr.spring.config
securityInitializer.java
package kr.spring.config;

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer{
	//abst~를 상속받으면 자동으로 보안관련 객체들이 생성되어서 스프링 컨테이너(메모리공간)으로 올라간다.

}
SecurityConfig.java
: 한글 인코딩 필요
package kr.spring.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.web.filter.CharacterEncodingFilter;

@Configuration // WEbConfig.java에서 SecurityConfig를 읽어오기 위한 어노테이션
@EnableWebSecurity // web에서 Sercurity를 쓰겠다.
public class SecurityConfig extends WebSecurityConfigurerAdapter{

		//Spring Security 환경설정하는 클래스
	//websecurity~ : 요청에 대한 보안 설정을 해주는 클래스
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		// 요청에 대한 보안 설정하는 곳
		// 교재 p.605
		CharacterEncodingFilter filter = new CharacterEncodingFilter();
		filter.setEncoding("UTF-8");
		filter.setForceEncoding(true);
		http.addFilterBefore(filter, CsrfFilter.class);
		
	}
	//객체로 등록하겠다 사용할 때 사용함.
	@Bean
	//패스워드 인코딩 기능을 메모리에 올리는 작업
	public PasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}
}
MemberController.java
public class MemberController {
//	mapper만드는 법 기억해야됨.
	@Autowired
	private MemberMapper mapper;
	@Autowired // 내가 만들어 놓은 비밀번호 암호화 객체를 주입받아 사용하겠다. !!!!!!!!!!!!!! 이게 securityConfig.java에서 옴.
	private PasswordEncoder pwEncoder;

➜ 여기서 PasswordEncoder가 SecurityConfig.java의 PasswordEncoder임.

MemberController.java > join.do
}else {
			//회원 가입 가능

			//null값 대신 넣으려구.
			m.setMemProfile("");
			//비밀번호 암호화 !!!!!!!!!!!!!!요기서 
			String encyPw = pwEncoder.encode(m.getMemPassword());
			m.setMemPassword(encyPw);

imageForm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

<c:set var="contextPath" value="${pageContext.request.contextPath}" />

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
	<div class="container">
	  <jsp:include page="../common/header.jsp"></jsp:include>
	  <h2>Spring MVC03</h2>
	  <div class="panel panel-default">
	    <div class="panel-heading">Board</div>
	    <div class="panel-body">

		<form action="${contextPath}/imageUpdate.do?${_csrf.parameterName}=${_csrf.token}" method="post" enctype="multipart/form-data">
		
			<table style="text-align: center; border : 1px solid #dddddd" class="table table-bordered">
				<tr>
					<td style="width: 110px; vertical-align: middle;">아이디</td>
					<td>${mvo.memID}</td>
				</tr>
				
				<tr>
					<td style="width: 110px; vertical-align: middle;">사진업로드</td>
					<td>
						<span class="btn btn-default">
							이미지를 업로드하세요.
							<input type="file" name="memProfile">
						</span>
					</td>
				</tr>
				<tr>
					<td colspan="2">
						<span id="passMessage" style="color:red;"></span>
						<input type="submit" class="btn btn-primary btn-sm pull-right" value="등록">
						<input type="reset" class="btn btn-warning btn-sm pull-right" value="취소">
					</td>
				</tr>
			</table>		
		</form>
		</div>
	    <div class="panel-footer">스프링게시판 - 뇽뇽이</div>
	  </div>
	</div>
	
	 <!-- Modal -->
	  <div class="modal fade" id="myModal" role="dialog">
	    <div class="modal-dialog">
	      <!-- Modal content-->
	      <div id="checkType" class="modal-content">
	        <div class="modal-header panel-heading">
	          <button type="button" class="close" data-dismiss="modal">&times;</button>
	          <h4 class="modal-title">메세지 확인</h4>
	        </div>
	        <div class="modal-body">
	          <p id="checkMessage"></p>
	        </div>
	        <div class="modal-footer">
	          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
	        </div>
	      </div>
	    </div>
	  </div>
	
		<!-- 회원가입 실패시 띄워줄 모달 -->
	  <div class="modal fade" id="myMessage" role="dialog">
	    <div class="modal-dialog">
	      <!-- Modal content-->
	      <div id="messageType" class="modal-content">
	        <div class="modal-header panel-heading">
	          <button type="button" class="close" data-dismiss="modal">&times;</button>
	          <h4 class="modal-title">${msgType}</h4>
	        </div>
	        <div class="modal-body">
	          <p id="">${msg}</p>
	        </div>
	        <div class="modal-footer">
	          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
	        </div>
	      </div>
	    </div>
	  </div>

	<script type="text/javascript">
		
		$(document).ready(function(){
			if(${not empty msgType}){
				if(${msgType eq "실패메세지"}){
					$("#messageType").attr("class","modal-content panel-warning");
				}
				$("#myMessage").modal("show");
			}
		});
	</script>
</body>
</html>

○ csrf 토큰 : 사용자가 임의로 변하는 특정의 토큰값을 서버에서 체크하는 방식.

                     - 서버에는 브라우저에 데이터를 전송할 때 CSRF토큰을 같이 전송함.

일반적으로 웹 애플리케이션은 사용자의 세션에 csrf토큰을 생성하고, 웸 페이지의 폼이나 ajax 요청에 해당 토큰을 포함.

 

joinForm.jsp
➜ csrf토큰 추가
<body>
	<div class="container">
		<jsp:include page="../common/header.jsp"></jsp:include>
		<h2>Spring MVC05</h2>
		<div class="panel panel-default">
			<div class="panel-heading">Board</div>
			<div class="panel-body">
			<!-- p.635보안 관련  -->
			
				<form action="${contextPath}/join.do" method="post">
				
				<!-- 이제는 서버로 단순히 회원가입 정보만 전달하는 것이 아니라 토큰도 전달해야 회원가입이 가능하다. -->
                <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}">
main.jsp
}else{
	$("#c"+ idx).css("display","none");
		$.ajax({
			url:"board/count" +idx,  //pathvariable방식 : 경로부분에 값(idx)을 보내는 방식, url에 가독성을 올리기 위해서.
			type:"put",
			beforeSend:function(xhr){
            	xhr.setRequestHeader(csrfHeaderName, csrfTokenValue);
			},
				success:loadList,
				error: function(){alert("error");}
	});
 }

이와 같이, loginForm.jsp,  update.jsp에도 추가함.