제6장 JACC Provider 사용

내용 목차

6.1. 개요
6.2. JACC 규약
6.2.1. Provider 설정 규약
6.2.2. Policy 설정 규약
6.2.3. Policy 결정 및 집행 규약
6.3. JACC Provider 개발
6.3.1. JACC Provider 구현
6.3.2. JACC Provider 패키징
6.3.3. Default JACC Provider
6.4. JEUS 보안 시스템과 JACC Provider 통합

본 장에서는 JACC의 목적을 설명하고 Custom JACC Provider를 구현하여 JEUS 보안 시스템에서 사용하는 방법에 대해 간단히 설명한다.

JACC(Java Authorization Contract for Containers)는 J2EE 1.4에서 처음으로 소개되었고, 현재 버전은 Jakarta™ Authorization 1.5이다.

Jakarta™ Authorization 배경에는 다음의 2가지 기본 목적이 있다.

  • Jakarta™ Enterprise Beans와 서블릿의 권한을 체크하는 경우 표준 SPI를 제공한다.

  • 기존 Java SE 보안 모델과 Jakarta™ EE 보안 모델 간의 조화를 추구한다.

Jakarta™ Authorization 는 Jakarta™ Enterprise Beans와 서블릿의 접근 권한을 정의하고 처리하는 표준적인 방법을 제시하고 있다. 따라서, JACC Provider를 작성하면 Jakarta™ Authorization 호환 Jakarta™ EE 서버에서 사용할 수 있다.

전체 Jakarta™ Authorization 스펙은 다음과 같이 3개의 세부 규약으로 구성되어 있다.

  • Provider 설정 규약

  • Policy 설정 규약

  • Policy 결정 및 집행 규약

Policy 설정 규약은 Jakarta™ EE DD 파일(ejb-jar.xml, web.xml)에 설정된 보안 제약(security constraints)을 javax.security.jacc 패키지에 정의된 java.security.Permission set으로 매핑하는 방법과 이러한 Permission을 JACC Provider(Custom java.security.Policy)에 추가하는 방법을 기술하고 있다.

이는 결국 Jakarta™ Enterprise Beans와 서블릿에서 JACC Provider가 권한 부여와 관련된 결정을 내릴 수 있게 만든다.

참고

Policy 설정 규약은 Principal-to-Role 매핑에 대한 언급이 없다. 오로지 Jakarta™ EE DD 파일에 근거하여 Role-to-Resource 매핑을 어떻게 할지만 정의하고 있다. 따라서 Princiapl-to-Role 매핑은 JACC Provider를 공급하는 업체에 따라 각각 다른 방법으로 정의되어 있다.

Policy 설정 과정을 간단하게 설명하면 다음과 같이 구성되어 있다.

  1. 시스템 속성(-D 속성으로 설정) javax.security.jacc.PolicyConfigurationFactory.provider에 Custom javax.security.jacc.PolicyConfigurationFactory 클래스명을 설정한다.

    JACC Provider는 Custom javax.security.jacc.PolicyConfigurationFactory를 포함하고 있다.

  2. Jakarta™ EE 서버는 이 속성값을 읽어서 해당 클래스의 인스턴스(PCF)를 생성한다.

  3. 서블릿과 Jakarta™ Enterprise Beans 모듈을 deploy한다.

  4. Deployment 코드는 web.xml과 ejb-jar.xml DD 파일을 읽어들여 설정된 security constraints 항목을 JACC Permission 인스턴스들로 전환한다. 이 Permission 클래스는 javax.security.jacc 패키지에 포함되어 있다. 이때 각 Permission 인스턴스는 서블릿과 Jakarta™ Enterprise Beans에 설정되어 있는 Role-to-Resource 매핑을 나타낸다.

  5. Deployment 코드는 PCF.getPolicyConfiguration() 메소드를 호출하여 javax.security.jacc.PolicyConfiguration 타입의 인스턴스(PC)를 리턴받는다.

  6. Deployment 코드는 4번 과정에서 생성된 Role-to-Resource Permission들을 PC의 다양한 메소드를 사용하여 PC에 추가한다.

  7. 모든 Permission을 PC에 추가하고 나면, PC의 commit() 메소드를 호출한다.

서블릿과 Jakarta™ Enterprise Beans 모듈이 undeploy될 때 PC.delete() 메소드가 호출된다. 이는 해당 서블릿 모듈과 Jakarta™ Enterprise Beans 모듈에 대한 Permission을 제거한다.

