모든 JAAS

응용 프로그램에 대한 로그인 인증 메커니즘을 만들어야했던 적이 있습니까? 확률은 각 새로운 구현이 이전 구현과 비슷하지만 동일하지는 않지만 두 번 이상있을 수 있습니다. 예를 들어, 한 구현은 Oracle 데이터베이스를 사용하고 다른 구현은 NT 인증을 사용하고 다른 구현은 LDAP (Lightweight Access Directory Protocol) 디렉토리를 사용할 수 있습니다. 애플리케이션 수준 코드를 변경하지 않고 이러한 모든 보안 메커니즘을 지원하는 것이 좋지 않을까요?

이제 Java 세계에서 JAAS (Java Authentication and Authorization Service)를 사용할 수 있습니다. 상대적으로 새로운이 API는 J2SE (Java 2 Platform, Standard Edition) 1.3의 확장이며 J2SE 1.4의 핵심 API이며 J2EE (Java 2 Platform, Enterprise Edition) 1.3 사양의 일부이기도합니다. 이 기사에서는 JAAS 필수 사항을 가르치고 실제 애플리케이션에 JAAS를 효과적으로 적용하는 방법을 보여줍니다. 이 기사의 애플리케이션은 사용자 로그인 정보를 저장하기 위해 RDBMS (관계형 데이터베이스 관리 시스템)를 사용하는 기존 Java 웹 기반 시스템에 JAAS를 통합 한 경험을 기반으로합니다. JAAS를 통해 우리는보다 강력하고 유연하며 일관된 로그인 및 인증 메커니즘을 설계했습니다.

아래 리소스에서 전체 작업 예제 세트를 다운로드 할 수 있습니다 (Java 소스, JSP (JavaServer Pages), JAAS 구성, 데이터베이스 및 빌드 스크립트 포함). JDBC (Java Database Connectivity)와 MySQL 데이터베이스가있는 Resin 서버를 사용하여이 예제를 테스트했습니다.

Java 인증 및 권한 부여 : 큰 그림

JAAS 이전에 Java의 보안 모델은 대부분 분산 된 네트워크 응용 프로그램을위한 플랫폼 독립적 언어로서의 기원에 의해 형성되었습니다. 초기에 Java는 브라우저 기반 애플릿과 같은 모바일 코드로 등장한 경우가 많았으므로 초기 보안 모델 은 코드의 출처작성자를 기반으로 사용자를 보호하는 데 중점을 두었 습니다.SecurityManager s, 샌드 박스 개념, 코드 서명 및 정책 파일과 같은 초기 Java 보안 메커니즘 은 모두 시스템에서 사용자를 보호하기위한 것입니다.

JAAS의 발명은 로그인 및 액세스 제어가 필요한 기존 클라이언트 및 서버 애플리케이션을 구현하는 데 사용되는 범용 프로그래밍 언어로의 Java 진화를 반영합니다. JAAS 는 프로그램을 실행하는 사람 또는 대상에 따라 액세스를 허용하거나 거부하여 사용자로부터 시스템을 보호합니다 . JAAS는 인증과 권한 부여를 모두 수행 할 수 있지만이 기사에서는 주로 인증에 중점을 둡니다.

JAAS는 애플리케이션과 서로 다른 기본 인증 및 권한 부여 메커니즘 사이에 추상화 계층을 배치하여 Java 보안 개발을 단순화 할 수 있습니다. 이러한 플랫폼 및 알고리즘과의 독립성을 통해 애플리케이션 수준 코드를 수정하지 않고도 다양한 보안 메커니즘을 사용할 수 있습니다. 대부분의 Java 보안 API와 마찬가지로 JAAS는 특정 구현이 개발되는 추상 클래스 및 인터페이스 집합 인 플러그 형 서비스 공급자 인터페이스 (SPI)의 확장 가능한 프레임 워크를 통해 이러한 구현 독립성을 달성합니다.

아래의 그림 1은 JAAS가이 플러그 가능성을 달성하는 방법에 대한 높은 수준의 개요를 제공합니다. 응용 프로그램 계층 코드는 주로 LoginContext. 그 아래 에는 적절한 보안 인프라를 사용하여 실제 인증을 처리하는 LoginContext동적으로 구성된 하나 이상의 집합 LoginModule이 있습니다.

JAAS는 다음 LoginModule과 같은 일부 참조 구현을 제공 합니다 JndiLoginModule. 여기에서 RdbmsLoginModule. 또한 간단한 구성 파일을 사용하여 구현을 선택하여 애플리케이션을 빠르게 설정하는 방법을 보여줍니다.

플러그 가능한 것 외에도 JAAS는 스택 가능합니다. 단일 로그인 컨텍스트에서 일련의 보안 모듈은 순서대로 호출되고 각각 다른 보안 인프라와 상호 작용하는 서로 위에 쌓일 수 있습니다.

