시큐리티는 허가된 사용자만이 특정 웹 페이지에 접근할 수 있도록 제한하는 보안 기능을 말한다. 사용자가 웹 브라우저를 사용하여 웹 페이지에 접근할 때 JSP 컨테이너는 요청된 페이지에 보안 제약이 있는지 확인하고 사용자에게 인증(authentication)을 요청한다. 이러한 인증은 일반적으로 사용자의 이름과 암호를 확인하여 수행된다. 인증되면 JSP 컨테이너는 특정 사용자가 해당 페이지에 접근할 수 있는지 확인하여 승인하는데 이를 권한 부여(authorization)라고 한다. 시큐리티는 사용자가 권한이 없는 데이터에 접근하는 것을 막거나 웹 공격자가 전송 데이터를 중간에 가로채는 것을 방지하는 등 중요한 역할을 한다.
| 시큐리티 처리 방법 | 설명 |
|---|---|
| 선언적 시큐리티 | 코드 작성 없이 web.xml 파일에 보안 구성을 작성하여 사용자의 인증을 수행하는 방식이다. |
| 프로그래밍적 시큐리티 | request 내장 객체의 메소드를 통해 사용자의 권한 부여를 처리하는 프로그래밍 방식이다. |
웹 애플리케이션의 인증과 권한 부여를 위해 톰캣 서버에 사용자와 역할을 쉽게 생성하고 구성 할 수 있다. 톰캣 서버에 인증 정보가 저장되는 장소는 /설치된 톰캣의 루트/conf/ 폴더 내의 tomcat-users.xml 파일로, 다음과 같은 형식으로 사용자와 역할이 구성되어 있다. 또는 이클립스 내에 웹 애플리케이션과 톰캣 서버 간에 연동하기 위해 생성한 Server 프로젝트 내의 tomcat-users.xml 파일에 사용자와 역할이 구성되어 있다. tomcat-users.xml 파일에서 주석 부분 (<!--, -->)을 해제해야 기존에 설정된 역할과 사용자를 사용하거나 새로운 역할과 사용자를 추가할 수 있다.
// Servers\Tmocat\tomcat-users.xml
<tomcat-users>
<role rolename="tomcat"/>
<role rolename="role1"/>
<role rolename="admin"/>
<user username="tomcat" password="1234" roles="tomcat"/>
<user username="both" password="1234" roles="tomcat,role1"/>
<user username="role1" password="1234" roles="role1"/>
<user username="admin" password="1234" roles="admin"/>
</tomcat-users>
선언적 시큐리티는 웹 애플리케이션 배포 설명자 web.xml 파일에 보안구성을 작성하여 수행하는 방식이다. 즉 웹 애플리케이션의 보안을 달성하기 위해 별도의 코드를 작성할 필요 없이 web.xml파일에 보안 구성을 작성하여 사용자가 웹 페이지에 접근할 수 있게 한다. web.xml 파일에는 보안 역할, 보안 제약 사항, 인증 처리 등을 설정하여 보안을 구성한다.
<security-role>은 웹 애플리케이션에 사용하는 역할을 나열하는 요소이다. <security-role> 요소는 web.xml 파일에 구성한다.
<security-role>
<role-name>역할 이름</role-name>
</security-role>
여기서 <role-name요소에 설정하는 역할 이름은 반드시 tomcat-users.xml에 등록된 역할과 사용자여야 한다. 다음은 웹 애플리케이션에서 사용되는 역할 manager와 employee를 설정하는 예이다.
<security-role> 요소 사용 예]<security-role>
<role-name>manager</role-name>
</security-role>
<security-role>
<role-name>employee</role-name>
</security-role>
시큐리티 제약 사항은 사용자의 요청 URL에 대한 접근 권한을 정의하는데 사용한다. 시큐리티 제약 사항은 web.xml 파일에 접근 권한 내용을 구성한다.
<security-constraint>
<web-resource-collection>....</web-resource-collection>
<auth-constraint>...</auth-constraint>
<user-data-constraint>...</user-data-constraint>
</security-constraint>
| 요소 | 설명 |
|---|---|
<web-resource-collection> | 웹 자원에 대한 접근을 설정한다. |
<auth-constraint> | 웹 자원에 접근할 수 있는 인증된 사용자를 설정한다. |
<user-data-constraint> | 데이터 전송 시 데이터 보호를 설정한다. |
<web-resource-collection> 요소<web-resource-collection은 웹 자원에 대한 접근을 설정하는 요소이다. <web-resource-collection> 요소는 <url-pattern>, <http-method>, <web-resource-name>등의 하위 요소로 구성된다.
<web-resource-collection>
<web-resource-name>자원 이름</web-resource-name>
<url-pattern>접근 제한 URL</url-pattern>
<http-method>전송 방식(GET/POST)</http-method>
</web-resource-collection>
| 요소 | 설명 |
|---|---|
<web-resource-name> | 웹 자원의 이름을 설정하며 생략할 수 있다. |
<url-pattern> | 접근 제한을 요청할 URL 목록을 설정한다. 자원에 대한 접근을 제한하지 않는 경우 생략할 수 있다. |
<http-method> 또는 <http-method-omission> | http 메소드를 설정한다. |
다음은 웹 애플리케이션에서 /cart/ 폴더의 하위 경로에 보안을 설정하는 예이다. 예를 들어 사용자가 http://localhost:8080/WebMarket/index.jsp 와 같이 보안 경로 /cart/에 위치한 index.jsp 페이지를 요청하면 권한이 있는 사용자만 접근할 수 있다.
<web-resource-collection> 요소 사용 예]<security-constraint>
<web-resource-collection>
<web-resource-name>WebMarket</web-resource-name>
<url-pattern>cart/*</url-pattern>
</web-resource-collection>
</security-constraint>
<auth-constraint> 요소권한이 부여된 사용자만이 웹 자원에 접근할 수 있도록 이름을 설정하는 요소이다. <auth-constraint> 요소에는 <web-resource-collection> 요소의 <url-pattern> 과 <http-method>에 설정된 경로에 접근할 수 있는 권한이 부여된 사용자의 이름을 지정한다. <auth-constraint>요소를 생략하면 웹 서버는 사용자 인증을 요구하지 않고 사용자의 요청을 승인한다.
<auth-constraint>요소는 <role-name>, <description> 등의 하위 요소로 구성된다. 이때 <role-name> 요소는 필요한 만큼 설정할 수 있다.
<auth-constraint>
<description>설명</description>
<role-name>역할 이름</role-name>
</auth-constraint>
다음은 권한이 부여된 사용자 이름으로 manager를 설정하는 예이다. <role-name> 에 설정한 manager는 반드시 tomcat-users.xml 파일에 역할과 사용자가 등록되어 있어야 한다.
| 요소 | 설명 |
|---|---|
<description> | 권한 부여 제약 사항에 대한 설명을 기술한다. |
<role-name> | 권한이 부여된 사용자의 이름을 대문자와 소문자를 구분하여 설정한다. 이때 반드시 tomcat-users.xml에 등록된 역할과 사용자여야 한다. 만약 모든 사용자에게 권한을 부여하려면 *로 표시한다. <role-name>요소를 생략하면 <url-pattern>요소에 설정된 접근 제한 URL에 대한 사용자의 요청을 허용하지 않는다. |
<auto-constraint> 요소 사용 예]<security-constraint>
<auth-constraint>
<description>관리자</description>
<role-name>manager</role-name>
</auth-constraint>
</security-constraint>
<user-data-constraint> 요소<user-data-constraint>는 클라이언트와 서버 간에 데이터를 전송할 때 데이터를 보호하는 방법을 설정하는 요소이다.
<user-data-constraint>
<transport-guarantee>NONE/INTEGRAL/
</user-data-constraint>
| 종류 | 설명 |
|---|---|
| NONE | 기본 값으로 데이터를 보호하지 않겠다는 의미이다. |
| INTEGRAL | 전송 중 데이터가 변경되지 않았음을 보장한다는 의미이다. |
| CONFIDENTIAL | 전송 중 데이터를 아무도 훔펴보지 않았음을 보장한다는 의미이다. |
<user-data-constraint> 요소 사용 예]<security-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
시큐리티 인증은 인증 처리를 위한 로그인 페이지나 오류 페이지를 호출하는 데 사용한다. 시큐리티 인증은 web.xml 파일에 인증 관련 내용을 구성한다.
<login-config>
<auth-method>...</auto-method>
<realm-name>...</realm-name>
<form-login-config>...</form-login-config>
</login-config>
<login-config> 요소는 <security-constraint> 요소에 설정된 접근 제한 자원에 사용자가 접근하는 경우 해당 자원의 접근을 위한 인증 처리 방법을 활성화한다. 또한 사용자에게 로그인 관련 메시지를 표시할 수 있다.
| 요소 | 설명 |
|---|---|
<auth-method> | 웹 자원에 대한 인증 처리 방식을 설정한다. |
<realm-name> | 웹 자원에 접근할 수 있는 인증된 사용자를 설정한다. |
<form-login-config> | 데이터 전송 시 데이터 보호를 설정한다. |
<auth-method> 요소<auth-method>는 웹 애플리케이션의 인증 처리 기법을 설정하는 요소이다. 인증 처리 기법은 BASIZ, DIGEST, FORM, CLIENT-CERT 등으로 이 중 하나를 <auth-method> 요소에 설정한다.
| 종류 | 설명 |
|---|---|
| BASIC | 웹 자원을 보호하는 간단하고 일반적인 방법이다. |
| DIGEST | 암호화 메커니즘을 이용하여 전송한다. 많이 사용되지 않는 암호화 기법으로 JSP 컨테이너가 반드시 지원하지 않을 수도 있다. |
| FORM | 일반적인 폼 페이지를 이용하여 로그인 정보를 서버에 전송하는 방식이다. 암호화되지 않은 로그인 정보를 그대로 전송한다. |
| CLIENT-CERT | 클라이언트가 인증서를 가지고 공인 키 인증 방식을 사용하여 로그인하는 방식이다. 클라이언트가 인증서를 가지고 있어야만 로그인되므로 비즈니스 환경에서만 사용된다. |
<auth-method> 요소의 종류 중에서 FORM 기반 인증 처리를 사용하려면 정해진 규칙을 따라야 한다. FORM 기반 인증 처리는 웹 브라우저가 인증 처리에 직접적으로 관여하지 않기 때문에 사용자가 로그인 페이지에 인증 정보를 직접 입력해야 전달된다. 이때 로그인 페이지에서 form 태그의 action 속성 값, 사용자 아이디와 비밀번호 등 input 태그의 name 속성 값은 다음과 같이 설정한다.
| 속성 이름 | 속성 값 |
|---|---|
| form 태그의 action 속성 | j_security_check |
| 사용자의 name 속성 | j_username |
| 비밀번호의 name 속성 | j_password |
<form action="j_security_check" method="post">
아이디: <input type="text" name="j_username">
비밀번호: <input type="password" name="j_password">
<input type="submit" value="로그인">
</form>
<realm-name> 요소<realm-name> 은 기본 인증의 영역 이름을 설정하는 요소이다. <realm-name> 요소에 설정된 영역 이름은 대개 웹 브라우저의 로그인 대화상자에 표시돤다. <realm-name> 요소는 FORM 기반 인증이나 다른 인증 방법에 필요하지 않기 때문에 아무런 영향을 미치지 않지만, <login-config> 요소에 대한 설명 속성이 없으므로 데이터를 문서화하는 데 일반적으로 사용된다.
<realm-name> 요소 사용 예]<login-config>
<realm-name>login</realm-name>
</login-config>
<form-login-config> 요소<form-login-config>는 인증 처리를 위한 로그인 및 오류 페이지를 설정하는 요소이다. <form-login-config> 요소는 <auth-method> 요소가 FORM 기반 인증 처리 기법으로 설정되었을 때 사용된다. <form-login-config> 요소는 <form-login-page>, <form-error-page> 등의 하위 요소로 구성된다. 로그인 및 오류 페이지의 경로는 웹 애플리케이션 이름을 기준으로 설정된다.
| 요소 | 설명 |
|---|---|
<form-login-page> | 인증을 위한 로그인 페이지를 설정한다. |
<form-error-page> | 인증 실패 시 표시할 오류 페이지를 설정한다. |
<login-config> 요소 사용 예: 폼 기반 인증]<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>login.jsp</form-login-page>
<form-error-page>error.jsp</form-error-page>
</form-login-config>
</login-config>
프로그래밍적 시큐리티는 웹 애플리케이션의 보안을 위해 코드를 작성하여 사용자의 권한 부여를 처리하는 방식이다. 선언적 시큐리티의 보안으로 충분하지 않을때 request 내장 객체의 메소드를 사용하여 사용자를 승인하는 방법이다.
| 메소드 | 형식 | 설명 |
|---|---|---|
| getRemoteuser() | String | 사용자의 인증 상태를 반환한다. |
| getAuthType() | String | 서블릿을 보호하는 데 사용되는 인증 방식의 이름을 반환한다. |
| isUserInRole(String role) | boolean | 현재 인증된 사용자에게 설정된 역할이 있는지 확인한다. 설정된 경우 true를 반환하고 그렇지 않은 경우 false를 반환한다. |
| getProtocol() | String | 웹 브라우저의 요청 프로토콜을 가져온다. |
| isSecure() | boolean | 웹 브라우저에서 https 요청으로 request가 들어왔는지 확인한다. 웹 브라우저에서 https로 접근하면 true를 반환하고, http로 전근하면 false를 반환한다. |
| getUserPrinciple() | Principle | 현재 인증한 사용자의 이름을 포함하여 Pricnciple 객체를 반환한다. |
<% if(request.isUserInRole("admin")) { %>
<a href="admin/addProduct.jsp">상품 등록</a>
<a href="admin/member.jsp">회원 관리</a>
<% } %>