참고

Policy 설정 과정에 대한 자세한 설명은 JACC 스펙을 참고한다.

Policy 결정 및 집행 규약은 이름에서도 알수 있듯이 Jakarta™ Enterprise Beans와 서블릿에서 접근 권한과 관련된 결정을 어떻게 내리고 집행할 것인지 기술하고 있다. 이는 앞서 설명한 2가지 세부 규약이 모두 충족된 이후에 적용된다.

Policy 결정 및 집행은 다음과 같은 과정으로 진행된다. 본 절에서는 서블릿을 예로 들어 설명하지만, Jakarta™ Enterprise Beans의 경우에도 아래의 설명과 동일하다.

  1. 해당 서블릿 페이지에 대한 요청이 들어온다.

  2. 서블릿 컨테이너는 javax.security.jacc.PolicyContext 클래스를 사용하여 JACC Context 정보를 설정한다.

  3. 서블릿 컨테이너는 2가지 JACC Web Permission(javax.security.jacc 패키지에 정의되어 있다)을 생성한다. 이 Permission 인스턴스는 현재 요청한 서블릿에 설정된 Permission을 나타낸다.

  4. 서블릿 컨테이너는 서블릿 요청자가 위의 2가지 Permission을 가졌는지 알아보기 위해 JACC Provider에 Query를 던진다. Query를 해석하는 데는 여러 가지 방법이 있다.

    예를 들어 Policy.implies() 메소드로 확인할 수 있다. 이때 파라미터로 요청자의 Principal로 초기화된 java.security.ProtectionDomain에서 체크하는 모든 Permission(들)이 사용된다.

  5. JACC Provider는 2번 과정에 설정된 context 정보, 3번에서 생성한 Permission 인스턴스, 요청자의 Principal(s), Principal-to-Role 매핑, Role-to-Resource 매핑 등을 모두 사용하여, 현재 요청자가 서블릿 페이지에 접근 권한을 가졌는지를 판단한다.

  6. 권한 체크 결과가 양수값이라면 서블릿 컨테이너는 요청자가 서블릿 페이지에 접근하도록 허락한다. 그렇지 않다면, 권한 체크에 실패했다는 에러 페이지가 나타난다.

참고

Policy 결정 및 집행 규약에 대한 자세한 설명은 JACC 스펙을 참고한다.

본 절에서는 Custom JACC Provider를 개발하는 방법과 JACC Provider 개발과 관련된 몇 가지 지침을 설명한다.

다음은 Custom JACC Provider를 구현하기 위해 필요한 클래스들과 그들 간의 관계를 단순하게 표현한 클래스 다이어그램이다. 이 다이어그램에서는 클래스 이름을 "MYJACC"로 시작했지만, 어떤 이름이 와도 상관없다.


JACC Provider를 구현할 때 필요한 클래스는 다음과 같다.

참고

본 절에서는 각 클래스 구현 방법에 대해 대략적으로 설명했다. 구현하는 방법에 대한 자세한 설명은 JACC 스펙의 Policy 결정 및 집행 규약과 각 클래스에 대한 Jakarta™ EE Javadoc을 확인한다.

본 절에서는 JEUS 보안 시스템과 디폴트 JACC Provider를 통합하는 방법에 대해 설명한다.

