2013년 9월 10일 화요일

[Head First]Servlets & JSP 내용정리-12장

Chapter.12

세가지 유형 해커들

  • Impersonator (임퍼스네이터) : 자신을 다른 사람처럼 속이는 녀석
  • Upgrader(업그레이더) : 자신의 등급을 속이는 녀석
  • Eavesdropper(이즈드롭퍼) : 중요한 정보를 몰래 훔쳐보는 녀석  --> 가장 나쁜 형태의 해커


서블릿 보안의 4요소

  • 인증(Authentication)
  • 인가(Authorization)
  • 비밀보장(Confidentiality)
  • 데이터 무결성(Data Integrity)


HTTP 환경에서 인증

  • HTTP 401 (Unauthorized) 응답 보내서 사용자의 암호와 패스워드를 요구 한다.
  • 컨테이너가 보안 테이블을 확인 하여 주어진 ID와 PWD 올바르면 해당 자원을 보내 준다.


인증, 인가에 컨데이너의 하는 일

  • 요청 자원에 대한 검색(lookup) 작업 : 보안 정보에 대해서
  • 인증 작업을 합니다. : 클라이언트에게 인증 정보를 요청
  • 인가 작업을 함 : 사용자가 자원에 대한 권한을 확인 한다.


보안 관련 제약 사항을 선언적으로 관리하는 이유(DD)

  • XML은 사용하기 용이하므로
  • 서블릿을 좀 더 유연하게 작성할 수 있으므로
  • 유지보수가 쉬우므로


서블릿 보안 관련 체크 사항

보안 개념
책임 소재
복잡도
노력 정보
인증
관리자
중간
높음
인가
(대부분) 배포자
높음
높음
비밀 보장
배포자
낮음
낮음
데이터 일관성
배포자
낮음
낮음


tomcat-users.xml 파일
<tomcat-users>
 <role rolename=”Guest”/>
 <role rolename=”Member”/>
 <user name=”Bill” password=”coder” roles=”Member, Guest”/>
 …
</tomcat-users>


인증 활성화 하기 (DD)
<login-config>
 <auth-memthod>BASIC</auth-memthod>
</login-config>


인가 단계
  1. 인가 단계 1 : 역할(role) 정의 하기


<security-role>
<role-name>Admin</role-name>
<role-name>Member</role-name>
<role-name>Guest</role-name>
</security-role>


<login-config>
 <auth-memthod>BASIC</auth-memthod>
</login-config>
------------------------
관련항목 설정


  1. 인가 단계 2 : 자원/메소드 제약 정의 하기


