Всичко това JAAS

Искали ли сте някога да създадете механизъм за удостоверяване на вход за приложение? Коефициентите са, имате и вероятно повече от веднъж, като всяко ново изпълнение е близко, но не идентично с предишното. Например, една реализация може да използва база данни на Oracle, друга може да използва NT удостоверяване, а друга, директория LDAP (лек протокол за директен достъп). Не би ли било хубаво да се поддържат всички тези механизми за сигурност, без да се променя код на ниво приложение?

Сега в света на Java можете с услугата за удостоверяване и упълномощаване на Java (JAAS). Този относително нов API беше разширение в J2SE (Java 2 Platform, Standard Edition) 1.3, е основен API в J2SE 1.4 и също е част от спецификацията J2EE (Java 2 Platform, Enterprise Edition) 1.3. В тази статия ще ви научим на основите на JAAS и ще ви покажем как ефективно да приложите JAAS към реални приложения. Базирахме приложението на тази статия върху собствения ни опит при интегрирането на JAAS в съществуваща уеб-базирана система на Java, която използва RDBMS (система за управление на релационна база данни) за съхраняване на информация за вход на потребителя. С JAAS разработихме по-здрави, гъвкави и последователни механизми за влизане и удостоверяване.

Можете да изтеглите пълен набор от работни примери от Ресурси по-долу (включва Java източници, JSP (JavaServer Pages), JAAS конфигурация, със скриптове за база данни и компилация). Тествахме тези примери, използвайки Resin сървър с JDBC (Java Database Connectivity) и базата данни MySQL.

Удостоверяване и упълномощаване на Java: Голямата картина

Преди JAAS, защитният модел на Java се формира най-вече от произхода си като независим от платформа език за разпределени мрежови приложения. В ранните си дни Java често се появява като мобилен код, като базираните на браузър аплети, и следователно първоначалният модел на защита се фокусира върху защитата на потребителите въз основа на произхода на кода и кой го е създал. Механизмите за ранна защита на Java като SecurityManagers, концепцията за пясъчник, подписването на код и файловете с политики са били предназначени да защитават потребителите от системата.

Изобретението на JAAS отразява еволюцията на Java в език за програмиране с общо предназначение, използван за внедряване на традиционни клиентски и сървърни приложения, които изискват контрол на достъп и достъп. JAAS защитава системата от потребители, като разрешава или отказва достъп въз основа на това кой или какво изпълнява програмата. Въпреки че JAAS може да извършва едновременно удостоверяване и упълномощаване, в тази статия ние се фокусираме основно върху удостоверяването.

JAAS може да опрости разработката ви за защита на Java, като постави абстракционен слой между вашето приложение и различни механизми за удостоверяване и упълномощаване. Тази независимост от платформи и алгоритми ви позволява да използвате различни механизми за сигурност, без да променяте кода на ниво приложение. Както при повечето приложни програмни интерфейси (API) за защита на Java, JAAS постига тази независимост от внедряването чрез разширяема рамка от интерфейси на доставчици на услуги (SPI): набор от абстрактни класове и интерфейси, за които са разработени специфични внедрения.

Фигура 1 по-долу дава общ преглед на високо ниво за това как JAAS постига тази свързаност. Кодът на приложния ви слой се занимава предимно с a LoginContext. Отдолу LoginContextе набор от един или повече динамично конфигурирани LoginModules, които обработват действителното удостоверяване, използвайки подходящата инфраструктура за сигурност.

JAAS предоставя някои референтни LoginModuleизпълнения, като например JndiLoginModule; можете също да разработите свой собствен, както ще направим тук с RdbmsLoginModule. Ще покажем също как можете бързо да настроите приложение с избор на изпълнения, като използвате прост конфигурационен файл.

В допълнение към JAAS с възможност за включване: в контекста на едно влизане, набор от модули за сигурност могат да се натрупват един върху друг, като всеки се извиква по ред и всеки взаимодейства с различна инфраструктура за сигурност.

