본문 바로가기
도서/프로그래밍

[08] 쉽게 배우는 JSP 웹 프로그래밍

by 신발사야지 2024. 1. 21.

8일차

CHAPTER 10 시큐리티

01 시큐리티의 개요

시큐리티는 허가된 사용자만이 특정 웹 페이지에 접근할 수 있도록 제한하는 보안 기능을 말합니다.

사용자에게 인증(authenticatio)을 요청합니다.

인증되면 사용자를 확인하여 권한 부여(authorization)합니다.

시큐리티는 인증과 권한부여를 하며 웹 공격자가 전송 데이터를 중간에 가로채는 것을 방지하는 듯 중요한 역할을 합니다.

처리 방법으로는 선언적 방법과 프로그래밍적 방법이 있습니다.

  • 선언전 시큐리티: 코드 작성 없이 wb.xml 파일에 보안을 구성
  • request 내장 객체의 메소드를 통해 처리

conf 폴더 내의 tomcat-user.xml 파일로 사용자 권한을 설정

web.xml 에서 접근 권한을 제한

<security-constraint>
	<web-resource-collection>
		<web-resource-name>BookMarket</web-resource-name>
		<url-pattern>cart/*</url-pattern>
	</web-resource-collection>
</security-constraint>

03 프로그래밍적 시큐리티 처리

request 내장 객체의 메소드를 사용

매소드 형식 설명

getRemoteUser() String 사용자의 인증 상태를 반환한다.
getAuthType() String 서블릿을 보하하는데 사용되는 인증 방식의 이름을 반환한다
isUserInRole(String role) boolean 현재 인증된 사용자에게 설정된 역할이 있는지 확인한다. 설정된 경우 true를 반환하고 그렇지 않은 경우 false를 반환한다.
getProtocol() String 웹 브라우저의 요청 프로토콜을 가져온다.
isSecure() boolean https 요청이면 true 아니면 false
getUserPrinciple() Principle 현재 인증한 사용자의 읾을 포함하여 java.security.Principle 객체를 반환한다.

CHAPTER 11 예외 처리

예외 처리 방법

page 디렉티브 태그를 이용: errorPage와 isErrorPage 속성을 이용한다.

web.xml 파일을 이용: <error-code> 또는 <exception-type> 요소를 이용

try-catch-finally 이용 : 자바 언어의 예외 처리 구문을 이용

우선순위

  1. JSP 페이지에서 try-catch-finally 문으로 처리
  2. page 디렉트비 태그의 errorPage 속성에서 설정한 오류 페이지
  3. JSP 페이지에서 발생한 예외 유형이 web.xml 에서 설정한 예외 유형과 동일한 경우
  4. web.xml 에서 설정한 오류 코드와 동일한 경우
  5. 모두 해당하지 않으면 웹 서버가 제공하는 기본 오류 페이지

02 page 디렉티브 태그를 이용

<% page errorPage="error.jsp" %>

03 web.xml 파일을 이용한 예외처리

<error-page>
  - error-code: 400, 500 , exception-type: ClassNotFoundException...
	<error-code></error-code>|<exception-type></exception-type>
	<location></location> - 오류 페이지의 URL
</error-page>

04 try-catch-finally

<%
	try {
		int num = 10 / 0;
	} catch (NumberFormatException e) {
			RequestDispatcher dispatcher = request.getRequestDispatcher("error.jsp");
			dispatcher.forward(request, response);
	}
%>

forward 메소드 방식: JSP 페이지를 호출하는 순간 서블릿 프로그램이 실행을 멈추며 JSP 페이지로 넘어가 그곳에서 실행하고 프로그램이 끝납니다.

include 메소드 방식: JSP 페이지가 실행된 후 나머지 서블릿 프로그램이 실행됩니다.

CHAPTER 12 필터

01 필터의 개요

필터는 클라이언트와 서버 사이에서 request 와 response 객체를 먼저 받아 사전/사후 작업 등 공통적으로 필요한 부분을 처리하는 것을 말합니다.

여러개의 필터가 엮여있는 필터 체인을 사용하기도 합니다.

Filter 인터페이스를 구현하는 자바 클래스를 생성하고, 생성된 자바 클래스를 web.xml 파일에 등록합니다.

필터 기능

Request 필터 - 인증(사용자 인증)
  • 요청 정보를 로그 파일로 작성 -암호화 인코딩 작업 | | Response 필터 | - 응답 결과에 내용 추가/수정 - 총 서비스 시간 측정 |

02 Filter 인터페이스의 구현 클래스

jakarta.servlet.Filter

init(): 필터 인스턴스의 초기화 메소드

doFilter(): 필터 기능을 작성하는 메소드

destory(): 인스턴스 종료 전에 호출되는 메소드

  1. <filter> 요소
<filter>
	<filter-name>MyFilter</filter-name>
	<filter-class>ch12.com.filter.LoggingFilter</filter-class>
	<init-param>
		<param-name>param</param-name>
		<param-value>admin</param-value>
	</init-param>
</filter>

String value = getServletConfig().getInitParameter("param");
  1. <filter-mapping> 요소

특정 리소스에 대해 어떤 필터를 사용할지 설정하는 데 사용

<filter-mapping>
	<filter-name>필터 이름</filter-name>
	<url-pattern>요청 URL 패턴</url-pattern>
</filter-mapping>

<filter-mapping>
	<filter-name>Myfilter</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

실제 필터를 사용해서 Logging 하는 예쩨

web.xml

<web-app>

<filter>
	<filter-name>Filter02_2</filter-name>
	<filter-class>ch12.com.filter.LogFileFilter</filter-class>
	<init-param>
		<param-name>filename</param-name>
		<param-value>c:\\\\logs\\\\monitor.log</param-value>
	</init-param>
</filter>
<filter-mapping>
	<filter-name>Filter02_2</filter-name>
	<url-pattern>/ch12/filter02_process.jsp</url-pattern>
</filter-mapping>
    
</web-app>

filter02.jsp

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Filter</title>
</head>
<body>
	<form method="post" action="filter02_process.jsp">
		<p> 아이디 : <input type="text" name="id">
		<p> 비밀번호: <input type="text" name="passwd">
		<p> <input type="submit" value="전송">
	</form>
</body>
</html>

filter02_process.jsp

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Filter</title>
</head>
<body>
	<%
		String id = request.getParameter("id");
		String passwd = request.getParameter("passwd");
	%>
	
	<p> 입력된 id 값 : <%=id %>
	<p> 입력된 pw 값 : <%=passwd %>
</body>
</html>

LogFileFiltter.java

package ch12.com.filter;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;

public class LogFileFilter implements Filter{
	PrintWriter writer;
	
	public void init(FilterConfig filterConfig) throws ServletException {
		String filename = filterConfig.getInitParameter("filename");
		if(filename == null) {
			throw new ServletException("로그 파일의 이름을 찾을 수 없습니다.");
		}
		
		try {
			writer = new PrintWriter(new FileWriter(filename, true), true);
		} catch (IOException e) {
			throw new ServletException("로그 파일을 열 수 없습니다.");
		}
	}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
			throws IOException, ServletException {
		
		writer.printf("현재일시 : %s %n", getCurrentTime());
		String clientAddr = request.getRemoteAddr();
		writer.printf("클라이언트 주소 : %s %n", clientAddr);
		
		filterChain.doFilter(request, response);
		
		String contentType = response.getContentType();
		writer.printf("문서의 콘텐츠 유형 : %s %n", contentType);
		writer.println("--------------------------------");
	}
	
	private String getCurrentTime() {
		DateFormat formatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(System.currentTimeMillis());
		
		return formatter.format(calendar.getTime());
	}

	public void destroy() {
		writer.close();
	}

}