내용 목차
본 장에서는 JEUS에서 핵심적인 보안 시스템을 실제로 어떻게 설치하고 설정하는지를 설명한다. 설명한 서비스 이외의 서비스를 도메인에 설정하는 방법은 참고 자료를 참고한다.
본 절에서는 보안 시스템 설정과 관련된 기본적인 사항들을 간단하게 설명한다.
JEUS의 보안 시스템은 Security Installer를 통해 서버를 실행할 때 시작된다. Security Installer는 domain.xml에 정의된 정보를 바탕으로 보안 도메인을 만들고 보안 서비스를 시작하여 JEUS를 안전하게 보호한다. 디폴트 보안 시스템에서는 accounts.xml과 policies.xml에 정의된 사용자 계정과 보안 정책이 적용된다.
보안 도메인에 대해 다음의 2가지를 설정할 수 있다.
보안 도메인과 보안 서비스에 대한 정의
해당 도메인에 대한 계정 및 정책 설정
디폴트 보안 시스템의 설정 과정은 다음과 같다.
보안 도메인들을 설정한다.
각 보안 도메인별로 구성요소와 보안 서비스를 설정한다.
각 도메인에 대한 Subjects(인증 데이터)의 사용자 정보를 설정한다.
각 도메인에 대한 Policies(보안 정책 데이터)를 설정한다.
Subject와 Policy 이외의 추가 사항을 설정한다.
Java SE SecurityManager를 설정한다(선택적).
JACC Provider를 설정한다(선택적).
다음은 디폴트 보안 시스템의 디렉터리 구조이다. 각 디렉터리에는 보안 시스템에서 사용하는 설정 파일들이 나열되어 있다.
JEUS_HOME/domains/<domain name> |--config |--security |--security.key |--policy |--SYSTEM_DOMAIN |--accounts.xml |--policies.xml
다음은 각 디렉터리 및 파일에 대한 설명이다.
애플리케이션에 JEUS 시스템과 다른 보안정책을 적용하려면 별도의 보안 도메인 디렉터리를 생성하고 관련 설정을 적용한 뒤 사용해야 한다.
도메인 설정은 WebAdmin을 사용해서 방법과 설정이 저장되는 domain.xml을 직접 편집하는 방법이 있다. 사용자 계정 설정과 보안 정책 설정을 제외한 나머지 사항은 동적 변경이 불가능하다. 따라서 보안 도메인을 추가하거나, 보안 서비스 설정등을 수정했을 경우 서버를 재부팅해야 수정된 사항이 적용됨에 유의한다.
보안과 관련된 모든 설정은 JEUS 도메인에 속한 모든 서버에 동일하게 적용된다. 따라서 사용자 계정 설정과 보안 정책 설정을 제외하고는 동작하고 있는 모든 서버를 재부팅해야 보안 설정 적용이 가능하다.
보안 도메인 설정을 위해서는 Domain Admin Server(이하 DAS)가 기동 중이어야 하고 설정 적용을 위해선 DAS를 포함한 서버 재부팅이 필요하다. 본 절에서는 WebAdmin과 XML 편집을 통해 보안 도메인을 정의하는 방법에 대해 설명한다.
WebAdmin의 왼쪽 메뉴에서 [Security]를 선택하면 현재 구성된 보안 도메인에 대한 정보를 볼 수 있다. 구성된 보안 도메인 중 애플리케이션에서 사용할 도메인의 이름을 'Default Application Domain' 항목을 통해 지정할 수 있으며, 보안 도메인의 추가, 삭제도 가능하다.
'Connect Retries' 항목 설정으로 JEUS Security NetworkService의 connection retry count 값을 정의할 수도 있다.
XML을 직접 편집하려면 JEUS_HOME/domains/<domain name>/config/domain.xml 내의 다음 태그를 이용하여 설정한다.
도메인에 대한 XML 파일 설정 방법은 JEUS_HOME/lib/schemas/jeus 디렉터리 내의 jeus-domain.xsd와 jeus-security.xsd의 XML 스키마에 정의되어 있다. 상위 태그는 <security-manager>이며, 이 태그는 도메인 설정과 관련된 다음 하위 태그를 가진다. 하위 태그는 0개 이상씩 설정 가능하다.
[예 2.1] <<JEUS_HOME/domains/<domain name>/config/domain.xml>>
<security-manager> <security-domains> <default-application-domain>SYSTEM_DOMAIN</default-application-domain> <security-domain> <name>SYSTEM_DOMAIN</name> ... </security-domain> <security-domains> </security-manager>
다음은 설정 태그에 대한 설명이다.
태그 | 설명 |
---|---|
<connect-retries> | JEUS Security NetworkService에서 connection retry count 값을 정의한다. (기본값: 10) |
<default-application-domain> | J2EE 애플리케이션에서 사용할 기본 보안 도메인의 이름을 정의한다. (기본값: SYSTEM_DOMAIN) |
<security-domains> | JEUS에 등록할 보안 도메인들을 설정한다. <security-domains>에 대한 보안 설정 파일의 예제는“2.3. 보안 도메인 구성요소 설정”을 참고한다. |
본 절에서 설명은 디폴트로 제공되는 XML을 이용한 설정에 대해 설명한다.
사용자 계정 및 보안 정책 설정은 XML뿐만 아니라 데이터베이스에 사용자 계정 정보와 보안 정책 정보를 저장하여 사용하는 것도 가능하며, 이에 대한 자세한 내용은 “2.5.3. 데이터베이스 사용 설정”과 “2.6.3. 데이터베이스 사용 설정”을 참고한다.
다음은 사용자 계정 및 보안 정책을 설정하는 과정에 대한 설명이다.
새로운 보안 도메인을 설정하려면 JEUS_HOME/domains/<domain name>/config/security 아래에 새로운 디렉터리를 생성해야 한다. 디렉터리 이름은 생성하려는 보안 도메인 이름과 일치해야 한다. 일반적으로 보안 도메인 이름은 모두 대문자로 쓰고 "_DOMAIN"으로 끝맺는다. 예를 들면 "DEFAULT_APPLICATION_DOMAIN"으로 명명할 수 있다.
DEFAULT_APPLICATION_DOMAIN 도메인을 생성하기 위해 명령 프롬프트에서 다음 명령어를 실행한다.
$ mkdir ${JEUS_HOME}/domains/domain1/config/security/DEFAULT_APPLICATION_DOMAIN
domain1은 실제 JEUS 도메인 이름으로 대체되어야 한다.
새로운 도메인 디렉터리를 생성한 후에 디렉터리 내에 몇 가지 설정 파일들을 생성한다.
가장 좋은 방법은 기존 도메인 디렉터리의 설정 파일들을 그대로 복사해서 필요에 따라 설정 파일을 변경하는 것이다(다음의 명령어는 모두 한 라인에 쓴다). 복사된 설정 파일에 대한 설명은 다음 절에서 설명한다.
$ cp ${JEUS_HOME}/domains/domain1/config/security/SYSTEM_DOMAIN/*.* ${JEUS_HOME}/domains/domain1/config/security/DEFAULT_APPLICATION_DOMAIN
JEUS_HOME/domains/<domain name>/security 아래에 SYSTEM_DOMAIN이 이미 디폴트로 존재한다. SYSTEM_DOMAIN은 JEUS 서버가 사용자 인증과 권한 체크를 위해 사용하는 도메인이다. 이 도메인은 JEUS를 기동하고, 종료하는 등의 Permission들과 JEUS 시스템 "administrator" 계정을 포함하고 있다.
새로 생성된 도메인은 JEUS를 다시 시작해야 적용된다.
보안 도메인 SYSTEM_DOMAIN은 domain.xml의 설정과는 관계없이 항상 포함된다. 기본적으로 JEUS_HOME/domains/<domain name>/config/security 경로 아래에 도메인과 같은 이름의 디렉터리를 생성하여 각 도메인별로 정의할 Repository에 대한 계정 정보(account.xsd)와 보안 정책 정보(policies.xsd)를 정의한다. 기타 도메인별 Security Service 등록은 domain.xml에 한다.
디폴트 보안 시스템에서 WebAdmin을 통해 보안 도메인을 추가한 경우에 위의 작업을 해 주지 않으면 SYSTEM_DOMAIN에 존재하는 계정 정보와 보안 정책 정보를 공유하게 된다. 보안 도메인에 따라 계정 정보와 보안 정책 정보를 분리하기 위해서는 위의 작업을 반드시 해야 한다.
본 절에서는 보안 서비스를 제외한 보안 도메인의 구성요소들을 설정하는 방법에 대해 설명한다.
WebAdmin의 왼쪽 메뉴에서 [Security]를 선택하면 Security Manager으로 이동한다. Security 설정화면에서 수정할 보안 도메인을 선택한다. 보안 도메인은 “2.2. 보안 도메인 정의”에서 설명한 대로 정의가 되어 있어야 하며, [LOCK & EDIT] 버튼을 클릭해서 설정변경 모드여야 한다.
Security Domains 목록에서 설정할 도메인 이름을 클릭하면 보안 설정화면으로 이동한다. 보안 설정화면은 다음의 탭으로 구성된다. 각 탭의 자세한 설명은 해당 절의 설명을 참고한다.
탭 | 설명 |
---|---|
[Cache Config] | 도메인에 적용된 보안 서비스에서 적용할 cache 정책값을 정의한다. |
[Key Store] | 도메인의 보안 서비스에 적용할 Keystore 파일의 정보를 정의한다. |
[Security Service] | 보안 서비스들을 설정하는 화면이다. |
[Custom Service] | JEUS Security Framework에서 제공하는 서비스 속성에 상관없이 JEUS Security API를 Implement한 서비스 속성에 별도의 보안 서비스 등록할 수 있다. 자세한 설명은 “2.4. 보안 서비스 설정”을 참고한다. |
[Accounts & Policies Management] | 사용자 계정 및 보안 정책을 설정한다. 자세한 설명은 “2.5. 보안 시스템 사용자 정보 설정”과 “2.6. 보안 시스템 정책 설정”을 참고한다. |
Cache Config 화면에서 도메인에 적용된 보안 서비스에서 적용할 Cache 정책값을 정의할 수 있다. 해당 Cache 값은 보안 서비스 중 하나인 Repository 서비스에 적용된다.
Keystore Config 화면에서 도메인의 보안 서비스에 적용할 Keystore 파일의 정보를 정의할 수 있다.
Keystore 파일에는 인증서 정보가 포함되어 있으며, 이를 이용한 사용자 인증이 가능하다. 하위의 설정값이 없는 경우 –Djeus.ssl.* 또는 –Djavax.net.ssl.* 설정되어 있는지 확인하고 해당 값이 없을 경우에는 기본값이 적용된다.
다음은 각 항목에 대한 설명이다.
항목 | 설명 |
---|---|
Keystore Path | Keystore 파일 경로를 설정한다. (${JEUS_HOME}/domains/<domain name>/config/security/keystore) |
Keystore Alias | Keystore 파일의 KeyEntry 타입의 인증서가 여러 개인 경우 명시적으로 alias 값으로 해당 서버 인증에 필요한 인증서를 가리키도록 한다. |
Keystore Password | Keystore 파일에 대한 패스워드를 설정한다(changeit). |
Keystore Keypassword | Keystore 파일에 대한 Keypassword를 설정한다. (기본값: <keystore-password> 값과 동일) |
Truststore Path | Truststore 파일 경로를 설정한다. (${JEUS_HOME}/domains/<domain name>/config/security/truststore) |
Truststore Password | Truststore 파일에 대한 패스워드를 설정한다(changeit). |
Custom Service 화면은 JEUS Security Framework에서 제공하는 서비스 속성에 상관없이 JEUS Security API를 Implement한 서비스 속성에 별도의 보안 서비스 등록할 수 있다. JEUS에서 제공하는 보안 서비스 종류와 Custom 보안 서비스의 개발과 관련된 사항은 “제5장 Custom 보안 서비스 개발”을 참고한다.
각 보안 도메인에서 로딩되는 보안 서비스는 domain.xml 내에 다음과 같이 설정되어 있다.
서비스에 대한 XML 파일 설정 방법은 JEUS_HOME/lib/schemas/jeus 디렉터리 내의 jeus-security.xsd의 XML 스키마에 정의되어 있다.
<security-domains> 태그의 하위에는 서비스 설정과 관련된 <security-domain>을 설정한다. <security-domain>은 1개 이상 설정이 가능하고 각 태그는 JEUS에서 사용하는 보안 도메인을 정의한다.
다음은 보안 설정 파일의 예제이다.
[예 2.2] 보안 시스템 서비스 설정 : <<domain.xml>>
<?xml version="1.0" encoding="UTF-8"?> <domain xmlns="http://www.tmaxsoft.com/xml/ns/jeus"> . . . <security-manager> <default-application-domain>DEFAULT_APPLICATION_DOMAIN</default-application-domain> <security-domains> <security-domain> <name>SYSTEM_DOMAIN</name> ..... </security-domain> <security-domain> <name>DEFAULT_APPLICATION_DOMAIN</name> </security-domain> </security-domains> </security-manager> . . . </domain>
<security-domain>에서 기타 다른 Service Provider에 대한 정보를 설정하지 않고 <name>에 대한 정보만 설정하면 해당 도메인에 기본으로 제공되는 보안 서비스들이 동작하게 된다.
다음은 <security-domain>의 하위 태그에 대한 설명이다.
보안 도메인에 대한 이름이다.
해당 도메인에 적용된 보안 Repository Service에서 적용할 Cache 정책값을 정의한다.
태그 | 설명 |
---|---|
<min> | Repository Service에 적용할 Cache entry 최소 size 값을 설정한다. |
<max> | Repository Service에 적용할 Cache entry 최대 size 값을 설정한다. |
<timeout> | Repository Service에 적용할 Cache entry의 timeout 값을 설정한다. |
해당 도메인의 보안 서비스에 적용할 Keystore 파일에 정보값을 정의한다.
하위의 설정값이 없는 경우 –Djeus.ssl.* 또는 –Djavax.net.ssl.* 설정이 되어 있는지 확인해 보고 해당 값이 없을 경우에는 기본값이 적용된다.
태그 | 설명 |
---|---|
<keystore-path> | Keystore 파일 경로를 설정한다. (${JEUS_HOME}/domains/<domain name>/config/security/keystore) |
<keystore-alias> | Keystore 파일의 KeyEntry 타입의 인증서가 여러 개인 경우 명시적으로 alias 값으로 해당 서버 인증에 필요한 인증서를 가리키도록 한다. |
<keystore-password> | Keystore 파일에 대한 패스워드를 설정한다(changeit). |
<keystore-keypassword> | Keystore 파일에 대한 Keypassword를 설정한다. (기본값: <keystore-password> 값과 동일) |
<truststore-path> | Truststore 파일 경로를 설정한다. (${JEUS_HOME}/domains/<domain name>/config/security/truststore) |
<truststore-password> | Truststore 파일에 대한 패스워드를 설정한다(changeit). |
JEUS 보안 시스템은 플러그(plug) 형태의 인증(Authentication) 서비스와 권한 확인(Authorization) 서비스를 지원한다. 본 절에서는 보안 서비스를 포함하여 보안 도메인의 구성요소들을 WebAdmin과 XML 편집을 통해 설정하는 방법에 대해 설명한다.
[Security Service] 메뉴를 선택하면 보안 서비스들을 설정하는 화면으로 이동한다. 보안과 관련된 작업을 하는 보안 서비스는 도메인별로 정의할 수 있다. 보안 서비스에 따라 해당 보안 도메인에서의 인증, 권한 확인 등에 대한 내부 동작이 달라진다.
메뉴 | 설명 |
---|---|
[Authentication] | 사용자 인증과 관련된 보안 서비스들을 수정한다. |
[Authorization] | 사용자 권한 확인과 관련된 보안 서비스들을 수정할 수 있다. |
[Identity Assertion] | 인증서로부터 사용자의 이름을 얻어오는 서비스를 설정할 수 있다. |
[Credential Mapping] | X509Certificate에 대한 Truststore 파일의 경로와 패스워드 경로를 지정할 수 있다. |
[Credential Verification] | 사용자의 Credential에 대해서 검사를 하는 서비스를 선택할 수 있다. |
[Audit] | JEUS Security Framework에서 발생하는 이벤트에 대한 정보를 수집하는 서비스에 대한 설정을 할 수 있다. |
[Subject Validation] | 사용자(Subject)에 대한 유효성 검사를 한다. |
Security Service의 [Authentication] 탭을 선택하면 사용자 인증과 관련된 보안 서비스들을 수정한다.
[Repository Service]
인증 Repository를 설정할 수 있다.
항목 | 설명 |
---|---|
Xml File Repository | 기본값으로는 XML을 사용하는 Xml File Repository가 선택되어 있다. Config File 영역에 파일 이름과 경로를 지정하여 사용한다. |
Database Repository | 체크박스를 선택해서 데이터베이스를 인증 Repository로 사용할 수도 있다. Resources에 정의된 'Datasource id'를 지정한다. |
Dbdriver Config | 데이터베이스 드라이버 설정한다. 데이터베이스 테이블 구성에 대한 사항은 “2.5.3. 데이터베이스 사용 설정”을 참고한다. |
Custom Repository | jeus.security.spi.AuthenticationRepositoryService를 구현한 Custom Service를 설정한다. |
[Jaas Login Config]
JAAS와 관련된 설정을 할 수 있다. 'Callback Handler Classname'에 Callback 핸들러의 Factory 클래스 이름을 정의할 수 있고, [ADD] 버튼을 통해 LoginModule을 추가할 수 있다. JAAS와 관련된 사항은 “제7장 JAAS 사용”을 참고한다.
[Custom Authetication Service]
사용자 인증을 수행하는 보안 서비스의 클래스 이름을 정의한다. jeus.security.spi.AuthenticationService를 구현한 클래스 이름을 설정한다. 기본값으로 JEUS에서 제공하는 'DefaultAuthenticationService'가 설정된다. 구현 클래스에 따라 프로퍼티를 입력한다.
Security Service의 [Authorization] 탭을 선택하면 사용자 권한 확인과 관련된 보안 서비스들을 수정할 수 있다.
[Basic]
인증 Repository와 마찬가지로 'Xml File Repository', 'Database Repository', 'Custom Repository' 중 하나를 선택할 수 있다.
항목 | 설명 |
---|---|
Jacc Service | JACC 서비스의 사용 여부를 설정한다. JACC를 사용하게 되면 JACC의 JEUS 구현체인 jeus.security.impl.azn.JACCAuthorizationService과 jeus.security.impl.aznrep.JACCAuthorizationRepositoryService이 권한 확인 및 Repository 서비스로 설정되어 동작한다. JACC와 관련된 사항은 “제6장 JACC Provider 사용”을 참고한다. |
Repository Service | 권한 확인 Repository를 설정할 수 있다. |
Database Repository | 데이터베이스 테이블 구성에 대한 사항은 “2.6.3. 데이터베이스 사용 설정”을 참고한다. |
Custom Repository | jeus.security.spi.AuthorizationRepositoryService를 구현한 Custom Service만 설정 가능하다. |
[Custom Authorization Service]
사용자 권한 확인을 수행하는 보안 서비스의 클래스 이름을 정의한다. jeus.security.spi.AuthorizationService를 구현한 클래스 이름을 설정한다. 기본값으로 JEUS에서 제공하는 DefaultAuthorizationService가 설정된다. 구현 클래스에 따라 프로퍼티를 설정할 수 있다.
Identity Assertion 화면에서 인증서로부터 사용자의 이름을 얻어오는 서비스를 설정할 수 있다. jeus.security.spi.IdentityAssertionService를 구현한 클래스 중 하나를 선택한다.
항목 | 설명 |
---|---|
Default Identity Assertion Service | 기본값으로 JEUS에서 제공하는 DefaultIdentityAssertionService에 대한 설정을 변경할 수 있다. 이 서비스는 X509Certificate를 기반으로 동작한다. 'Filename', 'Filepath' 설정을 통해 인증서와 사용자 이름의 맵핑 정보가 있는 XML 파일을 지정할 수 있다. |
Custome Identity Assertion Service | Custom Indentity Assertion 서비스를 정의한다. SPI 를 직접 구현한 클래스를 정의한다. |
Kerberos Identity Assertion | Kerberos 프로토콜을 이용한 Assertion에 대한 설정을 할 수 있다. 해당 설정을 하게 되면 JEUS에서 제공하는 LoginModule 구현체 중 jeus.security.impl.login.KerberosSharedStateLoginModule이 활성화된다. |
Credential Mapping 화면에서 X509Certificate에 대한 Truststore와 패스워드 경로를 지정할 수 있다.
기본값으로 jeus.security.spi.CredentialMappingService의 기본 구현체인 jeus.security.impl.credmap.JKSCertificateCredentialMappingService 서비스가 활성화된다.
Credential Verification 화면에서 사용자의 Credential에 대해서 검사하는 서비스를 선택할 수 있다.
기본값으로 'Password Verification'이 체크되어 사용자의 Password를 검사한다. 'Jeus Certificate Verification'을 선택하면 X509Certificate 검사가 가능하도록 할 수 있다.
Credential Verification 목록에서 [ADD] 버튼으로 jeus.security.spi.CredentialVerificationService를 구현한 클래스를 추가하여 사용할 수도 있다.
Audit 화면에서 JEUS Security framework에서 발생하는 이벤트에 대한 정보를 수집하는 서비스에 대한 설정을 할 수 있다.
'Filename', 'Filepath'에 로그를 남길 파일 이름과 경로를 설정할 수 있고, 'Audit Level'에 로그 레벨을 설정할 수 있다. 기본 구현체인 jeus.security.impl.auditlog.BasicAuditLogFileService이 사용된다.
Custom Audit Service 목록에서 [ADD] 버튼으로 jeus.security.spi.EventHandlingService를 구현한 클래스를 추가하여 사용할 수 있다.
Subject Validation 화면에서 사용자(Subject)에 대한 유효성 검사 여부를 설정할 수 있다. 'Default Subject Validation Service'를 선택하면 jeus.security.impl.expiration.SubjectExpirationValidationService 서비스가 활성화되어 ExpiryTime의 설정 유무로 사용자의 유효성 검사를 수행한다.
Custom Subject Validation Service 목록에서 [ADD] 버튼으로 jeus.security.spi.SubjectValidationService를 구현한 클래스를 추가하여 사용할 수 있다.
각 보안 도메인에서 로딩되는 보안 서비스는 domain.xml 내에 다음과 같이 설정되어 있다.
다음은 보안 설정 파일의 예제이다.
[예 2.3] 보안 시스템 서비스 설정 : <<domain.xml>>
<?xml version="1.0" encoding="UTF-8"?> <domain xmlns="http://www.tmaxsoft.com/xml/ns/jeus"> . . . <security-manager> <default-application-domain> DEFAULT_APPLICATION_DOMAIN </default-application-domain> <security-domains> <security-domain> <name>SYSTEM_DOMAIN</name> <authentication> <repository-service> <xml-file-repository> <config-file> <filename>accounts.xml</filename> <filepath> ${JEUS_HOME}/domains/domain1/config/security/ </filepath> </config-file> </xml-file-repository> </repository-service> </authentication> </security-domain> <security-domain> <name>DEFAULT_APPLICATION_DOMAIN</name> </security-domain> </security-domains> </security-manager> . . . </domain>
다음은 <security-domain>의 하위 태그에 대한 설명이다.
보안 도메인에 대한 이름이다.
해당 도메인에 적용할 인증 서비스를 정의한다.
<repository-service>
인증을 위한 사용자 정보 저장소 타입에 따른 서비스를 정의한다.
태그 | 설명 |
---|---|
<xml-file-repository> | 사용자 정보가 xml 파일에 정의된 경우 설정한다. |
<database-repository> | 사용자 정보가 데이터베이스에 정의된 경우 설정한다. |
<custom-repository> | jeus.security.spi.AuthenticationRepositoryService SPI를 상속하여 사용자 정보를 로딩하는 방식을 확장 Repository Service를 구현하여 적용하는 경우 설정한다. |
<jaas-login-config>
해당 도메인에 적용할 JAAS 서비스를 등록한다.
<callback-handler-class> : JAAS Callback Handler Factory 클래스 이름을 정의한다.
<login-module> : LoginModule 관련 내용을 설정한다.
태그 | 설명 |
---|---|
<login-module-classname> | LoginModule을 implements한 패키지를 포함한 클래스 이름을 정의한다. |
<control-flag> | 다음 4가지 속성들 중 하나를 정의하여 전반적으로 Authentication Stack에 대하여 조정하는 속성을 정의한다.
|
<option> (0개 이상) | LoginModule 초기화하는 경우 적용할 속성값을 정의한다. |
<custom-authentication-service>
jeus.security.spi.AuthenticationService SPI를 상속하여 기본으로 제공되는 인증 서비스를 확장해서 적용하고 싶은 경우 정의한다. 설정은 "Custom 보안 서비스" 설명을 참고한다.
해당 도메인에 적용할 권한 부여 서비스를 정의한다.
<repository-service>
권한 부여를 위한 정책 정보 저장소 타입에 따른 서비스를 정의한다.
태그 | 설명 |
---|---|
<xml-file-repository> | 정책 정보가 XML 파일에 정의된 경우 설정한다. |
<database-repository> | 정책 정보가 데이터베이스에 정의된 경우 설정한다. |
<custom-repository> | jeus.security.spi.AuthorizationRepositoryService SPI를 상속하여 정책 정보를 로딩하는 방식을 확장 Repository Service를 구현하여 적용하는 경우 설정한다. |
<custom-authorization-service>
jeus.security.spi.AuthorizationService SPI를 상속하여 기본으로 제공되는 인증 서비스를 확장 적용하고 싶은 경우 정의한다. 설정은 "Custom 보안 서비스" 설명을 참고한다.
<jacc-service>
JACC 1.4 기반의 권한 부여 서비스를 적용하는 경우 설정한다.
<identity-assertion> (0개 이상, 선택)
해당 도메인에 적용할 IdentityAssertion 서비스를 정의한다.
<default-identity-assertion-service>
JEUS Security Framework에서 제공하는 기본 Identity Assertion Service를 정의한다.
<x509-identity-assertion> : X509Certificate Token에 대한 Identity Assertion Service를 지원한다.
태그 | 설명 |
---|---|
<config-file> | X509Certificate Token에 대한 사용자 매핑을 하기 위해서 정보를 정의한 파일의 위치를 지정한다. (기본값: DOMAIN 폴더 하위에 위치한 user-cert-map.xml) |
<default-user-mapper> | X509Certificate Token 값에 attribute type(cert-attr-type) 값 또는 attribute type(attribute-type), attribute value에 대한 delimiter 값(attribute-value-delimiter)을 정의한다. |
<custom-identity-assertion-service>
jeus.security.spi.IdentityAssertionService SPI를 상속한 Identity Assertion Service를 확장 구현하여 정의한다. 설정은 "Custom 보안 서비스" 설명을 참고한다.
<credential-mapping> (0개 이상, 선택)
해당 도메인에 적용할 CredentailMapping Service를 정의한다.
<default-credential-mapping-service>
JEUS Security Framework에서 제공하는 기본 Credential Mapping Service를 지원한다.
<x509-credential-mapping> : X509Certificate에 대한 Credential Mapping Service를 지원한다.
태그 | 설명 |
---|---|
<truststore-path> | 현 도메인에 적용할 Truststore 파일에 대한 경로를 정의한다. |
<truststore-password> | 현 도메인에 적용된 Truststore파일 대한 패스워드를 정의한다. |
<custom-credential-mapping-service>
jeus.security.spi.CredentialMappingService SPI를 상속한 Credential Mapping Service를 확장 구현하여 정의한다. 설정은 "Custom 보안 서비스" 설명을 참고한다.
<credential-verification> (0개 이상, 선택)
해당 도메인에 적용할 Credential Verification Service를 정의한다.
<default-credential-verification-service>
JEUS Security Framework에서 제공하는 기본 Credential Verification Service 지원한다.
태그 | 설명 |
---|---|
<password-verification> | PasswordFactory 클래스에 대한 검증 서비스를 정의한다. |
<jeus-certificate-verification> | X509Certificate에 대한 검증 서비스를 정의한다. |
<custom-credential-verification-service>
jeus.security.spi.CredentialVerificationService SPI를 상속한 Credential Verification Service를 확장 구현하여 정의한다. 설정은 "Custom 보안 서비스" 설명을 참고한다.
JEUS Security Framework에서 발생하는 이벤트에 대한 정보를 수집할 수 있도록 해당 도메인에 적용할 EventHandlingService를 정의한다.
태그 | 설명 |
---|---|
<default-audit-service> | 해당 이벤트 정보를 기록하는 파일 경로와 이벤트 로그 레벨을 정의한다.
|
<custom-audit-service> | jeus.security.spi.EventHandlingServiceService SPI를 상속한 Audit Service를 확장 구현하여 정의한다. 설정은 "Custom 보안 서비스" 설명을 참고한다. |
다음은 Custom 보안 서비스를 설정하는 방법이다.
<classname> (필수)
Custom 보안 서비스를 구현한 Java 클래스명이다. 이 클래스는 파라미터가 없는 디폴트 public 생성자를 가지고 있어야 하며, jeus.security.spi 패키지의 SPI 클래스를 상속받거나, jeus.security.base.Service 클래스를 직접 상속해야 한다.
jeus.security.base.PropertyHolder 인터페이스(jeus.security.base.Service 클래스가 구현한다)를 통해 보안 서비스에 name-value 쌍으로 속성을 설정할 수 있다. 속성은 각 보안 서비스를 초기화하는 데 사용된다.
다음 2개의 하위 태그를 가진다.
태그 | 설명 |
---|---|
<name> | 속성명을 설정한다. |
<value> (선택) | 속성명에 해당하는 String 속성값을 설정한다. |
JEUS에서 제공하는 보안 서비스 종류와 Custom 보안 서비스의 개발과 관련된 사항은 “제5장 Custom 보안 서비스 개발”을 참고한다.
디폴트 보안 설정에서 사용자 데이터는 accounts.xml 파일에서 읽어 들인다.
다음은 파일 저장 경로이다.
JEUS_HOME/domains/<domain name>/config/security/<security domain name>/accounts.xml
여기서 <domain name>은 도메인의 이름이고, <security domain name>은 사용자가 관리될 보안 도메인의 이름을 나타낸다.
다음은 WebAdmin에서 사용자 정보를 설정하는 과정에 대한 설명이다.
[Accounts & Policies Management] > [accounts] 메뉴를 선택하여 사용자 정보에 대한 설정이 가능하다. 사용자 정보에 대한 사항은 동적 설정변경이 가능한 항목이다. [ADD], [DEL] 버튼을 클릭하여 사용자를 추가, 삭제할 수 있다.
Groups 목록에서 그룹을 추가, 삭제하는 것이 가능하며, 정의된 그룹에 사용자를 포함시키기 위해선 Users 항목에서 편집해야 한다. [ADD], [DEL] 버튼을 클릭하여 그룹을 추가, 삭제할 수 있다.
User 목록에서 [ADD] 버튼을 클릭하면 User 화면이 나타난다. 해당 화면에서는 JEUS에서 제공하는 기본 보안 시스템에 사용되는 accounts.xml 파일에 대한 수정만 제공된다.
'Password' 항목 오른쪽에 [입력] 버튼을 클릭하면 다음과 같이 사용자 패스워드를 설정할 수 있다. 암호화 알고리즘을 선택하여 사용자 패스워드를 타인이 알아볼 수 없도록 변경하여 저장한다. 암호화 알고리즘 선택과 패스워드 설정을 완료한 후 [확인] 버튼을 클릭한다.
패스워드 설정이 완료되면 다음 화면에서 사용자 패스워드가 암호화 알고리즘에 의해 변경된 것을 확인할 수 있다. 암호화에 대한 자세한 내용은 “2.5.4. 패스워드 보안 설정”을 참고한다.
'Group' 항목에서 사용자가 속할 Group을 지정한 뒤 [확인] 버튼을 클릭한다.
accounts.xml의 XML 스키마는 accounts.xsd이며, JEUS_HOME/lib/schemas/jeus 경로에 있다.
accounts.xml 파일에는 최상위 태그 <accounts> 하위에 <users> 및 <groups> 태그가 있으며 0개 이상의 <user> 및 <group> 태그가 포함되어 있다. 각각은 사용자와 그룹을 나타낸다.
[예 2.4] 보안 시스템 사용자 정보 설정 : <<accounts.xml>>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <accounts xmlns="http://www.tmaxsoft.com/xml/ns/jeus"> <users> <user> <name>user1</name> <password>{AES}mnG6ItxFO/WQlE2YzIZ7sA==</password> <group>group1</group> </user> <user> <name>user2</name> <password>{DES}7dJ0KDTGQNpSnQAPYBNnmA==</password> </user> <user> <name>user3</name> <password>{DES}7dJ0KDTGQNpSnQAPYBNnmA==</password> <group>nested_group</group> </user> <user> <name>user4</name> <password>{SEED}dl2EePMAcnxPYbIyknuZkA==</password> <group>nested_group</group> </user> </users> <groups> <group> <description>Group1</description> <name>group1</name> <subgroup>nested_group</subgroup> </group> <group> <description>For NestedGroup</description> <name>nested_group</name> </group> </groups> </accounts>
다음은 설정 태그에 대한 설명이다.
각 <user> 태그는 다음과 같은 하위 태그를 가지고 있다.
태그 | 설명 |
---|---|
<description> (선택) | <user>에 대한 설명이다. (문자열) |
<name> (필수) | <user>에 대한 이름을 나타낸다. (예: 사용자명, 사용자 ID) |
<password> (0개 이상, 선택) | <user>에 대한 패스워드를 나타낸다. <password>는 어떤 특정 알고리즘을 사용하여 인코딩된 값을 정의한다. <password> 태그에 적용된 알고리즘 또는 인코딩 방식을 ’{}’ 블록 사이에 기입하도록 한다. 인코딩 방식에 대한 자세한 내용은 “2.5.4. 패스워드 보안 설정”을 참고한다. |
<group> (0개 이상, 선택) | <user>가 포함된 그룹을 나타낸다. 한 사용자는 여러 그룹에 포함될 수 있으며, 다음의 <group> 태그에서 정의된 그룹을 지정해야 한다. |
본 절에서는 JEUS가 정의한 데이터베이스 테이블을 이용한 Authentication을 설정하는 방법에 대해서 설명한다.
다음 예제는 JEUS에 정의한 데이터소스를 이용할 때 설정하는 방법이다.
[예 2.5] 데이터베이스를 이용한 사용자 설정 : <<domain.xml>>
<?xml version="1.0" encoding="UTF-8"?> <domain xmlns="http://www.tmaxsoft.com/xml/ns/jeus"> . . . <security-manager> <seuciry-domains> <security-domain> <name>MY_DOMAIN</name> <authentication> <repository-service> <database-repository> <datasource-id>auth</datasource-id> </database-repository> </repository-service> </authentication> . . . </security-domain> </security-domains> </security-manager> . . . </domain>
위의 예제에서 <datasource-id>에는 Authentication에 사용할 domain.xml에 등록한 데이터소스의 ID를 명시해야 한다. 또 다른 방법으로 DriverManager를 이용해 JEUS에서 제공하는 JDBC를 이용하지 않고 직접 DB와 통신하면서 Authentication을 이용할 수 있는데, 위의 예제에서 <datasource-id> 태그 부분을 다음과 같이 변경한다.
다음 예제는 JEUS JDBC를 이용하지 않을 때 데이터베이스 Repository를 설정하는 방법이다.
[예 2.6] JEUS JDBC를 사용하지 않는 경우 설정 : <<domain.xml>>
<security-manager>
...
<repository-service>
<dbdriver-config>
<vendor>oracle</vendor>
<driver>oracle.jdbc.OracleDriver</driver>
<url>jdbc:oracle:thin:@127.0.0.1:1521:ORA9I</url>
<username>scott</username>
<password>{base64}dGlnZXI=</password>
</dbdriver-config>
</repository-service>
...
</security-manager>
이 방식을 이용할 경우 커넥션을 맺고 끊는 것이 매우 잦기 때문에 성능상 문제가 있을 가능성이 크므로 JEUS JDBC(<datasource-id>)를 이용하는 방법을 권장한다.
데이터베이스에서 사용되는 테이블은 다음과 같이 구성된다.
데이터베이스에 테이블이 존재하지 않을 경우
JEUS_HOME/templates/security/dbrealm.sql.template 파일을 이용해서 DB에 테이블을 생성하면
사용자명이 "jeus", 패스워드가 "jeus"인 사용자가 최초로 생성된다.
본 절에서는 패스워드 보안 설정에 대한 사항 중 암호화 알고리즘과 SecretKey 파일 관리방법에 대해서 설명한다.
사용자 설정을 할 때는 사용자의 패스워드를 지정해야 한다. 패스워드를 plain-text 형식으로 저장하는 것이 가능하나 암호화 알고리즘을 통해 암호화하여 타인이 알아볼 수 없도록 하는 것이 좋다.
안정성이 입증된 대칭키 알고리즘인 AES를 사용하는 것을 권장한다.
jeusadmin의 set-password 명령이나 WebAdmin을 통해 사용자별로 패스워드의 암호화가 가능하며, JEUS_HOME/bin/encryption을 이용하여 직접 암호화할 수도 있다.
직접 암호화한 경우는 패스워드를 설정할 때 다음의 형식으로 설정한다.
{알고리즘}암호화된문자열
대칭키 암호화 알고리즘의 키 값은 JEUS_HOME/domains/<domain name>/config/security/security.key 파일에 저장된다.
다음은 패스워드 암호화에서 지원하는 알고리즘에 대한 설명이다.
항목 | 설명 |
---|---|
AES/DES/DESede/SEED/Blowfish | 대칭키 암호화 알고리즘이다. |
base64 | 인코딩 알고리즘이다. Base64로 인코딩된 정보는 누구나 손쉽게 디코딩할 수 있어 보안상 안전하지 않다. |
SHA | Hash 알고리즘이다. 복호화가 불가능하다. |
암호화 툴(JEUS_HOME/bin에 위치)을 사용해서 패스워드를 암호화하는 경우 해당 암호화 파일에 적용되는 SecretKey 정보를 security.key 파일에 암호화 알고리즘별로 저장하여 관리한다. 마스터 패스워드를 입력받아 이 패스워드로 security.key 파일을 암호화하여 저장할 수 있다.
security.key 파일은 다음 경로에 위치한다. 도메인 환경을 구성하는 경우 해당 security.key 파일을 함께 다른 노드에 옮겨놓아야 한다.
JEUS_HOME/domains/<domain name>/config/security/security.key
JEUS에 등록하는 데이터베이스 패스워드를 암호화하였을 경우 클라이언트에서는 이를 decrypt하기 위해 Key가 필요하다. 이때 SecretKey 파일 경로를 시스템 프로퍼티를 이용해 설정할 수 있다.
또한, security.key 파일에 마스터 패스워드가 설정된 경우 마스터 패스워드도 시스템 프로퍼티를 이용해서 설정할 수 있다. key path를 지정하는 프로퍼티 이름은 jeus.security.keypath이며, 마스터 패스워드를 설정하려면 jeus.security.master를 이용하면 된다. 이 프로퍼티들은 JEUS를 기동할 때도 이용할 수 있다. 다만, 보안의 이유로 마스터 패스워드는 프롬프트(standard input)로 입력하는 것을 권장한다.
JEUS 스크립트를 통한 서버 부트나 jeusadmin으로 서버에 접속할 때는 사용자 정보가 필수로 입력되어야 한다. 이때 사용자 정보를 매번 입력하지 않고 로그인 정보를 캐시하여 사용할 수 있는 기능을 제공한다.
해당 정보는 USER_HOME/.jeusadmin/.jeuspasswd 파일에 Base64로 인코딩되어 저장된다. Base64 인코딩은 보안상 전혀 안전하지 않고, 파일에 사용자의 중요한 정보인 id/password가 저장되기 때문에 본 기능의 사용은 권장하지 않는다.
로그인 정보의 Cache는 한 번이라도 인증이 이루어진 다음 파일에 기록된다.
jeusadmin의 connect 명령을 수행할 때 사용자 정보와 함께 -cachelogin 옵션을 추가하면 해당 로그인 정보가 파일에 저장된다. JEUS 스크립트의 경우는 <domain name>:<server name>을 Key로 로그인 정보가 저장된다.
추후 JEUS 스크립트가 실행될 때 사용자 정보를 입력하지 않아도 도메인 이름과 서버 이름이 같은 로그인 정보가 존재하면 자동으로 사용자 정보를 채워준다. 캐시된 로그인 정보가 존재한다 하더라도 사용자가 직접 사용자 정보를 입력한 경우에는 캐시된 로그인 정보는 무시된다. jeusadmin의 경우는 접속하려는 서버의 <host>:<port>를 Key로 로그인 정보를 저장한다.
다음 예제는 저장된 로그인 정보를 보여준다.
[예 2.7] 저장된 로그인 정보 : <<.jeuspasswd>>
#Warning: We don't recommend to use this on Production Environment. localhost:9736 amV1czpqZXVz domain1:server1 amV1czpqZXVz
저장된 로그인 정보는 jeusadmin의 off-line 명령인 remove-login-cache 명령을 통해 삭제할 수 있다.
디폴트 보안을 설정하는 경우 정책 데이터(권한 부여 데이터)는 policies.xml 파일에서 읽어온다.
이 파일은 다음 경로에 위치한다.
JEUS_HOME/domains/<domain name>/config/security/<security domain name>/policies.xml
<domain name>은 도메인의 이름이고, <security domain name>은 정책이 적용될 보안 도메인의 이름을 나타낸다
[Accounts & Policies Management] 탭에서 [policies] 메뉴를 선택하면 보안 정책에 대한 사항을 설정할 수 있다. Role Permissions에서는 Principal과 Role에 대한 맵핑을 정의할 수 있다. 하나의 Role에 여러 개의 Principal이 맵핑될 수 있으며, 이렇게 맵핑된 Principal을 해당 Role에 대한 권한을 갖는다.
[ADD] 버튼을 클릭하여 Principal-to-Role 맵핑을 추가할 수 있다.
사용자 정보 설정과 마찬가지로 이 화면에서는 JEUS에서 제공하는 기본 보안 시스템에 사용되는 policies.xml 파일에 대한 수정만이 제공됨에 유의한다.
Role Permisions 목록에서 [ADD] 버튼을 클릭하면 Role Permision을 등록할 수 있다.
'Role'에 이름을 지정한 뒤 해당 Role의 권한을 부여할 Principal을 선택한다. 누구도 Role에 접근하지 못하게 하려면 'Excluded'에 체크하고, 누구나 Role에 접근할 수 있도록 하려면 'Unchecked'를 선택한다. 정보의 등록이 완료되면 [확인] 버튼을 클릭한다.
다음은 Resource Permissions를 등록하는 과정에 대한 설명이다.
Role에 실제 동작 권한인 Resource 권한을 주기 위해선 Resource Permissions에서 'default'를 선택한다. Context ID는 보안정책을 구분하는 ID로 사용되며, 'default'는 JEUS 기본 보안 시스템에서 사용하는 보안정책의 Context ID이다.
Context ID default에서 JEUS 시스템에 대한 Resource 권한 설정을 한다. Recource Permissions에서 [ADD] 버튼을 클릭하여 Role-to-Resource 맵핑을 추가할 수 있다.
Recource Permissions 화면에서 Resource의 이름과 Actions를 설정한 후 해당 Resource에 대한 권한을 부여할 Role을 선택하고 [ADD] 버튼을 클릭한다. Role Permission 설정과 마찬가지로 누구도 Resource에 접근하지 못하게 하려면 'Excluded'에 체크하고, 누구나 Resource에 접근할 수 있도록 하려면 'Unchecked'에 체크한다. JEUS의 Resource 권한 목록에 대해서는 “Appendix B. JEUS Server Permissions”를 참고한다.
policies.xml의 XML 스키마는 policies.xsd로 JEUS_HOME/lib/schemas/jeus 디렉터리 내에 있다.
policies.xml은 0개 이상의 <policy> 태그로 구성되어 있으며, 각 태그는 개별 정책(권한 부여 데이터)을 나타낸다.
[예 2.8] 보안 시스템 Policy 설정 : <<policies.xml>>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <policies xmlns="http://www.tmaxsoft.com/xml/ns/jeus"> <policy> <role-permissions> <role-permission> <principal>user1</principal> <role>administrator</role> </role-permission> <role-permission> <principal>user1</principal> <role>teller</role> <actions>9:00-17:00</actions> <classname> jeus.security.resource.TimeConstrainedRolePermission </classname> </role-permission> </role-permissions> <resource-permissions> <context-id>default</context-id> <resource-permission> <role>teller</role> <resource>bankdb</resource> <actions>select, update</actions> </resource-permission> <resource-permission> <role>administrator</role> <resource>jndi</resource> <actions>modify, delete</actions> </resource-permission> <resource-permission> <resource>jndi</resource> <actions>lookup</actions> <unchecked/> </resource-permission> <resource-permission> <role>administrator</role> <resource>jeus.*</resource> <actions>*</actions> </resource-permission> </resource-permissions> </policy> </policies>
다음은 설정 태그에 대한 설명이다.
Principal-to-Role 매핑들에 대한 정보를 제공한다. 하위 태그로 0개 이상의 <role-permission> 태그를 가지고 있다.
<role-permission> 태그는 다음의 태그로 구성되어 있다.
태그 | 설명 |
---|---|
<principal> (0개 이상) | 현재 <role-permission>을 소유하고 있는 Principal 이름이다. |
<role> (1개, 필수) | Role 이름을 나타낸다. |
<actions> (선택) | Role에 대한 액션을 나타낸다. |
<classname> (선택) | Role Permission으로 사용될 java.security.Permission을 구현한 Java 클래스명이다. 생략되면 jeus.security.resource.RolePermission이 디폴트로 사용된다. Custom Permission을 설정하고 구현하는 방법은 "Custom Permission 구현 및 설정"을 참고한다. |
<excluded> (선택) | 값이 없는 empty 태그( <xxx/> )이다. 설정되어 있으면 해당 Role Permission이 배제된다. 즉, Permission이 암시하는 Role에 아무도 접근할 수가 없다. |
<unchecked> (선택) | 값이 없는 empty 태그이다. 설정되어 있으면 Role Permission이 체크되지 않는다. 즉, Permission이 암시하는 Role에 누구나 접근할 수 있다. |
<resource-permissions> (0개 이상)
Role-to-Resource에 대한 정보는 다음의 태그로 구성되어 있다.
<context-id> (선택)
문자열로 Context ID를 나타낸다. Context는 권한 부여 체크가 일어나는 범위를 나타낸다. JEUS 시스템이 JEUS 리소스에 대해 사용하는 기본 Context ID는 "default"이다.
<resource-permission> (0개 이상)
다음의 항목으로 구성되어 있다.
태그 | 설명 |
---|---|
<role> (0개 이상) | 현재 Resource Permission을 소유하고 있는 Role 이름이다. |
<resource> (1개, 필수) | 리소스 이름을 나타낸다. |
<actions> (선택) | 리소스에 대한 액션을 나타낸다. |
<classname> (선택) | Resource Permission으로 나타내는 java.security.Permission을 구현한 클래스명이다. 생략하면 jeus.security.resource.ResourcePermission이 디폴트로 사용된다. Custom Permission을 생성하고 설정하는 방법은 "Custom Permission 구현 및 설정"을 참고한다. |
<excluded> (선택) | 값이 없는 empty 태그이다. 설정하면 해당 Resource Permission이 배제된다. 즉, Permission이 암시하는 리소스는 누구도 접근할 수 없다. |
<unchecked> (선택) | 값이 없는 empty 태그이다. 설정하면 해당 Resource Permission을 체크하지 않는다. 즉, Permission이 암시하는 리소스는 누구나 접근할 수 있다. |
보통 policies.xml은 JEUS 서버 리소스에 대한 Permission( JNDI, JMS, Security 서버 등)을 설정하는 데 사용되고, J2EE 애플리케이션과 J2EE 모듈에 대한 Permission을 설정하는 데는 사용하지 않는다. 대신 J2EE 애플리케이션과 모듈에 Permission을 설정하기 위해 다양한 DD 파일을 사용한다. 자세한 사항은 “제3장 애플리케이션과 모듈에서 보안 설정”을 참고한다.
Permission(Role Permission 또는 Resource Permission)을 policies.xml 파일에 추가할 때마다 Permission을 나타내는 Java 클래스명을 설정해야 한다. 해당 클래스는 java.security.Permission 추상 클래스를 확장한 것이다. 자신만의 java.security.Permission 구현 클래스를 생성하여, policies.xml에 <classname> 태그로 설정하면 Custom Permission을 직접 생성할 수 있다.
다음 요구사항을 가진 새로운 Custom Permission을 구현하는 방법을 설명한다. 새로운 Role Permission은 원래의 Role 외에 다음과 같은 2가지 조건이 충족되는 상황에서 또 다른 Role을 암시할 수 있다.
또 다른 Role도 원래의 Role과 동일한 이름을 가지고 있다.
현재 시간이 특정 시간 범위(오전 9시부터 오후 5시까지) 내에 있을 때만 또 다른 Role을 암시할 수 있다.
예를 들어 이러한 Role Permission은 뱅킹 애플리케이션에서 "user2"라는 Principal이 오전 9시부터 오후 5시까지 업무시간 동안만 "teller"라는 Role을 가질 수 있도록 만들 수 있다.
이를 위해 다음의 2가지 작업이 필요하다.
Custom Permission 클래스를 구현한다. 클래스 구현이 완료되면 "javac"로 컴파일하고 JEUS 서버의 클래스 패스에 해당 클래스 경로를 설정한다.
다음은 위의 요구사항을 만족하는 Custom Permission 클래스를 구현한 것이다. 자세한 코드는 생략한다.
[예 2.9] Custom Permission 클래스 : <<TimeConstrainedRolePermission.java>>
package jeus.security.resource; import java.security.Permission; import java.util.Calendar; import java.util.StringTokenizer; /** * A time-constrained Role permission. * <p> * With this permission implementation you can express * things such as "X can only be in the role Y between * 09:00 AM to 05:00 PM". */ public class TimeConstrainedRolePermission extends RolePermission { private String timeConstraint = "*"; private int startTime = Integer.MIN_VALUE; private int endTime = Integer.MAX_VALUE; public TimeConstrainedRolePermission(String roleName) { this(roleName, "*"); } public TimeConstrainedRolePermission(String roleName, String timeConstraint) { super(roleName); if (timeConstraint != null) { this.timeConstraint = timeConstraint; parseTimeConstraint(); } } private void parseTimeConstraint() { . . . } public boolean equals(Object anotherObject) { . . . } public int hashCode() { . . . } public String getActions() { return timeConstraint; } public boolean implies(Permission anotherPermission) { if (this.timeConstraint.equals("*")) { return super.implies(anotherPermission); } else { Calendar cal = Calendar.getInstance(); int curHour = cal.get(Calendar.HOUR_OF_DAY); int curMinute = cal.get(Calendar.MINUTE); int now = curHour * 60 + curMinute; if (now >= this.startTime && now <= this.endTime) { return super.implies(anotherPermission); } else { return false; } } } }
해당 클래스는 jeus.security.resource.RolePermission을 상속하고,
jeus.security.resource.RolePermission은 다시
java.security.Permission을 상속한다. 이는 코드 재사용성을 높이기 위한 구조이다.
TimeConstrainedRolePermission을 상속해 또 다른 java.security.Permission을 만드는 것도 가능하다.
위의 소스 일부에서 보면 2가지 타입의 생성자가 있다.
첫 번째는(role name) 하나의 파라미터만 받는다.
두 번째는(role name, time constraint) 2개의 파라미터를 받는다.
java.security.Permission에서 첫 번째 파라미터는 "name"을 뜻하고 두 번째 파라미터는 "actions"를 뜻한다. 몇몇 Permission 구현 클래스는 "actions" 파라미터를 받는 두 번째 타입의 생성자가 생략되기도 한다.
"actions" 파라미터는 Permission에 대한 유효 시간을 나타내며, “09:00-17:00”라는 값을 가진다.
"name" 파라미터는 "administrator" 또는 "teller"와 같은 Role명을 나타낸다.
소스의 핵심은 "implies(Permission anotherPermission)" 메소드로 현재 시스템 시간이 주어진 유효 시간 내에 있는지 체크한 다음, 만약 그렇다면 super.implies() 메소드를 호출하고, 그렇지 않으면 false를 리턴한다. 모든 implies() 메소드는 Boolean 값을 리턴하게 되어 있는데, 해당 Permission이 파라미터로 넘어온 Permission을 암시하는지를 나타낸다.
1. implies() 메소드와 java.security.Permission 추상 클래스에 대한 자세한 정보는 Java SE JavaDoc 문서를 참고한다.
2. jeus.security.resource.RolePermission, jeus.security.resource.TimeConstrainedRolePermission, jeus.security.resource.ResourcePermission에 대한 자세한 정보는 참고 자료와 JEUS Security JavaDoc에서 jeus.security.resource 패키지를 참고한다.
policies.xml에 해당 Permission을 사용하도록 설정한다.
[예 2.10] Custom Permission 클래스 : <<policies.xml>>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <policies xmlns="http://www.tmaxsoft.com/xml/ns/jeus"> <policy> <role-permissions> <role-permission> <principal>user2</principal> <role>administrator</role> <actions>9:00-17:00</actions> <classname> jeus.security.resource.TimeConstrainedRolePermission </classname> </role-permission> </role-permissions> <resource-permissions> <context-id>default</context-id> <resource-permission> <role>administrator</role> <resource>jeus.*</resource> <actions>*</actions> </resource-permission> </resource-permissions> </policy> . . . </policies>
"user2"라는 사용자는 "administrator" Role을 오전 9시부터 오후 5시까지 업무시간 동안만 부여받는다. "administrator" Role은 모든 JEUS 리소스(jeus.*)에 대해 모든 액션(*)을 실행할 수 있는 권한을 가지고 있다. 따라서, user2는 업무시간 동안만 모든 JEUS 리소스에 대한 모든 권한을 행사할 수 있다.
위의 스키마는 J2EE 애플리케이션과 모듈에서 JEUS DD 파일을 설정할 때도 그대로 적용되고 예제에서 보여준 Principal-to-Role Permission에 적용되고, Role-to-Resource Permission에도 동일하게 적용된다. JEUS DD에서 Custom Permission을 사용하는 방법은 “제3장 애플리케이션과 모듈에서 보안 설정”을 참고한다.
데이터베이스를 이용하여 Policy를 설정하려면 다음과 같이 domain.xml에서 보안 도메인 서비스를 지정해야 한다. Authentication과 마찬가지로 Driver Manager를 직접 이용하고 싶은 경우 <datasource-id> 대신에 <dbdriver-config> 태그를 추가한다. 그러나 일반적으로 JEUS JDBC 데이터소스를 사용할 것을 권장한다.
[예 2.11] 데이터베이스를 이용한 Policy 설정 : <<domain.xml>>
<?xml version="1.0" encoding="UTF-8"?> <domain xmlns="http://www.tmaxsoft.com/xml/ns/jeus"> ... <security-manager> <security-domains> <security-domain> <name>MY_DOMAIN</name> <authorization> <repository-service> <database-repository> <datasource-id>auth</datasource-id> </database-repository> </repository-service> </authorization> . . . </security-domain> </security-domains> </security-manager> . . . </domain>
데이터베이스를 사용하는 AuthenticationRepositoryService를 사용하려면 데이터베이스에 접근하는 JDBC 드라이버와 접근을 하기위한 정보인 URL, 사용자 이름 그리고 패스워드가 필요하다.
본 예제에서는 Oracle에 접근하기 위한 정보로 패스워드는 base64로 인코딩된 문자가 입력된다. 특정 암호화 알고리즘 또는 인코딩 방식이 적용된 패스워드 값을 기입하는 경우 accounts.xml의 사용자 패스워드와 동일한 방식으로 기입하면 된다.
데이터베이스에서 사용되는 테이블은 다음과 같이 구성된다.
데이터베이스에 테이블이 존재하지 않는다면
JEUS_HOME/templates/security/dbrealm.sql.template 파일을 이용해서 DB에 테이블을 생성하여
기본적인 Policy는 “SYSTEM_DOMAIN”에 “administrator”라는 Role을 가지게 되고, “jeus.*”에
대한 Resource 권한을 가진다. “administrator” Role 포함된 principal은 “2.5.3. 데이터베이스 사용 설정”에서 설명한 jeus이다.
본 절에서는 Subject와 Policy 이외의 추가 항목을 설정하는 방법을 설명한다.
JEUS에서 Java SE SecurityManger를 사용하면, 플랫폼에 대한 부수적인 견고성을 얻을 수 있으나 성능이 저하된다. 일반적으로 Java SE SecurityManger에서는 모든 핵심 JEUS 코드뿐 아니라 JEUS에 deploy되어 있는 J2EE 애플리케이션 및 모듈이 완벽하게 신뢰받은 코드로 간주되므로, 굳이 보안 관리자를 사용하여 부하를 초래할 필요는 없다. 보안 관리자를 사용하지 않는 모드가 JEUS에서 디폴트 모드이다.
그러나 때때로 Java SE SecurityManger를 사용하여 코드 수준의 보안을 강화시켜 추가적인 견고성을 높이는 문제가 성능 저하보다 중요하게 다루어지는 경우가 있다.
예를 들어 시스템 관리자가 불안정한 코드를 포함하고 있을지도 모르는 Java EE 애플리케이션을 JEUS에 deploy해야 한다. 이 경우에 성능 저하라는 비용을 감수하고서라도 코드 레벨의 보안을 강화시켜 호스트를 보호하는 것이 더 중요하다고 판단되면 Java SE SecurityManger를 작동시켜야 한다.
Java SE SecurityManger를 JEUS와 함께 동작시키기 위해 domain.xml에 특정 서버에 대해 jvm-option을 다음과 같이 정의한다.
-Djava.security.manager -Djava.security.policy=${JEUS_HOME}/domains/domain1/config/security/policy(UNIX기준)
정책 파일은 JEUS_HOME/domains/<domain name>/config/security/policy이며 내용은 다음과 같다.
[예 2.12] Java SE SecurityManager 설정 : <<policy>>
grant codeBase "file:${jeus.home}/lib/system/*" { permission java.security.AllPermission; }; grant { permission java.net.SocketPermission "127.0.0.1:1024-", "connect, accept, connect, listen, resolve"; permission java.security.SecurityPermission "runTrustedLogin", "read"; permission java.security.SecurityPermission "loginCodeSubject", "read"; permission java.security.SecurityPermission "putProviderProperty.*"; permission java.security.SecurityPermission "insertProvider.*"; permission javax.management.MBeanPermission "*", "*"; };
Java SE SecurityManger는 JEUS의 보안 시스템과는 완전히 별개의 것이다. JEUS 보안 시스템은 코드 수준의 보호(코드를 호출할 수 있는 Permission 설정)가 아니라, 사용자 수준의 보호(누가 로그인했고, 해당 자원에 대한 Permission이 있는가)를 다루고 있다.
둘 사이 유일한 접점은 JEUS가 특별한 경우 Java SE SecurityManger를 사용하여 코드 수준의 Permission을 체크함으로써 악의적인 Servlet이나 EJB 코드로부터 JEUS를 보호하기도 한다는 점이다.
JEUS에서 JACC 1.4 설정에 대한 이슈는 “제6장 JACC Provider 사용”에서 충분히 설명할 것이다. 더 자세한 내용은 해당 절을 참고한다.
IdentityAssertionService 지원하는 경우 추가적으로 인증서와 사용자 간의 매핑 정보가 있는 cert-user-map.xml 파일에서 읽어 들인다. 이 파일은 다음의 경로에 위치한다.
JEUS_HOME/domains/<domain name>/config/security/<security domain name>/
<domain name>은 도메인의 이름이고, <security domain name>은 사용자가 속한 보안 도메인의 이름을 나타낸다. cert-user-map.xml의 XML 스키마는 cert-user-map.xsd이며, JEUS_HOME/lib/schemas/jeus 경로에 있다.
이 파일에는 최상위 태그 <cert-user> 하위에 <user> 및 <cert> 태그가 있으며 하위 0개 이상의 <cert-user> 태그가 포함되어 있다. 각각은 사용자에 대한 인증서 매핑을 위한 속성 정보를 나타내고 있다.
[예 2.13] Identity 부여를 위한 정보 설정 : <<cert-user-map.xml>>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <cert-user-map xmlns="http://www.tmaxsoft.com/xml/ns/jeus"> <cert-user> <username>user1</username> <cert> <subjectDN>user1DN</subjectDN> </cert> </cert-user> </cert-user-map>
각 <cert-user> 태그는 다음과 같은 하위 태그를 가지고 있다.
각 <cert> 태그는 다음과 같은 하위 태그를 가지고 있으며 사용자에 대한 인증서 매핑 정보을 정의한다. 이는 Truststore 파일에 포함된 인증서에 대해서 하위 attribute 값들이 유일한 ID를 보장해서 idenity를 부여할 수 있도록 사용자 이름과 매핑되는 값들을 정의한다.
태그 | 설명 |
---|---|
<alias> (선택) | Keystore 내의 Certificate에 대한 Alias를 정의한다. (문자열) |
<subjectDN> (선택) | Keystore 내의 Certificate에 대한 subjectDN를 정의한다. (문자열) |
<SKI> (선택) | Keystore 내의 Certificate에 대한 SKI를 정의한다. (문자열) |
<issuer> (선택) | Keystore 내의 Certificate에 대한 issuer를 정의한다. (문자열) |
<serialNo> (선택) | Keystore 내의 Certificate에 대한 serial number를 정의한다. (문자열) |
JEUS 보안 시스템에서는 인증서로 인증된 Identity 사용자 정보에 대한 인증서 정보를 얻을 수 있는 API를 제공하는 UserCertMappingService를 제공한다. UserCertMappingService 지원하는 경우 추가적으로 사용자별 인증서 파일을 얻기 위한 매핑 정보가 있는 user-cert-map.xml 파일에서 읽어 들인다. 이 파일은 다음의 경로에 위치한다.
JEUS_HOME/domains/<domain name>/config/security/<security domain name>/
<domain name>은 도메인의 이름이고, <security domain name>은 사용자가 속한 보안 도메인의 이름을 나타낸다. user-cert-map.xml의 XML 스키마는 user-cert-map.xsd이며, JEUS_HOME/lib/schmas/jeus 경로에 있다.
이 파일에는 최상위 태그 <user-cert-map> 태그 하위에 0개 이상의 <user-cert> 태그가 포함되어 있다. 각각은 Keystore 파일에서 사용자에 대한 인증서를 얻기 위한 속성 정보를 나타낸다.
[예 2.14] Identity에 대한 인증서 정보 설정 : <<user-cert-map.xml>>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <user-cert-map xmlns="http://www.tmaxsoft.com/xml/ns/jeus"> <user-cert> <username>user1</username> <alias>alias1</alias> <keypassword>changeit</keypassword> <secretkey> <keyname>testkeypass</keyname> <keyalgorithm>AES</keyalgorithm> <keyvalue>bjhTUjJvSXRTOGlkVEdlNHJnM2N3VnljSDZXV0JkYz0=</keyvalue> </secretkey> </user-cert> </user-cert-map>
각 <user-cert> 태그는 다음과 같은 하위 태그를 가지고 있다.
Keystore 내의 Certificate에 대한 사용자 이름을 정의한다. "primary" identify로서 유일해야 한다.
(예: 사용자명, 사용자 ID)
Keystore 내의 Certificate에 대한 Alias를 정의한다.
Keystore 내의 Certificate에 대한 Private Key를 얻기위한 Keypassword를 정의한다. (예: changeit)
Private Key를 정의한다.
각 <secretkey> 태그는 다음과 같은 하위 태그를 가지고 있다.
태그 | 설명 |
---|---|
<keyname> (필수) | Private Key의 이름을 정의한다. <user-cert-map> 태그 하위에 존재하는 keyname 값은 유일해야 한다. (문자열) |
<keyalgorithm> (필수) | Private Key의 키 알고리즘을 나타낸다. (문자열) |
<keyvalue> (필수) | Private Key의 값을 Base64 형태로 나타낸다. |