애플리케이션과 모듈에서 보안 설정

본 장에서는 Jakarta EE 애플리케이션과 EJB 모듈, 웹 모듈에서 보안을 설정하는 방법을 설명한다.

1. 개요

본 절에서는 애플리케이션과 모듈에 보안을 설정하는 것과 관련된 가장 기본적인 이슈를 설명한다.

Jakarta EE 애플리케이션, EJB 모듈, 웹 모듈의 가장 기본적인 보안 설정 과정은 다음과 같다.

  1. Role-to-Resource 매핑을 각 모듈마다 설정한다.

  2. 각 애플리케이션에 대해 Principal-to-Role 매핑을 정의한다.

1.1. 모듈 Deployment 대 애플리케이션 Deployment

JEUS에서 deploy하는 방법은 크게 2가지로 나누어진다.

  • EJB 모듈(.jar 파일), 웹 모듈(.war 파일)을 각각 독립적으로 deploy하는 방법

  • 여러 개의 EJB 모듈, 웹 모듈, Connector 모듈(.rar)을 EAR로 압축하여 Jakarta EE 애플리케이션(.ear)으로 deploy하는 방법

1.2. Role-to-Resource 매핑

Assembler는 EJB 모듈이나 웹 모듈을 deploy하기 전에 해당 모듈에 Role-to-Resource 매핑을 설정해야 한다. Role-to-Resource 매핑을 보안 제약(security constraint)이라고 하며, 논리적인 Role에 모듈의 리소스를 매핑하는 것을 의미한다.

  • EJB 모듈에서 리소스는 EJB의 메소드를 의미하며, META-INF/ejb-jar.xml에 설정한다.

  • 웹 모듈에서 리소스는 서블릿 URL을 의미하며, WEB-INF/web.xml에 설정한다.

다음은 EJB 모듈에 설정된 보안 제약 내용으로 META-INF/ejb-jar.xml에 설정에 대한 설명이다.

EJB 모듈에 설정된 보안 제약 : <ejb-jar.xml>
<?xml version="1.0"?>
<ejb-jar xmlns="http://java.sun.com/xml/ns/j2ee">
    <display-name>product</display-name>
    <enterprise-beans>
        <entity>
          <ejb-name>product</ejb-name> (1)
            . . .
           <security-role-ref> (2)
                <role-name>cust</role-name>
                <role-link>customer</role-link>
            </security-role-ref>
        </entity>
    </enterprise-beans>
    <assembly-descriptor>
        . . .
       <security-role> (3)
            <role-name>administrator</role-name>
        </security-role>
       <security-role> (4)
            <role-name>customer</role-name>
        </security-role>
       <method-permission> (5)
            <role-name>administrator</role-name>
            <method>
                <ejb-name>product</ejb-name>
                <method-intf>Remote</method-intf>
                <method-name>getSecretKey</method-name>
                <method-params>
                   <method-param>java.lang.Integer</method-param>
                </method-params>
            </method>
        </method-permission>
      <method-permission> (6)
            <unchecked/>
            <method>
                <ejb-name>product</ejb-name>
                <method-name>doSomeAdmin</method-name>
                <method-params>
                    <method-param>java.lang.String</method-param>
                </method-params>
            </method>
        </method-permission>
       <method-permission> (7)
            <role-name>customer</role-name>
            <method>
                <ejb-name>product</ejb-name>
                <method-name>test1</method-name>
            </method>
        </method-permission>
       <exclude-list> (8)
            <method>
                <ejb-name>product</ejb-name>
                <method-intf>Remote</method-intf>
                <method-name>getCustomerProfile</method-name>
                <method-params></method-params>
            </method>
        </exclude-list>
    </assembly-descriptor>
</ejb-jar>

DD 파일의 각 부분이 의미하는 보안 제약 사항은 다음과 같다.

1 "product"라 불리는 Entity EJB가 있다.
2 Role-to-Role Reference 매핑이 선언되어 있다. 실제 선언된 Role인 "customer"는 "cust"라는 Role Reference로 참조될 수 있다. 이는 EJB 소스 내에 "cust"라는 이름의 Role은 실제로는 "customer" Role에 해당한다는 것을 의미한다.
3 논리적 Role인 "administrator"가 선언되어 있다.
4 논리적 Role인 "customer"가 선언되어 있다.
5 Role-to-Resource 매핑이 선언되어 있는데, 이는 "administrator" Role이 리모트 EJB 인터페이스의 getSecreteKey 메소드를 호출할 수 있도록 허락한다. 이 매핑에 따라 오직 "administrator" Role에 속하는 Principal만이 getSecreteKey 메소드를 호출할 수 있다.
6 doSomeAdmin 메소드는 Unchecked로 선언되어 있다. 즉, 누구나 Role에 상관없이 이 메소드를 호출할 수 있다는 의미이다.
7 "customer" Role에 속하는 Principal은 "product" EJB의 "test1" 메소드를 호출할 수 있다.
8 getCustomerProfile 메소드는 Excluded 목록에 포함되어 있다. 즉, Role에 상관없이 어떤 Role도 해당 메소드를 호출할 수 없다는 의미이다.

웹 모듈에 대해서도 EJB와 비슷한 설정이 적용된다. 단, EJB에서 Role이 EJB 메소드를 호출할 수 있느냐의 문제였다면 웹 모듈에서는 Role이 서블릿 URL에 접근할 수 있느냐의 문제를 다룬다. 웹 모듈 보안 설정에 대한 자세한 정보는 웹 모듈 보안 설정을 참고한다.