JAAS 측면은 일부 익숙한 보안 아키텍처 패턴 및 기존 프레임 워크에서 모델링됩니다. 예를 들어 스택 가능 기능은 의도적으로 Unix PAM (Pluggable Authentication Module) 프레임 워크와 유사합니다. 트랜잭션 관점에서 JAAS는 2 단계 커밋 (2PC) 프로토콜과 유사한 동작을 채택합니다. Policy파일 및을 포함한 JAAS의 보안 구성 개념 Permissions은 J2SE 1.2 보안 패키지에서 제공됩니다. JAAS는 또한 이름 Subject이 파생 된 X.509 인증서와 같은 다른 확립 된 보안 프레임 워크에서 아이디어를 차용합니다 ( Subject나중에 자세히 알아 보겠습니다 ).

참고 : JAAS는 몇 가지 새로운 Java 보안 API 중 하나 일뿐입니다. Java 보안에 대한 자세한 내용은 "Java 보안 퍼즐"사이드 바와 아래 리소스를 참조하십시오.

클라이언트 측 및 서버 측 JAAS

클라이언트와 서버 모두에서 JAAS를 적용 할 수 있습니다. 클라이언트 측에서 사용하는 것은 간단합니다. 곧 설명하겠습니다. 서버 측에서는 상황이 조금 더 복잡해집니다. 현재 애플리케이션 서버 시장의 JAAS는 약간 일치하지 않습니다. J2EE 앱 서버는 사용하는 서버에 따라 JAAS를 약간 다르게 사용합니다. 예를 들어 JBossSX는 자체 아키텍처를 사용하여 전체 보안 프레임 워크에 JAAS를 훌륭하게 통합합니다 (Scott Stark의 뛰어난 JavaWorld 기사 "Integrate Security Infrastructures with JBossSX"(2001 년 8 월)에 자세히 설명되어 있음). 그러나 WebLogic 6.x는 JAAS를 지원하지만 세부 사항은 다릅니다.

따라서 서버 측과 클라이언트 측 모두에서 JAAS를 이해할 수 있으므로이 기사에서 두 가지 모두에 대한 예를 보여 드리겠습니다. 그리고 서버의 단순성을 위해 Resin 애플리케이션 서버를 사용할 것이므로 더 깨끗한 슬레이트로 시작할 수 있습니다 (Resin은 자체적으로 플러그 형 인증 체계를 가지고 있지만 표준이 아니므로 JAAS를 사용하면 더 많은 이식성을 얻을 수 있습니다. 나중에 옵션).

핵심 JAAS

JAAS를 시작하려면 먼저 설치되었는지 확인해야합니다. J2SE 1.4에는 이미 JAAS가 포함되어 있습니다. J2SE 1.3은 그렇지 않습니다. J2SE 1.3을 계속 사용하려면 Sun Microsystems에서 JAAS를 다운로드하십시오. 주어진 디렉토리에 JAAS를 다운로드하여 설치하면 lib라는 파일이 들어있는 라는 하위 디렉토리가 표시됩니다 jaas.jar. 당신은 당신의 클래스 패스에이 파일을 추가해야하거나 (에 여러분의 JRE (자바 런타임 환경) 확장 디렉토리에 복사합니다 \lib\ext경우, 귀하의 JRE의 위치입니다). 그러면 JAAS를 사용할 수 있습니다. 참고 : 애플리케이션 서버를 사용하는 경우 JAAS가 이미 포함되어있을 수 있습니다. 자세한 내용은 서버 설명서를 확인하십시오.

이러한 접근 방식을 사용하면 Java 보안 속성 파일에서 일부 JAAS 관련 시스템 속성 설정 (및 기타 많은 Java 보안 설정)을 변경할 수 있습니다. 이 파일 java.security/lib/security디렉토리에 있으며 표준 Java 특성 파일 형식으로 작성됩니다.

애플리케이션에서 JAAS 인증을 사용하려면 일반적으로 다음 단계가 포함됩니다.

  1. 만들기 LoginContext
  2. 선택적으로 전달 CallbackHandler받는 LoginContext인증 데이터를 수집 또는 처리하는,
  3. LoginContextlogin()메서드 를 호출하여 인증을 수행합니다.
  4. 반환 된을 사용하여 권한있는 작업 수행 Subject(로그인이 성공했다고 가정)

다음은 최소한의 예입니다.

