이것 저것 개발 공부/Servlet
[Servlet] Servlet에서 Request와 Response를 가공하는 가장 좋은 방법 | Wrapper 클래스
crushed-taro
2025. 5. 13. 22:43
728x90
반응형
[Servlet] Servlet에서 Session과 Cookie 완벽 이해하기 | 차이점, 사용법, 예제까지 정리
[Servlet] Servlet에서 Session과 Cookie 완벽 이해하기 | 차이점, 사용법, 예제까지 정리
[Servlet] Servlet Forward와 Redirect의 차이점과 사용법 완벽 정리 [Servlet] Servlet Forward와 Redirect의 차이점과 사용법 완벽 정리[Servlet] Servlet 메서드와 파라미터 제대로 알기 - 초보자를 위한 웹 개발 가이
crushed-taro.tistory.com
1. Servlet Wrapper
1. Servlet Wrapper
1. Servelt Wrapper란
- 관련 클래스(ServletRequest, ServletResponse, HttpServletRequest, HttpServletResponse)를 내부에 보관하며 해당 인터페이스를 구현한 객체를 참조하여 구현 메소드를 위임한다.
- Java Event처리의 Adapter Class와 비슷한 기능을 한다고 볼 수 있다.
- 사용자가 별도의 request나 response 객체를 생성하여 활용할 때 Wrapper Class를 상속하여 활용하면, 편하게 원하는 Class만 재정의하여 사용할 수 있다.
2. Wrapper Class
- HttpServletRequestWrapper
- 요청한 정보를 변경하는 Wrapper Class로, HttpServletRequest 객체를 매개로 하는 생성자를 가진다.
public SampleWrapper(HttpServletRequest wrapper) {
super(wrapper);
}
- HttpServletResponseWrapper
- 응답할 정보를 변경하는 Wrapper Class로, HttpServletResponse 객체를 매개로 하는 생성자를 가진다.
public SampleWrapper(HttpServletResponse wrapper) {
super(wrapper);
}
3. Wrapper Class 활용 예시
- HttpServletRequestWrapper 클래스를 상속받아 비밀번호를 암호화하는 Wrapper 클래스를 작성한다.
- 요청 받은 정보로부터 값을 꺼내올 때 암호화된 값을 꺼내오도록 request 객체 등을 자체적으로 조작하기 위하여 wrapper를 활용한다.
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
public class RequestWrapper extends HttpServletRequestWrapper {
/* 부모에 기본생성자가 존재하지 않으므로 request를 전달해주는 생성자 필요 */
public RequestWrapper(HttpServletRequest request) {
super(request);
}
@Override
public String getParameter(String key) {
String value = "";
if("password".equals(key)) {
/* spring-security-crypto 라이브러리 사용 */
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
value = passwordEncoder.encode(super.getParameter(key));
} else {
value = super.getParameter(key);
}
return value;
}
}
- 위 에서 작성한 Wrapper를 적용하는 필터 클래스를 작성한다.
import java.io.IOException;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
@WebFilter("/member/*")
public class PasswordEncryptFilter implements Filter {
public void destroy() {}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest hrequest = (HttpServletRequest) request;
RequestWrapper wrapper = new RequestWrapper(hrequest);
chain.doFilter(wrapper, response);
}
public void init(FilterConfig fConfig) throws ServletException {}
}
- 요청을 처리하는 서블릿에서 확인하면 암호화된 값이 현출되는 것을 확인할 수 있고, BCryptPasswordEncoder 클래스의 matches() 메소드를 통해 암호화된 값이 특정 값과 일치하는지 확인할 수 있다.
@WebServlet("/member/regist")
public class RegistMemberServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String password = request.getParameter("password");
System.out.println("userPwd : " + password);
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
System.out.println(passwordEncoder.("pass01", password));
}
}
4. (참고) 암호화 및 Bcrpt
- 위 그림처럼 중간에 패킷 정보를 빼내어 가져가는 해킹 기법인 ‘패킷스니핑’에 대비하여 개인 정보 등 보안에 민감한 데이터에는 암호화 처리가 필요하다.
- 암호화하면 패킷스니핑으로 해킹해도 복호화하지 못하는 이상 크게 의미가 없기 때문이다.
- 데이터베이스 해킹에 대비해 DB 저장 시에도 암호화된 데이터를 넣어야 한다.
- 서버는 양방향 암호화 처리를 한다.
- 암호화란 평문을 다이제스트(= 기존 문자열을 변환한 일정 길이의 문자열)로 변경하는 것이고, 복호화는 다이제스트를 다시 평문으로 변경하는 것이다.
- 이때 암호화는 가능하지만 복호화는 불가한 것이 단방향 암호화이고, 암호화와 복호화 모두 가능한 것이 양방향 암호화이다.
저장한 서버도 관리자도 알아서는 안되는 고객의 개인 정보 등이 있을 수 있으므로 데이터베이스는 단방향 암호화 처리를 한다.
💡 BCrypt 암호화
비밀번호를 데이터베이스에 저장할 목적으로 설계된 암호화 알고리즘이다.
랜덤 솔팅 기법을 적용한 다이제스트 생성을 지연시킨 단방향 해시 암호화 알고리즘이다.
암호화는 가능하나 복호화가 불가능한 높은 수준의 암호화 알고리즘이다.
- 해시 알고리즘이란 어떤 메시지를 넣더라도 해시 함수를 통과하면 동일한 길이의 랜덤한 문자열이 반환되는 것으로, 빠른 속도로 다이제스트 생성이 가능하다.
- 무차별 대입 → 모든 경우의 수에 대해 다이제스트를 생성해 맞춰보면서 패턴 탐색
- 사전식 대입 → 사전 속 단어를 다이제스트로 변경해 다이제스트와 비교해 패턴 탐색
- 이러한 해시 알고리즘은 다이제스트 생성 방식이 동일하므로 아래 두 가지 방법으로 패턴만 알아내면 복호화가 가능해진다.
- 따라서 위와 같은 패턴 탐색을 방지하고자 Bcrypt 암호화에서 적용한 salting 기법은 원문만 암호화하지 않고 지정한 다른 글자(= salt값)를 붙여 암호화하는 것이고, BCrypt는 암호화할 때마다 랜덤한 salt값을 이용한다.
728x90
반응형