지금까지 언급한 2가지 Role, 즉 "administrator"와 "customer"는 논리적 개념으로 실제 deploy되는 환경을 의미하지 않는다. 따라서, 논리적 Role을 실제 환경의 사용자나 사용자 그룹에 매핑하는 작업이 필요하다. 이 작업을 Principal-to-Role 매핑이라 하는데 자세한 내용은 Principal-to-Role 매핑에서 설명한다.

1.3. Principal-to-Role 매핑

일반적으로 Deployer가 Jakarta EE 모듈 또는 애플리케이션에 정의된 Role을 실제 환경의 사용자나 사용자 그룹에 매핑하는 작업을 한다. 여기서, Principal을 논리적 Role에 매핑하는 것은 애플리케이션 범위(scope)를 가진다는 점에 주의해야 한다.

예를 들어 모듈 M1과 M2가 A1이라는 애플리케이션에 포함되어 있다면, Principal-to-Role 매핑은 M1과 M2에서 공유된다. 더 나아가 A2라는 별도의 애플리케이션은 A1과는 완전히 다른 Principal-to-Role 매핑을 가진다. A1과 A2에서 동일한 이름의 Role이 있다고 하더라도 이들은 서로 다른 Role로 인식되며 공유되지 않는다.

다음 그림은 이러한 범위와 관련된 개념에 대한 설명이다.

figure principal to role mapping
Principal-to-Role 매핑

위 그림에서 보듯이 2개의 서로 다른 애플리케이션(A1, A2)가 서로 다른 Principal-to-Role 매핑을 가지고 있으며, 포함되어 있는 모듈(M1, M2)은 애플리케이션이 포함하고 있는 매핑을 공유한다.

JEUS에서 Principal-to-Role 매핑은 다음의 파일에 설정된다.

  • JEUS DD인 jeus-ejb-dd.xml(EJB 모듈)

  • jeus-web-dd.xml(웹 모듈)

  • jeus-application-dd.xml(Jakarta EE 애플리케이션)

다음은 ejb-jar.xml에 대한 jeus-ejb-dd.xml의 설정 예이다.

Principal-to-Role 매핑 : <jeus-ejb-dd.xml>
<?xml version="1.0"?>
<jeus-ejb-dd xmlns=“http://www.tmaxsoft.com/xml/ns/jeus”>
     <module-info>
       <role-permission> (1)
            <principal>user1</principal>
            <role>administrator</role>
            <classname>mypackage.MyRolePermission</classname>
        </role-permission>
       <role-permission> (2)
            <principal>user2</principal>
            <role>customer</role>
        </role-permission>
       <role-permission> (3)
            <role>roleA</role>
            </excluded>
        </role-permission>
       <role-permission> (4)
            <role>roleB</role>
            </unchecked>
        </role-permission>
       <unspecified-method-permission> (5)
            <role>administrator</role>
        </unspecified-method-permission>
    </module-info>
    <beanlist>
        . . .
    </beanlist>
</jeus-ejb-dd>

위의 예제는 다음과 같은 보안 정보를 담고 있다.

1 "user1"이라는 Principal(user)에게 "administrator" Role을 허가하는 Role Permission이 선언되어 있다. 이는 "user1"이 "administrator" Role의 모든 권한을 가지게 되었다는 것을 의미한다.

예제에서 보듯이 Custom Role Permission은 <classname> 태그로 정의한다. Custom Role Permission에 대한 자세한 정보는 보안 시스템 설정을 참고한다.

2 "user2"라는 Principal(user)에게 "customer" Role을 부여하는 Role-Permission이 선언되어 있다. 이는 "user2"가 "customer" Role이 가지는 모든 권한을 가지게 되었다는 의미이다. <classname> 태그가 설정되어 있지 않았으므로, 디폴트 Role Permission이 설정되어 있다.
3 "roleA"라는 Role은 모든 Principal로부터 배제되어(excluded) 있다. 즉, 어떤 Principal도 "roleA"에 포함될 수 없다.
4 "roleB"라는 Role은 권한 부여 시스템에서 체크되지 않는다.(unchecked) 즉, 모든 Principal은 자동으로 "roleB"에 포함된다.
5 <unspecified-method-permission>은 "unspecified" EJB 메소드를 기본적으로 어떻게 다룰지 결정한다. "unspecified" EJB 메소드는 ejb-jar.xml에서 <method-permission> 태그로 언급되지 않은 메소드를 의미한다. <unspecified-method-permission>은 3가지 방식으로 처리할 수 있다. Role에 매핑(예제에서는 "administrator" Role에 매핑되었다)하거나, excluded(누구도 접근할 수 없는 것)로 취급하거나, unchecked(누구나 접근할 수 있는 것)로 취급하는 것이 그것이다. 마지막 unchecked 옵션이 기본값이다.

웹 모듈(jeus-web-dd.xml)의 설정은 <unspecified-method-permission> 설정이 없다는 것을 제외하고, EJB 모듈에서 설정과 동일하다.

1.4. 사용자 설정

사용자 설정은 크게 2가지로 나누어진다.

  • 애플리케이션에서 사용하는 도메인 자체의 사용자 설정을 이용하는 방식으로 다음의 파일에 설정한다. (보안 시스템 사용자 정보 설정 참조)

    JEUS_HOME/domains/<domain name>/config/security/<security domain name>/accounts.xml
  • EJB 모듈(.jar 파일), 웹 모듈(.war 파일), Jakarta EE 애플리케이션(.ear)자체의 사용자 설정 방식으로 WEB-INF(웹 모듈) 또는 META-INF(EJB 모듈 및 EAR) 디렉터리 안의 accounts.xml을 설정한다.

사용자 정보는 위의 어떤 방식으로 설정을 했는지에 관계없이 애플리케이션의 보안 도메인 범위(scope)을 가진다. 즉, 한 보안 도메인에서의 사용자는 같은 보안 도메인을 사용하는 모든 애플리케이션 내에서 공유된다.