<security-constraint>
 <web-resource-collection>
   <web-resource-name>UpdateRecipes</web-resource-name>
   <description>선택 사항</description>    
   <url-pattern>/Beer/AddRecipe/*</usrl-pattern>
   <url-pattern>/Beer/ReviewRecipe/*</usrl-pattern>
   
   <http-method>GET</http-method>
   <http-method>POST</http-method>
   -------------------------------
   항목으로 정의한 자원에 대한 제약을 걸 HTTP 메소드를 정의 하라
   GET와 POST에 대해서만 제약 유효 하고 그외 메소드에 대한 누구던지
   접근 가능 하다.
   먄악 정의 하지않으면 모든 메소드에 다 제약을 건다는 의미
 </web-resource-collection>


 <auth-constraint>
   <role-name>Admin</role-name>
   <role-name>Member</role-name>
 </auth-constraint>
 ------------------
 정의된 자원에 대해 http-method 수행 할 group
</security-constraint>


웹은 자원 단위의 제약이 아니라 HTTP 요청단위의 제약을 거는 것입니다.


<role-name> 규칙
  • 만약 <auth-contraint>에 <role-name>이 없다면 어떤 사용자도 접근 할 수 없다.
  • <role-name>*</role-name> 모든 사용자가 다 접근 가능하다.
  • <role-name> 대소문자구분


<auth-contraint> 규칙
  • 옵선 항목
  • 항목이 있다는 말은 관련 URL에 대하여 인증 실시하고 컨데이너에게 지시함.
  • 없다면 URL에 대하여 인증 없이도 접근할 수 있다는 것
  • 안에 <description> 가능 함.
  • <auth-contraint/> 와 공태그는 정 반대 입니다.
  • 이 옵션에 의해서 자원에 접근하지 못해도 Request Dispatcher를 통해서 가능하다.


HttpServletRequest에 프로그램적인 보안과 관련된 3개 메소드
  • getUserPrincipal() : EJB에 사용 (관련 무)
  • getRemoteUser() : 인증이 되어는지 안 되었는지 확인하는 메소드. 잘 사용안함.
  • isUserInRole() : 메소드 내에서 인가관리(권한관리)를 함.


isUserInRole() 동작 방식
  • 호출하기 전, 반드시 인증을 거쳐야 함. (인증하지 않으면 false)
  • 컨데이너가 인자로 넘어온 값(“rolename”)과 정의된 사용자 역할과 비교 합니다.
  • 사용자가 해당 역할이라고 한다면, 참(true)를 리턴함.


서블릿 코드
if(request.isUserInRole(“Manager”)){
                       ----------
                      배포서술자에 <security-role-ref>의 <role-name>와 같음.
}


배포 서술자
<web-app...>
<servlet>
  <security-role-ref>
    <role-name>Manager</role-name>
    <role-link>Admin</role-link>
    ----------------------------
    <security-role>의 Admin와 서로 맵핑함.
  </security-role-ref>
  ...
</servlet>
</web-app>
<web-app...>
 <security-role>
   <role-name>Admin</role-name>
   <role-name>Member</role-name>
 </security-role>
</web-app>


** 만약 <security-role-ref>와 <security-role>에 동일한 이름이 있다면 ~-ref 우선임.


4가지 인증 방식
  • BASIC : 암호하지 않은 인코딩한(base64) 형식을 전송 , 약한 인증 방식
  • DIGEST : 안전한 형태 , 암호화 매커니즘을 사용함. J2EE 컨데이너에서 반드시 지원해야 하는 방식 아님.
  • CLIENT-CERT : 공인키 인증(PKC) 사용. 매우 안전한 방식으로 전송 클라이언트 인증서 가져야 함.
    보통 비즈니스 환경에서 사용
  • FORM : 자신만의 로그인 폼을 제공. 4가지 보안 방식중 가장 약함. 암호화되지 않은 채 전송됨.
설정
<web-app..>
 <login-config>
   <auth-method>BASIC | DIGEST | CLIENT-CERT | FORM</auth-method>
 </login-config>
 FORM 일때만
[
 <form-login-config>
   <form-login-page>/loginPage.html</form-login-page>
   <form-error-page>/loginError.html</form-error-page>
 </form-login-config>
]
 …
</web-app>


폼 기반 인증 - 해야 할일
  1. DD에 <login-config> 정의 하기
  2. HTML 로그인 폼 생성
  3. HTML 오류 페이지 생성


HTML 로그인 폼과 컨테이너간 데이터 공유를 위한 3가지 항목 (반드시 아래 이름으로 사용해야 함.)
  • action 명 :  j_security_check
  • user 명 name 속성 : j_username
  • pwd , name 속성 : j_password


인증 방식 정보 표
유형
스펙
데이타 무결성
주석
BASIC
HTTP
Base64 - 약함
HTTP 표준, 모든 브라우저가 지원
DIGEST
HTTP
좀더 강력한 방식 - SSL 만큼은 아님
HTTP ,J2EE 컨테이너에서 옵션 사항임.
FORM
J2EE
가장 약함, 암호화 안됨
사용자 정의 로그인 화면 지원
CLIENT-CERT
J2EE
강력함 - 공인키(PKC)
강력하지만 사용자가 인증서를 가지고 있어야 함.


안전하게 데이터 전송하기 : HTTPS가 답입니다. 실전에서는 대부분 SSL 기반에 HTTPS를 사용함. (전송 계층의 방식)


데이터 기밀성과 데이터 무결성을 분리하여 선언하기
<web-app..>
<security-constraint>
  <web-resource-collection>
    ...
  </web-resource-collection>
  <auth-constraint>
    ...
  </auth-constraint>
  <user-data-constraint>
    <transport-guarantee>CONFIDENTIAL</transport-guarantee>
  </user-data-constraint>   
</security-constraint>
</web-app>


<transport-guarantee>에 들어 갈 수 있는 값.

  • NONE : 디폴트 값. 데이터 보호를 하지 않겠다는 의미
  • INTEGRAL : 전송 중 데이터가 변경되지 않음을 보장한다는 말이죠.
  • CONFIDENTIAL : 전송 중 그 누구도 데이터를 훔쳐보지 않았음을 보장한다는 말이죠 (보장하기 위해서)
    SSL를 사용한다.

[Head First]Servlets & JSP 내용정리-11장

Chapter.11 웹 애플리케이션 배포

배포 파일 및 디렉토리 구조


WAR 파일

  • 전체 웹 어플리케이션 디렉토리를 jar로 압축하여(** 웹 애플리케이션 컨텍스트 디렉토리가 아닌 WEB-INF 바로 위에서 압축)
  • 톰켓의 경우 WAR파일 이름이 웹 어플리케이션 이름
  • META-INF/MANIFEST.MF 파일에 라이브러리 의존성을 작성하면, 배포 시 필요한 라이브러리를 확인 할 수있다.



정적인 컨텐츠 및 JSP를 브라우저에서 직접 접근 하려면..

  • 직접 접근 이란 - 브라우저 주소창에 자원에 대한 경로를 표기하여 요청하면, 서버가 이 파일을 넘겨준다는 뜻
  • 직접 접근을 막기 위해서 : WEB-INF 밑에 두던가 WAR의 경우에는 META-INF 아래에 두면 됨.(forward난 include를 통해서 접근 할 수 있다.)
  • 파일 자원 접근
    • WEB-INF/lib의 jar 일때 : 클래스 로더의 getResource() 나 getResourceAsStream() 사용
    • JAR파일로 배포하지 않은 웹 애플리케이션 내부 자원 : ServeltContext API. getResource() 나 getResourceAsStream()

컨테이너가 클래스 찾는 순서

WEB-INF/classes  -> WEB-INF/lib 순으로 찾는다.

서블릿 맵핑시 가상(논리적인) 디렉토리 구조를 사용할 수 있다.

http://www.huni.com/AdviceApp/Beer/BeerSelect.do
                  ---------- -------------------------
                  1)         2)
1) web application context root
2) dd 상에만 존재하는 가상 디렉토리 Beer               
                        

3가지 <url-pattern> 타입

  1. 정확하게 이름까지 일치 하는 것 : <url-pattern>/Beer/SelectBeer.do</url-pattern>
  2. 디렉토리까지만 일치하는 것 : <url-pattern>/Beer/*</url-pattern>
  3. 확장자만 일치하는 것 : <url-pattern>*.do</url-pattern>

서블릿 맵핑의 핵심

  1. 제일 먼저 정확히 이름이 일치하는 것을 찾음
  2. 다음으로 디렉토리가 일치하는 것을 찾음.
  3. 마지막으로 확장자가 일치하는 것을 찾음.
  4. 둘이상의 디렉토리가 일치할 때는 항상 많이 일치하는 것을 선택함.

DD에 환영 파일(디폴트 페이지) 설정하기

  • 전체 사이트 디폴트 웝페이지를 설정 가능 (conf/web.xml)
  • 개별 윕 애플리케이션의 디폴트 웹 페이지 설정
  • 선택 기준은 항목 리스트에 제일 먼저 일치하는 파일을 찾는다.

<web-app ..>
 <welcome-file-list>
   <welcome-file>index.html</welcome-file>
   <welcome-file>default.jsp</welcome-file>
 </welcome-file-list>
</web-app>             

DD에 오류 페이지 설정하기

예외사항별로 오류 페이지 정의하기
<error-page>
 <exception-type>java.lang.ArithmethicException</exception-type>
 <location>/arithmeticeError.jsp</location>
</error-page>

HTTP 상태 코드별로 오류 페이지 정의하기
<error-page>
 <error-code>404</error-code>
 <location>/arithmeticeError.jsp</location>
</error-page>

프로그램적으로 오류 코드 발생 시키는 예제

response.sendError(HttpServletResponse.SC_FORBIDDEN); 혹은 response.sendError(403);

DD에서 강제로 서블릿 초기화하기

  • <load-on-startup> 값을 0 보다 큰 값을 설정하면 컨테이너는 애플리케이션이 배포되는 시점에 서블릿을 초기화합니다. 값이 가장 작은 값 부터 먼저 로딩 함.
  • ** 값이 동일하면 먼저 설정된 것 부터 로딩합니다.

<servlet>
 <servlet-name>KathyOne</servlet-name>
 <servlet-class>foo.DeployTestOne</servlet-class>
 <load-on-startup>1</load-on-startup>
</servlet>             

XML에 부합하는 JSP 만들기 : JSP 문서

항목
일반 JSP 페이지 문법
JSP 문서 문법
지시자
(taglib제외)
<%@ page import=”java.util.*” %>
<jsp:directive.page import=”java.util.*” />
선언문
<%! int y = 3; %>
<jsp:declaration>
 int y = 3;
</jsp:declaration>
스크립틀릿
<% list.add(“Fred”); %>
<jsp:scriptlet>
 list.add(“Fred”);
</jsp:scriptlet>
텍스트
There is no tags
<jsp:text>
 There is no tags
</jsp:text
스크립팅
표현식
<%= it.next() %>
<jsp:expression>
 it.next()
</jsp:expression>

EJB 관련 태그들

지역(로컬) 빈에 대한 참조
<ejb-local-ref>
 <ejb-ref-name>ejb/Customer</ejb-ref-name> --> JNDI 로 검색
 <ejb-ref-type>Entity</ejb-ref-type>
 <local-home>com.wickedlysmart.CustomerHome</local-home>
 <local>com.wickedlysmart.Customer</local>
</ejb-local-ref>            
원격(리모트) 빈에 대한 참조
<ejb-ref>
 <ejb-ref-name>ejb/Customer<ejb-ref-name> --> JNDI 로 검색
 <ejb-ref-type>Entity<ejb-ref-type>
 <home>com.wickedlysmart.CustomerHome</home>
 <remote>com.wickedlysmart.Customer/<remote>
</ejb-ref>             
**  관련 태크는 리모트가 먼저 생겼으면 지역빈 나중에 생겨서 이름위 같이 되었음.

JDNI <env-entry> DD 태크

<env-entry>
 <env-entry-name>rates/discountRate</env-entry-name>
 <env-entry-type>java.lang.Integer</env-entry-type>
 <env-entry-value>10</env-entry-value>
</env-entry>            

<mime-mapping> DD 태그

<mime-mapping>
 <extension>mpg</extension> : 확장자
 <mime-type>video/mpeg</mime-type> : MIME 타입
</mime-mapping>          

어디로 가야 하나

자원 유형
배포 위치
배포 서술자
WEB-INF 바로 밑에(WEB-INF는 웹 애플리케이션 루트 바로 밑에 있음)
태그 파일
JAR 배포가 아닌 경우에는 WEB-INF/tags 혹은 WEB-INF/tags 하위 디렉토리로 배포
JAR 파일 배포 한다면, META-INF/tags 또는 META-INF/tags 하위 디렉토리로 배포 해야 함.
** 태그 파일을 JAR로 배포 하는 경우 JAR안에 TLD 파일이 들어 이어야 합니다.
HTML과 JSPs
(직접 접근 가능)
클라이언트가 접근할 수 있도록 HTML과 JSP를 배포하려면, WEB-INF와 WEB-INF 하위 디렉토리를 제외하고는 웹 어플리케이션 루트 밑이라면 어디라도 좋음. WAR파일로 배포 할때도 META-INF와 그 하위 디렉토리만 제외하고는 배포 가능 합니다.
HTML과 JSPs
(직접 접근 불가)
WEB-INF 하위 (WAR 배포시는 META-INF)
TLDs
(.tld)
JAR 배포가 아니라면 , TLD는 WEB-INF 또는 WEB-INF 하위 디렉토리로 배포
JAR 파일로 배포 한다면 TLD는 META-INF 또는 META-INF 하위 디렉토리로 배포 해야 합니다.
서블릿 클래스
서블릿 클래스는 WEB-INF/classes 디렉토리 밑에 패키지 구조가 그대로 디렉토리 구조로 바뀌어 들어가면 됨.
JAR 파일로 배포 한다면 패키지 디렉토리 구조를 JAR 파일로 만든 다음 WEB-INF/lib 아래에 배포 하면 됩니다.
태그 핸들러 클래스
서블릿 클래스 규칙과 동일함.
JAR 파일
JAR파일은 WEB-INF/lib 아래에 있어야 합니다.