JEUS 보안 시스템과 JACC Provider를 통합하기 위한 과정은 다음과 같다.

  1. Principal-to-Role 매퍼를 구현한다.

    JACC 인터페이스는 Principal-to-Role 매핑에 대해 어떤 것도 언급하고 있지 않고 단지 Role-to-Resource 매핑만 정의하고 있다. Principal-to-Role 매핑을 위해 JEUS 만의 별도의 인터페이스가 필요하다. 이를 위해 JEUS는 jeus.security.impl.aznrep.JACCPrincipalRoleMapper라는 인터페이스를 제공한다. 이 인터페이스는 구현해야 할 단 하나의 메소드인 addPrincipalRoleMapping(PermissionMap map, String policyId)을 포함하고 있다. 이 메소드는 Principal-to-Role 매핑을 policyId로 대표되는 PolicyConfiguration에 추가한다.

    주의

    Principal-to-Role 매핑은 Jakarta™ EE에서 애플리케이션 범위를 가진다는 점에 주의한다. 동일 Jakarta™ EE 애플리케이션에 속한 모든 Principal-to-Role 매핑은 하나의 Map에 병합되기 때문이다. PermissionMap 클래스와 PermissionMap 인스턴스를 서로 병합하는데 사용되는 add() 메소드에 대한 자세한 정보는 PermissionMap 클래스에 대한 API 문서를 참고한다.

    JACCPrincipalRoleMapper 인터페이스를 구현한 클래스는 파라미터가 없는 public 생성자를 제공해야 한다. 그리고 반드시 JACC Provider JAR 내에 추가되어야 한다. JACCPrincipalRoleMapper 인터페이스에 대한 자세한 정보는 참고 자료와 Javadoc을 확인한다.

    JACCPrincipalRoleMapper가 Pricinpal-to-Role 매핑을 생성하는 과정은 다음과 같다.

    1. jeus.security.jacc.principalRoleMapper 시스템 속성으로 jeus.security.jacc.principalRoleMapper를 구현한 클래스명을 설정한다.

    2. 설정이 완료되면 jeus.security.impl.aznrep.JACCAuthorizationRepositoryService를 구현한 클래스가 이 속성값을 읽어 Class.forName(mapperClassname).newInstance() 메소드로 해당 인스턴스를 생성한다.

    3. 생성된 인스턴스의 addPrincipalRoleMapping() 메소드를 호출하여 JEUS DD 파일에 명시된 Principal-to-Role 매핑을 생성해서 추가한다.

  2. 보안 설정 파일을 설정한다.

    JEUS 보안 시스템은 2개의 어댑터 클래스를 사용하여 JEUS native authorization API와 JACC authorization API를 연결한다.

    2개의 어댑터 클래스와 각각의 역할은 다음과 같다.

    • jeus.security.impl.azn.JACCAuthorizationService

      컨테이너에서 Policy 결정 및 집행 규약을 구현하는 부분으로 권한을 체크하기 위해 java.security.Policy.getPolicy().implies() 메소드를 호출한다.

    • jeus.security.impl.aznrep.JACCAuthorizationRepositoryService

      Policy 설정 규약을 구현한 부분으로 컨테이너가 생성한 jeus.security.base.Policy 인스턴스를 JACC Provider의 구성 요소인 PolicyConfiguration 인스턴스에 추가하는 역할을 한다.

    JACC를 작동시키기 위해서는 이 2가지 보안 서비스가 domain.xml의 도메인 서비스 정의에 설정되어 있어야 한다.


  3. 시스템 Path에 JACC Provider JAR Path를 추가한다.

    시스템 Path에 JACC Provider JAR 파일을 추가하기 위해 다음의 디렉터리에 JAR 파일을 위치시킨다.

    JEUS_HOME/lib/system

  4. Java 시스템 속성을 설정한다.

    JACC 규약과 JEUS는 애플리케이션 서버가 JACC Provider를 인식하도록 다음 3가지 Java 시스템 속성을 규정하고 있다.

    • javax.security.jacc.policy.provider

      JACC Provider를 나타내며, java.security.Policy를 구현한 클래스명이다.

    • javax.security.jacc.PolicyConfigurationFactory.provider

      PolicyConfiguration 인스턴스를 생성하고 로딩하는 PolicyConfigurationFactory를 구현한 클래스명이다.

    • jeus.security.jacc.principalRoleMapper

      jeus.security.impl.aznrep.JACCPrincipalRoleMapper 인터페이스를 구현한 클래스명으로 JEUS DD 파일로부터 Principal-to-Role 매핑을 생성한다.

    위의 3가지 시스템 속성은 모든 서버에 대해서 domain.xml에 <jvm-option>으로 설정되어야 한다.


디폴트 JACC Provider 클래스

이전에 언급한 대로 디폴트 JACC provider 클래스명은 다음과 같다.

구분클래스명
Policyjeus.security.impl.jacc.JACCPolicyWrapper
PolicyConfigurationFactoryjeus.security.impl.jacc.JACCPolicyConfigurationFactoryImpl
JACCPrincipalRoleMapperjeus.security.impl.jacc.JACCDefaultPrincipalRoleMapper

이 클래스들은 모두 다음의 위치에 패키징되어 있다.

JEUS_HOME/lib/system/jeus.jar