2. EJB 모듈 보안 설정

본 절에서는 EJB 모듈에 보안 설정하는 방법을 자세하게 설명한다. 본 절에서 다루지 않은 CSI와 같은 보안 설정들은 JEUS EJB 안내서를 참고한다.

보안 설정 방법은 크게 2가지로 나눌 수 있다.

2.1. ejb-jar.xml 설정

ejb-jar.xml에 다음과 같은 보안 요소를 설정할 수 있다.

  • Role-to-Role Reference 매핑

  • security identity 설정

  • 논리적 Role 선언

  • EJB 메소드 Permission 설정

다음 예제는 위 보안 설정 요소를 포함하는 ejb-jar.xml이다.

보안 설정 : <ejb-jar.xml>
<?xml version="1.0"?>
<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee">
    <display-name>product</display-name>
    <enterprise-beans>
        <entity>
            <ejb-name>product</ejb-name>
            . . .
            <security-role-ref>
                <role-name>cust</role-name>
                <role-link>customer</role-link>
            </security-role-ref>
            <security-identity>
                <run-as>
                    <role-name>administrator</role-name>
                </run-as>
            </security-identity>
        </entity>
    </enterprise-beans>
    <assembly-descriptor>
        . . .
        <security-role>
            <role-name>administrator</role-name>
        </security-role>
        <security-role>
            <role-name>customer</role-name>
        </security-role>
        <method-permission>
            <role-name>administrator</role-name>
            <method>
                <ejb-name>product</ejb-name>
                <method-intf>Remote</method-intf>
                <method-name>getSecretKey</method-name>
                <method-params>
                   <method-param>java.lang.Integer</method-param>
                </method-params>
            </method>
        </method-permission>
        <method-permission>
            <unchecked/>
            <method>
                <ejb-name>product</ejb-name>
                <method-name>doSomeAdmin</method-name>
                <method-params>
                    <method-param>java.lang.String</method-param>
                </method-params>
            </method>
        </method-permission>
        <method-permission>
            <role-name>customer</role-name>
            <method>
                <ejb-name>product</ejb-name>
                <method-name>test1</method-name>
            </method>
        </method-permission>
        <exclude-list>
            <method>
                <ejb-name>product</ejb-name>
                <method-intf>Remote</method-intf>
                <method-name>getCustomerProfile</method-name>
                <method-params></method-params>
            </method>
        </exclude-list>
    </assembly-descriptor>
</ejb-jar>

ejb-jar.xml에 다음과 같은 보안 요소를 설정할 수 있다.

  • Role-to-Role Reference 매핑

    Role-to-Role Reference 매핑은 <security-role-ref> 태그로 정의한다. 목적은 실제 논리적 Role에 대한 참조를 설정하는 것이다. 그래서 EJB 소스에서는 실제 Role 대신 Role Reference를 사용하게 된다.

    다음은 <security-role-ref>의 하위 태그에 대한 설명이다.

    태그 설명

    <role-name>

    실제 Role에 대한 참조명으로 EJB 코드에는 실제 Role 이름 대신 참조명을 사용한다.

    <role-link>

    <security-role> 태그로 선언한 실제 Role 이름으로 Role Reference는 <role-link>가 가리키는 Role에 매핑된다.

  • Security Identity 설정

    모듈 내에 있는 각 EJB는 다른 EJB로 원격지를 호출할 때 자신의 Security Identity를 전파한다. EJB의 Security Identity는 <ejb-jar> <enterprise-beans> <type> <security-identity> 태그로 설정한다.

    다음의 하위 태그를 설정한다.

    태그 설명

    <use-caller-identity>

    empty 태그로 만일 설정되어 있으면, EJB를 호출할 때 호출자 자신이 Security Identity로 사용된다.

    <run-as>

    EJB가 호출할 때 <role-name>에 설정된 Role에 해당하는 principal을 Security Identity로 이용한다. jeus-ejb-dd.xml에 <run-as-identity> 태그가 있을 경우 이 설정은 무시된다.

  • 논리적 Role 선언

    <assembly-descriptior>의 하위 태그인 <security-role>는 해당 EJB 모듈에 적용되는 논리적 Role을 선언하는 태그이다. ejb-jar.xml에 언급되어 있는 모든 Role 이름은 이 태그 내에 선언되어 있어야 한다.

  • EJB 메소드 Permission 설정

    <assembly-descriptor>의 하위 태그인 <method-permission>는 각 EJB 메소드에 보안 제약을 설정하는 태그이다.

    다음은 <method-permission>의 하위 태그에 대한 설명이다.

    태그 설명

    <role-name> (선택)

    <security-role> 태그에 선언되어 있는 논리적 Role 이름으로 아래에 정의된 메소드에 접근할 수 있다.

    <unchecked> (선택)

    값이 없는 empty 태그로 설정되어 있으면 아래에 정의된 메소드는 권한 체크를 하지 않는다. 즉, Role에 상관없이 누구나 메소드에 접근할 수 있다.

    <method> (1개 이상)

    <role-name> 또는 <unchecked> 태그가 적용되는 메소드로 하위 태그는 다음과 같다.

    • <ejb-name> : 메소드를 포함하고 있는 EJB 이름이다.

    • <method-intf> : 메소드를 포함하고 있는 EJB 인터페이스 타입으로 생략되면, 로컬, 리모트 인터페이스 모두를 뜻하게 된다.

    • <method-name> : EJB 메소드 이름이다.

    • <method-params> (선택) : 0개 이상의 <method-param> 태그를 가질 수 있다. <method-param> 태그는 EJB 메소드의 각 파라미터를 나타낸다. 태그가 생략된 경우 메소드 이름만 동일하다면 파라미터와 상관없이 동일한 Permission이 적용된다. EJB에는 파라미터는 다르고 메소드 이름은 은 동일한 여러 개의 메소드가 있을 수 있다. 이 메소드들에 공통적으로 해당 Method Permission이 적용된다는 의미이다. <method-param> 태그 값은 패키지 이름을 포함한 완전한 Java 클래스 이름이거나, int와 같은 Java Primitive 타입이 될 수 있다. <method-params>를 empty 태그로 설정하면(<method-params/>) 매개변수가 하나도 없다는 것을 의미한다.

    <exclude-list> (1개)

    단 하나의 <exclude-list>가 올 수 있으며, Excluded되는 EJB 메소드를 정의한다. 즉, 누구도 접근할 수 없는 메소드이다. 하위 태그로 1개 이상의 <method> 태그를 가질 수 있다.

