Dec 15

프로젝트에서 Tomcat 5.5 환경에서 개발을 하다 실 서버 환경이 Tomcat에서 Jeus 6로 변경되었다.

다행스럽게 사용하는 태그라이브러리가 별다른 문제없이 동작되는 것을 확인했었는데,

우연히 IE를 사용하여 테스트 중 특정 페이지가 제대로 출력되지 않는 문제를 발견했다.

소스에는 문제가 없었는데 이유는 단순하게도 IE의 인코딩이 문제가 되는 페이지만

UTF-8 인코딩을 EUC-KR로 잘못 인지하는 것이다.

게다가 원인은 <fmt:formatDate />태그를 사용하면 인코딩이 잘못 인지되는 것이었다.

이를 해결하기 위해서는 <fmt:formatDate />태그를 사용하기 전에 <fmt:setLocale value=”UTF-8″/> 를 추가하면 된다.

<%@page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ko" lang="ko">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
...
<jsp:useBean id="testDate" class="java.util.Date"/>
<fmt:setLocale value="UTF-8"/>
날짜: ${testDate}
<fmt:formatDate pattern="yyyy.MM.dd" value="${testDate}"/>
</body>
</html>
Aug 20

Tomcat을 사용할 때 가끔씩 다음과 같은 오류가 발생할 때가 있다.

경고: Parameters: Invalid chunk ignored.

이것은 Tomcat의 Parameters 클래스에서 출력하는 것으로 Tomcat 5.5.27 소스를 보면 다음과 같다.

apache-tomcat-5.5.27-src/connectors/util/java/org/apache/tomcat/util/Parameters.java

public void processParameters( byte bytes[], int start, int len,
        String enc )
{
...
    if( nameEnd<=nameStart ) {
        log.warn("Parameters: Invalid chunk ignored.");
        continue;
        // invalid chunk - it's better to ignore
    }
...
}

소스를 보면 이 경고 메시지는 매개변수 명과 값이 구분안되는 경우 (예를 들어 요청중에  &= 또는 &&와 같은 경우) 나타날 수 있다.

호출하는 쪽을 수정하면 좋으나 이것이 불가능할 때는 오류 메시지가 출력되지 않도록 할 수 밖에 없다.

CATALINA_HOME/conf/logging.properties 파일의 마지막에 다음 줄을 추가하고 Tomcat을 재시작 한다.

org.apache.tomcat.util.http.Parameters.level = SEVERE
Aug 13

Tomcat과 같은 어플리케이션 서버를 사용한 인증 방법을 간단히 정리하면 다음과 같다.

1. 어플리케이션 서버

Tomcat에서는 server.xml 파일에 사용자 지정 Realm 설정을 한다.

예제에서는 member 테이블의 email 컬럼을 사용자명으로, MD5로 암호화된 passwd 컬럼을 암호로 사용하고,

역할은 role 컬럼을 사용하도록 했다.

<Realm className="org.apache.catalina.realm.JDBCRealm"
 driverName="com.mysql.jdbc.Driver"
 connectionURL="jdbc:mysql://localhost:3306/sample?useUnicode=true"
 connectionName="user1" connectionPassword="password"
 userTable="member" userNameCol="email" userCredCol="passwd" digest="MD5"
 userRoleTable="member" roleNameCol="role"
/>

2. 웹 어플리케이션

해당 웹 어플리케이션의 web.xml 파일을 설정한다.
여기에서는 예로 /protected 란 디렉토리의 모든 파일을 요청할 때 인증이 필요하며,
인증된 계정은 Admin이나 SuperAdmin의 Role을 가지고 있어야 한다고 설정했다.

<security-constraint>
 <display-name>보안 설정</display-name>
 <web-resource-collection>
 <web-resource-name>SiteManager</web-resource-name>
  <url-pattern>/protected/*</url-pattern>
  <http-method>GET</http-method>
  <http-method>POST</http-method>
 </web-resource-collection>
 <auth-constraint>
  <description>사이트 관리자</description>
  <role-name>Admin</role-name>
  <role-name>SuperAdmin</role-name>
 </auth-constraint>
</security-constraint>

<login-config>
 <auth-method>FORM</auth-method>
 <realm-name>Site Managers</realm-name>
 <form-login-config>
  <form-login-page>/login.jsp</form-login-page>
  <form-error-page>/login_error.jsp</form-error-page>
 </form-login-config>
</login-config>

<security-role>
 <role-name>Admin</role-name>
</security-role>
<security-role>
 <role-name>SuperAdmin</role-name>
</security-role>

로그인 폼인 login.jsp 파일은 다음과 같이 간단하며 로그인이 성공하면 요청한 페이지로 자동으로 이동된다.

<form method="POST" action="j_security_check">
  <input type="text" name="j_username">
  <input type="password" name="j_password">
  <input type="submit" value="로그인">
</form>

로그인이 되면 다음과 같이 로그인 된 회원 정보를 확인할 수 있다.

String remoteUser = request.getRemoteUser();
java.security.Principal principal = request.getPrincipal();
String username = principal.getName();
boolean isAdmin = request.isUserInRole("Admin");
boolean isSuperAdmin = request.isUserInRole("SuperAdmin");

3. 참고