Аспектите на JAAS са моделирани на някои познати архитектурни модели на сигурност и съществуващи рамки. Например подреждащата се функция умишлено наподобява рамката на Unix Pluggable Authentication Module (PAM). От гледна точка на транзакциите, JAAS приема поведения, подобни на протоколите за двуфазно фиксиране (2PC). Концепциите за конфигуриране на защитата на JAAS, включително Policyфайлове и Permissions, идват от пакетите за сигурност J2SE 1.2. JAAS също така взаимства идеи от други утвърдени рамки за сигурност, като X.509 сертификати, от които Subjectпроизлиза името (ще научите повече за това Subjectпо-късно).

Забележка: JAAS е само един от няколкото нови API за защита на Java. За повече информация относно защитата на Java вижте страничната лента "Пъзел за защита на Java" и ресурси по-долу.

Клиентски и сървърни JAAS

Можете да приложите JAAS както на клиента, така и на сървъра. Използването му от страна на клиента е лесно, както ще демонстрираме скоро. От страна на сървъра нещата стават малко по-сложни. В момента JAAS на пазара на сървъри за приложения е малко непоследователен; J2EE сървърите за приложения използват JAAS малко по-различно, в зависимост от това кой използвате. Например, JBossSX, използвайки своя собствена архитектура, добре се интегрира в цялостната му JAAS рамка за сигурност (което е описано подробно в отлично Скот Старк JavaWorld статия "Интегриране на сигурността инфраструктури с JBossSX" (August 2001)). Въпреки това, въпреки че WebLogic 6.x поддържа JAAS, подробностите се различават.

Така че можете да разберете JAAS както от гледна точка на сървъра, така и от страна на клиента, в тази статия ще демонстрираме примери за двете. И за целите на простотата на сървъра, ще използваме сървъра за приложения Resin, за да можем да започнем с по-чист лист (Resin има собствена схема за удостоверяване с възможност за включване, но е нестандартна, така че използването на JAAS ни дава по-голяма преносимост опции по-късно).

Основен JAAS

За да започнете с JAAS, първо трябва да се уверите, че е инсталиран. J2SE 1.4 вече включва JAAS; J2SE 1.3 не. Ако искате да продължите да използвате J2SE 1.3, изтеглете JAAS от Sun Microsystems. След като изтеглите и инсталирате JAAS в дадена директория, ще видите извикана поддиректория lib, която съдържа един файл с име jaas.jar. Ще трябва да добавите този файл към своя път на класа или да го копирате в директорията с разширения на JRE (Java Runtime Environment) ( \lib\extтам, където е местоположението на вашия JRE). След това сте готови за JAAS. Забележка: Ако използвате сървър на приложения, той може вече да включва JAAS. За подробности проверете документацията на вашия сървър.

С всеки от тези подходи имайте предвид, че можете да промените някои от свързаните с JAAS настройки на системните свойства (както и много други настройки за защита на Java) във файла със свойства на защитата на Java. Този файл, java.securityсе намира в /lib/securityдиректорията и е написан в стандартния файлов файлов формат на свойствата на Java.

Използването на JAAS удостоверяване от вашето приложение обикновено включва следните стъпки:

  1. Създавам LoginContext
  2. По избор предайте a CallbackHandlerна LoginContext, за събиране или обработка на данни за удостоверяване
  3. Извършване на идентификация, като се обадите на LoginContext-те login()метод
  4. Извършвайте привилегировани действия, използвайки върнатото Subject(при условие, че влизането е успешно)

Ето минимален пример:

LoginContext lc = нов LoginContext ("MyExample"); опитайте {lc.login (); } catch (LoginException) {// Неуспешно удостоверяване. } // Удостоверяването е успешно, вече можем да продължим. // Можем да използваме върнатата тема, ако желаем. Subject sub = lc.getSubject (); Subject.doAs (под, ново MyPrivilegedAction ());

Под кориците се случват още няколко неща:

  1. По време на инициализацията LoginContextнамира конфигурационния запис "MyExample"в JAAS конфигурационен файл (който сте конфигурирали), за да определи кои LoginModules да се заредят (вижте фигура 2)
  2. По време на вход, на LoginContextкоето приканва всеки LoginModuleе login()метод
  3. Всеки login()метод извършва удостоверяване или записва aCallbackHandler
  4. На CallbackHandlerИзползва едно или повече Callbackте да си взаимодействат с потребителя и да събират вход
  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) .