예제에 대한 설명은 Role-to-Resource 매핑을 참고한다. 각 태그에 대한 자세한 설명은 EJB 스펙을 참고한다. 또한 JEUS에서 EJB를 Deploy하는 방법은 JEUS EJB 안내서를 참고한다.

2.2. jeus-ejb-dd.xml 설정

jeus-ejb-dd.xml에 다음과 같은 보안 요소를 설정할 수 있다.

  • 보안 관련된 설정

  • ejb-jar.xml에 설정되어 있지 않는 EJB 메소드 설정

  • Run-as Identity를 사용하는 EJB Principal 설정

EJB에서 대부분 Role-to-Method 매핑은 ejb-jar.xml에 설정되어 있으나, ejb-jar.xml에서 설정되어 있지 않는 메소드를 어떻게 다룰지와 실제 Principal-to-Role 매핑을 어디서 선언할지는 여전히 해결해야 할 문제이다. 이는 EJB.jar 파일의 META-INF 디렉터리에 존재하는 jeus-ejb-dd.xml 파일에서 설정한다.

다음 예제는 위 보안 설정 요소를 포함하는 jeus-ejb-dd.xml이다.

보안 설정 : <jeus-ejb-dd.xml>
<?xml version="1.0"?>
<jeus-ejb-dd xmlns=“http://www.tmaxsoft.com/xml/ns/jeus”>
     <module-info>
        <role-permission>
            <principal>user1</principal>
            <role>administrator</role>
            <classname>mypackage.MyRolePermission</classname>
        </role-permission>
        <role-permission>
            <principal>user2</principal>
            <role>customer</role>
        </role-permission>
        <role-permission>
            <role>roleA</role>
            </excluded>
        </role-permission>
        <role-permission>
            <role>roleB</role>
            </unchecked>
        </role-permission>
        <unspecified-method-permission>
            <role>administrator</role>
        </unspecified-method-permission>
    </module-info>
    <beanlist>
        <jeus-bean>
            . . .
            <run-as-identity>
                <principal-name>user1</principal-name>
            </run-as-identity>
        </jeus-bean>
        . . .
    </beanlist>
</jeus-ejb-dd>

jeus-ejb-dd.xml에 다음과 같은 보안 요소를 설정할 수 있다.

  • 보안 관련된 설정

    jeus-ejb-dd.xml에서 대부분 보안 관련된 설정의 <jeus-ejb-dd> 루트 태그 바로 아래에 있는 <module-info> 태그 내에 설정된다.

    • <role-permission> (0개 이상)

      다음은 <role-permission>의 하위 태그에 대한 설명이다. 각 태그는 Role(Principal-to-Role 매핑)을 정의하고 있다.

      태그 설명

      <principal> (0개 이상)

      Role에 매핑되는 Principal 이름이다.

      <role> (필수)

      단 하나만 허락되며, 필수 항목으로 실제 논리적 Role 이름이다.

      Role Permission을 구현하는 Java 클래스의 생성자에 첫 번째 파라미터로 넘겨진다. Role 이름은 ejb-jar.xml에 선언된 Role 이름과 일치해야 한다.

      <actions> (선택)

      Role Permissionn에 대해 부가적인 정보를 제공한다. 만약 설정되어 있다면 액션 데이터는 Role Permission을 구현하는 Java 클래스의 두 번째 파라미터로 넘겨진다.

      <classname> (선택)

      Role Permission을 구현하는 클래스로 패키지 이름을 포함한 완전한 이름이어야 한다. 이 클래스는 java.security.Permission 클래스의 서브 클래스로 최소한 하나의 파라미터(Role의 이름)를 받는 public 생성자를 가지고 있어야 한다.

      생략되어 있다면 jeus.security.resource.RolePermission이 사용된다.

      <excluded> (선택)

      empty 태그로 만약 설정되어 있다면 해당 Role은 excluded된 것으로 취급한다(누구도 Role Permission에서 언급한 Role에 접근할 수 없다).

      <principal>, <unchecked> 태그보다 우선순위가 높다.

      <unchecked> (선택)

      empty 태그로 만약 설정되어 있다면, 해당 Role은 unchecked된 것으로 취급한다(누구나 Role Permission에서 언급한 Role에 접근할 수 있다).

      <principal> 태그보다 우선순위가 높다.

  • ejb-jar.xml에 설정되어 있지 않는 EJB 메소드 설정

    ejb-jar.xml에 설정되어 있지 않는 EJB 메소드들을 설정한다. <module-info>의 <unspecified-method-permission> 태그 내에 정의된다. 설정 가능한 하위 태그는 다음과 같다.

    태그 설명

    <role> (선택)

    설정되어 있다면 모든 설정되지 않는 메소드는 이 Role에 매핑된다.

    <excluded> (선택)

    설정되어 있다면 모든 설정되지 않는 메소드는 excluded 취급된다(누구도 접근할 수 없다).

    <role>이나 <unchecked> 태그보다 우선순위가 높다.

    <unchecked> (선택)

    설정되어 있다면 모든 설정되지 않은 메소드는 unchecked로 취급된다(누구나 접근할 수 있다).

    <role> 태그보다 우선순위가 높다.

  • Run-as Identity를 사용하는 EJB Principal 설정

    Run-as Identity를 사용하는 EJB에 대해 Principal을 설정은 <jeus-bean> <run-as-identity> <principal-name> 태그 내에 주어진 Principal 이름이 사용된다. Principal은 ejb-jar.xml에서 <security-identity> <run-as> <role-name> 태그 내에 설정된 Role 내에 포함되어 있어야 한다.

  1. 예제에 대한 자세한 설명은 Role-to-Resource 매핑을 참고한다.

  2. 각 태그에 대한 자세한 정보는 JEUS EJB 안내서를 참고한다.