LoginContext lc = new LoginContext ( "MyExample"); 시도 {lc.login (); } catch (LoginException) {// 인증에 실패했습니다. } // 인증에 성공했습니다. 이제 계속할 수 있습니다. // 원하는 경우 반환 된 Subject를 사용할 수 있습니다. 제목 sub = lc.getSubject (); Subject.doAs (sub, new MyPrivilegedAction ());

덮개 아래에서 몇 가지 다른 일이 발생합니다.

  1. 초기화하는 동안 LoginContext"MyExample"(가 구성한) JAAS 구성 파일에서 구성 항목 을 찾아 LoginModule로드 할을 결정합니다 (그림 2 참조).
  2. 로그인하는 동안 LoginContextLoginModulelogin()메소드를 호출합니다.
  3. login()방법은 인증을 수행하거나CallbackHandler
  4. CallbackHandler사용하는 하나 이상의 Callback(S)은 사용자와 상호 작용하는 입력을 수집
  5. A new Subject instance is populated with authentication details such as Principals and credentials

We'll explain further details below, but to begin, let's look at the key JAAS classes and interfaces involved in the process. These are typically divided into the following three groups:

Table 1. JAAS classes and interfaces

Common Subject, Principal, credential (credential is not any specific class, but can be any object)
Authentication LoginContext, LoginModule, CallbackHandler, Callback
Authorization Policy, AuthPermission, PrivateCredentialPermission

Most of these classes and interfaces are in the javax.security.auth package's subpackages, with some prebuilt implementations in the com.sun.security.auth package, included only in J2SE 1.4.

Note: Because we focus on authentication in this article, we don't delve into the authorization classes.

Common: Subjects, Principals, and Credentials

The Subject class represents an authenticated entity: an end-user or administrator, or a Web service, device, or another process. The class contains three sets of security information types:

  • Identities: In the form of one or more Principals
  • Public credentials: Such as name or public keys
  • Private credentials: Like passwords or private keys

Principals represent Subject identities. They implement the java.security.Principal interface (which predates JAAS) and java.io.Serializable. A Subject's most important method is getName(), which returns an identity's string name. Since a Subject instance contains an array of Principals, it can thus have multiple names. Because a social security number, login ID, email address, and so on, can all represent one user, multiple identities prove common in the real world.

The last element here, credential, is not a class or an interface, but can be any object. Credentials can include any authentication artifact, such as a ticket, key, or password, that specific security systems might require. The Subject class maintains unique Sets of private and public credentials, which can be retrieved with methods such as getPrivateCredentials() and getPublicCrendentials(). These methods are more often used by security subsystems than at the application layer.

Authentication: LoginContext

Your application layer uses LoginContext as its primary class for authenticating Subjects. LoginContext also represents where JAAS's dynamic pluggability comes into play, because when you construct a LoginContext, you specify a named configuration to load. The LoginContext typically loads the configuration information from a text file, which in turn tells the LoginContext which LoginModules to use during login.

The three commonly used methods in LoginContext are:

Table 2. LoginContext methods

login() Performs login, a relatively complex step that invokes all LoginModules specified for this configuration. If it succeeds, it creates an authenticated Subject. If it fails, it throws a LoginException.
getSubject() Returns the authenticated Subject.
logout() Logs out the authenticated Subject and removes its Principals and credentials.

We will show how to use these methods later.

Authentication: LoginModule

LoginModule is the interface to specific authentication mechanisms. J2SE 1.4 ships with a set of ready-to-use LoginModules, including:

Table 3. LoginModules in J2SE 1.4

JndiLoginModule Verifies against a directory service configured under JNDI (Java Naming and Directory Interface)
Krb5LoginModule Authenticates using Kerberos protocols
NTLoginModule Uses the current user's NT security information to authenticate
UnixLoginModule Uses the current user's Unix security information to authenticate

Along with these modules comes a set of corresponding concrete Principal implementations in the com.sun.security.auth package, such as NTDomainPrincipal and UnixPrincipal.

The LoginModule interface has five methods:

Table 4. LoginModule methods

initialize() Called after the LoginModule is constructed.
login() Performs the authentication.
commit() Called by the LoginContext after it has accepted the results from all LoginModules defined for this application. We assign Principals and credentials to the Subject here.
abort() Called when any LoginModule for this application fails (even though earlier ones in sequence may have succeeded—thus akin to a 2PC model). No Principals or credentials are assigned to the Subject.
logout() Removes the Principals and credentials associated with the Subject.

The application layer calls none of these methods directly—the LoginContext invokes them as needed. Our example below will elaborate on these methods' implementations.

Authentication: CallbackHandlers and Callbacks

CallbackHandlers 및 Callbacks LoginModule는 사용자 또는 시스템에서 필요한 인증 정보를 수집하면서 실제 상호 작용 메커니즘과는 독립적입니다. 우리는 디자인에서이 기능을 활용할 것입니다 RdbmsLoginModule. 사용자 자격 증명 (사용자 이름 / 암호)을 얻는 방법에 의존하지 않으므로 설명 할 다른 응용 프로그램 환경 (명령 줄 또는 JSP에서)에서 사용할 수 있습니다. .