3. 웹 모듈 보안 설정

본 절에서는 웹 모듈(서블릿 모듈)에 보안 설정하는 방법을 설명한다.

웹 모듈의 보안 설정은 크게 2가지로 구성된다.

3.1. web.xml 설정

web.xml은 Web Archive(WAR 파일)에 대한 메인 DD 파일이다. 표준 Jakarta EE DD 파일로 WAR 파일의 WEB-INF 디렉터리 내에 있다.

web.xml에서 설정할 수 있는 보안 요소는 다음과 같다.

  • Run-as Identity

    웹 모듈에 포함되어 있는 서블릿은 EJB로 원격 호출을 할 때 자신의 Security identity를 전파한다.

    서블릿의 Security identity는 <web-app><servlet><run-as> 태그 내에 설정되고, 다음과 같은 하위 태그를 가진다.

    태그 설명

    <role-name> (선택)

    서블릿을 실행하는 Role로 생략하면 호출자의 identity가 사용된다.

  • Role-to-role reference 매핑

    Role-to-role reference 매핑은 <security-role-ref> 태그로 설정하며, Role Reference를 실제 논리적 Role에 매핑하는 것이 목적이다. Role Reference는 서블릿 코드에서 Role을 나타낼 때 사용된다.

    web.xml에서 <security-role-ref> 태그는 <servlet> 내에 설정되며, 다음과 같은 하위 태그를 가진다.

    태그 설명

    <role-name>

    서블릿 코드에 사용되는 Role 이름이다.

    <role-link>

    <security-role> 태그로 정의한 실제 Role 이름으로 <role-name> 태그에 설정된 Role Reference를 실제 Role에 매핑한다.

  • 서블릿 URL 접근 Permissions (Security constraints, 보안제약)

    서블릿 URL에 접근을 제한하려는 목적으로 <web-app> 태그 바로 아래에 있는 <security-constraint> 태그를 사용한다.

    <security-constraint>는 다음과 같은 하위 태그를 가진다.

    • <web-resource-collection> (1개 이상)

      접근 제한이 설정되는 웹 리소스의 목록을 나타낸다.

      태그 설명

      <web-resource-name>

      웹 리소스 이름이다.

      <url-patterns> (0개 이상)

      웹 리소스를 나타내는 URL(contextroot에 상대 경로로 지정) 패턴이다.

      다음은 URL 패턴의 예이다.

      • /mywebapp/* : mywebapp가 포함된 모든 URL

      • /something : 정확한 URL

      • *.jsp : JSP로 끝나는 모든 리소스

      <http-method> (0개 이상)

      웹 리소스에 적용되는 HTTP 메소드를 나타낸다.

      • GET

      • POST

      • PUT

    • <auth-constraint> (선택)

      <security-constraint> 태그 내에 정의된 웹 리소스에 접근할 수 있는 Role을 설정한다. 하위 태그로는 0개 이상의 <role-name> 태그가 오는데 각각은 접근이 허락된 Role을 나타낸다.

      Role 이름이 설정되어 있지 않고 empty 태그 (<auth-constraint/>)로 설정되어 있다면, 아무도 해당 웹 리소스에 접근할 수 없다는 의미이다(이는 웹 리소스가 excluded된다는 것과 동일하다).

      <auth-constraint> 태그가 아예 생략되어 있다면 이는 웹 리소스가 unchecked된다는 것으로 Role에 상관없이 누구나 웹 리소스에 접근할 수 있다는 의미이다.

    • <user-data-constraint> (선택)

      웹 리소스에 맺어지는 커넥션에 대해 "transport guarantee"(전송 보장)할 것인가를 선언하는 태그다.

      하위 태그로 <transport-guarantee> 태그를 가지며, 웹 리소스로의 커넥션을 보장하는 레벨을 나타낸다.

      설정값 설명

      NONE

      커넥션을 보장하지 못한다는 의미이다.

      INTEGRAL

      메시지의 무결성(즉, 보내진 메시지는 변경되지 않은 원본이다)을 보장하는 커넥션이라는 의미이다.

      CONFIDENTIAL

      메시지가 도청되는 것을 방지하기 위해 암호화되어 보내진다는 의미이다.

  • 논리적 Role 선언

    <security-constraint> 태그 다음에 논리적 Role을 나타내는 <security-role> 태그가 온다. 각 태그는 <role-name> 태그를 가지고 있는데, 이미 DD에 언급되었던 논리적 Role 이름을 선언하는 부분이다.

다음은 web.xml의 보안 설정 예제이다.

웹 모듈 보안 설정 : <web.xml>
<?xml version="1.0"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee">
    <servlet>
        <servlet-name>HelloWorld</servlet-name>
        . . .
       <run-as> (1)
            <role-name>R1</role-name>
        </run-as>
       <security-role-ref> (2)
            <role-name>adminRef</role-name>
            <role-link>R1</role-link>
        </security-role-ref>
        . . .
    </servlet>
   <security-constraint> (3)
       <web-resource-collection>
            <web-resource-name>A</web-resource-name>
            <url-pattern>/a/*</url-pattern>
            <url-pattern>/b/*</url-pattern>
            <url-pattern>/a</url-pattern>
            <url-pattern>/b</url-pattern>
            <http-method>DELETE</http-method>
            <http-method>PUT</http-method>
        </web-resource-collection>
        <web-resource-collection>
            <web-resource-name>B</web-resource-name>
            <url-pattern>*.asp</url-pattern>
        </web-resource-collection>
        <auth-constraint/>
    </security-constraint>
   <security-constraint> (4)
        <web-resource-collection>
            <web-resource-name>C</web-resource-name>
            <url-pattern>/a/*</url-pattern>
            <url-pattern>/b/*</url-pattern>
            <http-method>GET</http-method>
        </web-resource-collection>
        <web-resource-collection>
            <web-resource-name>D</web-resource-name>
            <url-pattern>/b/*</url-pattern>
            <http-method>POST</http-method>
        </web-resource-collection>
        <auth-constraint>
            <role-name>R1</role-name>
        </auth-constraint>
        <user-data-constraint>
            <transport-guarantee>
                CONFIDENTIAL
            </transport-guarantee>
        </user-data-constraint>
    </security-constraint>
   <security-role> (5)
        <role-name>R1</role-name>
    </security-role>
    <security-role>
        <role-name>R2</role-name>
    </security-role>
    <security-role>
        <role-name>R3</role-name>
    </security-role>
</web-app>

위 예제의 각각의 부분이 의미하는 내용은 다음과 같다.

1 Run-as-Identity가 Role "R1"으로 설정되어 있는 것은 서블릿의 Security identity가 "R1"에 속한 Principal이어야 한다는 의미이다. 실제 Principal은 JEUS DD 파일에서 설정된다.
2 <security-role-ref> 태그는 실제 Role인 "R1"을 Role Reference인 "adminRef"로 매핑해 놓았는데, 실제 서블릿 소스 내에서는 Role대신 Role Reference인 "adminRef"를 사용한다.
3 첫 번째 Security constraint 설정은 "/a", "/b", "/a/*", "/b/*" URL 패턴을 가지고 있으면서 HTTP 메소드가 DELETE, PUT인 URL과 "*.asp"로 끝나는 URL은 누구도 접근할 수 없다는 것을 말하고 있다.

<auth-constraint/>로 설정되어 있기 때문이다.

4 두 번째 Security constraint 설정은 "/a/*", "/b/*" 패턴을 가지고 있으면서 GET 방식인 URL과 /b/* 패턴을 가지고 있으면서, POST 방식인 URL은 오직 "R1" Role에 포함된 Principal만 접근할 수 있다는 것을 말하고 있다. 그리고 해당 커넥션은 CONFIDENTIAL을 보장한다.
5 "R1", "R2", "R3" 3개의 논리적 Role을 선언하고 있다.

웹 리소스(URL 패턴 + HTTP 메소드)가 web.xml에 별도로 설정되어 있지 않으면, 해당 리소스는 Role에 상관없이 누구나 접근할 수 있다는 의미이다. 이는 Jakarta EE에서 웹 애플리케이션 접근에 대한 기본값이다.

web.xml에 나타나는 모든 태그들에 대한 자세한 정보는 서블릿 스펙을 참고한다. 또한 JEUS에서 서블릿을 deploy하는 것에 대한 추가적인 정보는 JEUS Web Engine 안내서를 참고한다.

3.2. jeus-web-dd.xml 설정

웹 모듈에 대한 JEUS DD 파일인 jeus-web-dd.xml에서 보안을 설정하는 방법에 대해 설명한다.

  • Principal-to-Role 매핑 정의

    jeus-web-dd.xml에서 Principal-to-Role 매핑을 정의하기 위해 <jeus-web-dd><role-mapping> 태그를 사용한다.

    다음은 <role-mapping>의 하위 태그들이다.

    • <role-permission> (0개 이상)

      Role에 대한 Permission(보통 Principal-to-Role 매핑)을 다음의 하위 태그에 설정한다.

      태그 설명

      <principal> (0개 이상)

      Role에 매핑되는 Principal 이름이다.

      <role> (1개, 필수)

      논리적 Role 이름이다. Role 이름은 Role Permission을 구현하는 Java 클래스 생성자에 첫 번째 파라미터로 전달되고, web.xml에 주어진 논리적 Role 이름과 일치해야 한다.

      <actions> (선택)

      Role Permission에 대한 추가적인 데이터를 전달한다. 설정되어 있다면 Role Permission을 구현하는 Java 클래스 생성자의 두 번째 파라미터로 전달된다.

      <classname> (선택)

      Role Permission을 구현하는 Java 클래스명이다.

      이 클래스는 java.security.Permission의 구현 클래스로 최소한 하나의 파라미터(String rolename)를 넘겨받는 public 생성자를 가지고 있어야 한다.

      생략되면 기본값으로 “jeus.security.resource.RolePermission” 클래스가 사용된다.

      <excluded> (선택)

      empty 태그로 설정되어 있으면 Role은 excluded된 것으로 취급한다. 즉, 어떤 Principal도 해당 Role을 부여받을 수 없다.

      <principal>, <unchecked> 태그보다 우선순위가 높다.

      <unchecked> (선택)

      empty 태그로 설정되어 있으면 Role은 unchecked된 것으로 취급한다. 즉, Principal에 상관 없이 누구나 Role을 부여받을 수 있다.

      <principal> 태그보다 우선순위가 높다.

  • 서블릿에서 <run-as-principal> 설정

    서블릿에서 <run-as-principal>을 설정하기 위해 <servlet> 태그를 선언하고 <run-as><principal-name> 태그를 추가한다. <principal-name> 태그 값은 web.xml에서 <run-as><role-name>에 선언된 Role에 속하는 Principal이어야 한다.

현재로는 web.xml에서 언급되어 있지 않는 서블릿 URL을 어떻게 다룰지 정의하는 태그가 jeus-web-dd.xml에 없다. 서블릿 스펙에서는 모든 정의되지 않은 URL을 항상 Unchecked로 취급한다. 즉, 누구나 접근할 수 있다.

다음은 jeus-web-dd.xml의 보안 설정 예제이다.

웹 모듈 보안 설정 : <jeus-web-dd.xml>
<?xml version="1.0"?>
<jeus-web-dd xmlns=“http://www.tmaxsoft.com/xml/ns/jeus”>
        <context-path>/tutorial</context-path>
        <docbase>Tutorial</docbase>
        . . .
        <role-mapping>
           <role-permission> (1)
                <principal>user1</principal>
                <principal>user2</principal>
                <principal>customerGroup</principal>
                <role>R1</role>
            </role-permission>
            <role-permission> (2)
                <role>R2</role>
                </excluded>
            </role-permission>
           <role-permission> (3)
                <role>R3</role>
                </unchecked>
            </role-permission>
           <role-permission> (4)
                <principal>tellerGroup</principal>
                <role>R4</role>
                <actions>09:00-17:00</actions>
                <classname>
                    jeus.security.resource.TimeConstrainedRolePermission
                </classname>
            </role-permission>
        </role-mapping>
     <servlet> (5)
           <servlet-name>HelloWorld</servlet-name>
        <run-as-identity>
           <principal-name>user1</principal-name>
        </run-as-identity>
        . . .
</servlet>
        . . .
</jeus-web-dd>

위 예제의 각 부분에 대한 의미는 다음과 같다.

1 "user1", "user2", "customerGroup" Principal은 "R1" Role에 속한다.
2 "R2" Role은 Excluded되어 있다. 즉, 아무도 "R2" Role을 부여받을 수 없다.
3 "R3" Role은 Unchecked되어 있다. 즉, 누구나 "R3" Role을 부여받을 수 있다.
4 "tellerGroup" Principal은 오전 9시부터 오후 5시까지 Role "R4"를 부여받는다. jeus.security.resource.TimeConstrainedRolePermission 클래스의 implies() 메소드에서 구현된다.
5 run-as-principal로 "user1"이 사용되었다. 즉, 서블릿에서 EJB를 호출할 때 "user1"이 security identity로 넘겨진다. Deployer는 "user1"이 web.xml에 정의된 "R1" Role에 속하는지 반드시 확인해야 한다.

4. Jakarta EE 애플리케이션 보안 설정

본 절에서는 Jakarta EE 애플리케이션(EAR 파일)의 보안을 설정하는 방법을 설명한다.

기본적인 설정 방법은 다음과 같다.

4.1. application.xml 설정

Jakarta EE 애플리케이션은 .ear 확장자를 가진 Archive 파일이다. EAR Archive는 EJB 모듈, 웹 모듈, Connector 모듈 그리고 모듈에서 참조하고 있는 클래스들로 구성되어 있다. META-INF 디렉터리는 application.xml 설정 파일을 포함하고 있는데, 전체 애플리케이션에 대한 여러 가지 정보를 제공한다.

본 절에서는 application.xml에서 보안과 관련된 부분을 설명한다.

기본적으로 application.xml에는 보안과 관련된 설정은 논리적 Role을 설정하는 단 한 가지 밖에 없다. Role 선언은 EAR 파일 내에 있는 모든 EJB 모듈과 웹 모듈에 공통으로 적용되며 애플리케이션 범위(scope)를 가진다.

Jakarta EE 애플리케이션 보안 설정 : <application.xml>
<?xml version="1.0" encoding="UTF-8"?>
<application version="1.4" . . .>
    <description>Application description</description>
    <display-name>myApp</display-name>
    <module>
        <web>
            <web-uri>myWebApp.war</web-uri>
            <context-root>myWebApp</context-root>
        </web>
    </module>
    <module>
        <ejb>myEjbApp.jar</ejb>
    </module>
   <security-role> (1)
        <role-name>Administrator</role-name>
    </security-role>
   <security-role> (2)
        <role-name>Customer</role-name>
    </security-role>
</application>

위의 예제에서는 2가지 Role이 선언되었다.

1 "Administrator"
2 "Customer"

두 가지 Role은 Role-to-Resource 매핑을 정의하기 위해 EJB 모듈과 웹 모듈의 DD 파일에서 사용된다. EJB 모듈과 웹 모듈 보안에 대해서는 EJB 모듈 보안 설정웹 모듈 보안 설정에서 이미 설명되었다.

애플리케이션을 JEUS 서버에 deploy하기 전에 논리적 Role이 실제 Principal에 매핑되었는지 확인해야 한다. 이 매핑은 각각의 경우에 따라 아래 파일에 매핑된다.

  • 애플리케이션의 경우 : jeus-application-dd.xml

  • EJB 모듈의 경우 : jeus-ejb-dd.xml (Principal-to-Role 설정은 jeus-ejb-dd.xml 설정을 참고)

  • 웹 모듈의 경우 : jeus-web-dd.xml (Principal-to-Role 설정은 jeus-web-dd.xml 설정을 참고)

애플리케이션 전체에서 Role과 Principal-to-Role 매핑을 공유하기 때문에 Jakarta EE 애플리케이션에 포함되어 있는 모든 모듈을 잘 알고 있어야 한다. 가령, application.xml에 "Administrator"라는 Role을 설정해 놓고, jeus-application-dd.xml에서 "user2"라는 Principal을 할당했다고 가정한다. 이 Role 매핑은 애플리케이션에 포함된 모든 EJB 모듈과 웹 모듈에서 적용된다.

비슷하게 Role과 Principal-to-Role 매핑을 특정 EJB의 jeus-ejb-dd.xml에만 정의했다고 해도 설정된 Role과 Principal-to-Role 매핑은 .ear에 포함된 모든 모듈에서 여전히 공유될 수 있다.

Jakarta EE 애플리케이션에서 모든 Principal-to-Role 매핑은 그것이 jeus-application-dd.xml에 설정되어 있든 특정 jeus-ejb-dd.xml이나 jeus-web-dd.xml에 설정되어 있든 상관없이 애플리케이션 범위(scope)를 가진다는 점을 주의한다.

4.2. jeus-application-dd.xml 설정

애플리케이션 레벨에서 Principal-to-Role 매핑은 jeus-application-dd.xml에 설정한다.

Principal-to-Role 매핑을 정의하기 위해 jeus-application-dd.xml의 <application> 태그 아래에 다음 태그들을 추가한다.

  • <role-permission> (선택)

    <role-permission> 태그는 Principal-to-Role 매핑을 정의하며, 선택적으로 Excluded, Unchecked Role을 설정할 수 있다. 이 태그는 jeus-web-dd.xml, jeus-ejb-dd.xml, policies.xml과 완전히 동일하게 동작한다.

    다음의 하위 태그를 가진다.

    태그 설명

    <principal> (0개 이상)

    Role에 매핑되는 Principal 이름이다.

    <role> (1개, 필수)

    Role 이름을 나타낸다. 이는 Role Permission을 구현하는 Java 클래스 생성자에 첫 번째 파라미터로 넘겨진다.

    Role 이름은 application.xml에 선언된 논리적 Role 이름과 일치해야 한다.

    <actions> (선택)

    Role Permission에 부가적인 정보를 제공한다. 설정되어 있다면 Role Permission을 구현하는 Java 클래스 생성자에 두 번째 파라미터로 넘겨진다.

    <classname> (선택)

    Role Permission을 구현하고 있는 Java 클래스명이다. 이 클래스는 java.security.Permission 클래스의 서브 클래스로 최소한 하나의 파라미터(String rolename)를 넘겨받는 public 생성자가 있어야 한다.

    생략되어 있다면 기본값으로 jeus.security.resource.RolePermission이 사용된다.

    <excluded> (선택)

    empty 태그로 설정되어 있으면 Role은 Excluded로 취급된다. 즉, 아무도 해당 Role을 부여받을 수 없다.

    <principal>이나 <unchecked> 태그보다 우선순위가 높다.

    <unchecked> (선택)

    empty 태그로 설정되어 있으면, Role이 Unchecked로 취급된다. 즉, 누구나 해당 Role을 부여받을 수 있다.

    <principal> 태그보다 우선순위가 높다.

<application> 태그 아래에 해당 애플리케이션이 deploy되는 보안 도메인을 설정해 놓아야 한다. 기본값으로 'SYSTEM_DOMAIN’이 사용되지만, 특정 애플리케이션이 특별한 보안 서비스를 필요로 한다면 해당 보안 서비스를 포함하고 있는 새로운 도메인을 생성해서 deploy해야 한다.

jeusadmin의 deploy 명령어에서 보안 도메인 이름을 설정할 수 있다.

Jakarta EE 애플리케이션 보안 설정 : <jeus-application-dd.xml>
    <application>
        . . .
       <role-permission> (1)
           <principal>user2</principal>
           <role>Administrator</role>
        </role-permission>
       <role-permission> (2)
           <role>Customer</role>
           </unchecked>
        </role-permission>
        . . .
    </application>

위의 예제에서, Jakarta EE 애플리케이션 보안을 다음과 같이 설정했다.

1 "user2"라는 Principal은 "Administrator" Role에 매핑되어 있으며, 디폴트 RolePermission을 사용한다.
2 모든 Principal에 "Customer" Role을 부여한다(Role이 unchecked되었기 때문이다).
  1. 보안 도메인을 설정하는 방법은 보안 도메인 설정를 참고한다.

  2. Custom Permission을 개발하고 설정하는 방법은 보안 시스템 정책 설정을 참고한다.

  3. JEUS에 Jakarta EE 애플리케이션을 deploy하는 방법은 JEUS Server 안내서를 참고한다.

5. 예제

본 절에서는 위에서 설명한 설정을 기반으로 작성한 예제에 대해 간략하게 설명한다.

다음 화면은 최초로 접속할 때의 로그인 화면이다. 해당 URL에 checked permission이 설정된 경우에만 보이며, Unchecked permission일 때는 이 화면이 생략되고 바로 페이지가 표시된다. Excluded permission일 때는 Authorization이 실패하고 에러 화면이 나타난다.

figure sample login
로그인 화면

인증에 실패하였거나 권한이 없는 계정으로 로그인했을 경우 에러 페이지가 나타난다. 권한이 있는 계정으로 로그인에 성공하면 다음과 같은 화면이 나타난다.

figure sample mainpage
메인 화면

이 예제는 메인 페이지에서 3개의 서블릿으로 링크가 걸려 있으며, 3개의 EJB 메소드를 호출하게 된다. 로그인한 계정과 설정 파일에 따라 접근할 수 있는지 여부에는 차이가 있으므로 여러 가지 설정을 하고 여러 계정으로 로그인해 보면서 직접 확인해본다.