Обзор
Служба аутентификации и авторизации Java (JAAS) – это низкоуровневая структура безопасности Java SE, которая расширяет модель безопасности от безопасности на основе кода до безопасности на основе пользователя . Мы можем использовать JAAS для двух целей:
- Аутентификация: идентификация сущности, на которой в данный момент выполняется код.
- Авторизация: После проверки подлинности убедитесь, что этот объект имеет необходимые права управления доступом или разрешения для выполнения конфиденциального кода.
В этом руководстве мы рассмотрим, как настроить JAAS в примере приложения, реализуя и настраивая его различные API, особенно LoginModule .
Как работает JAAS
При использовании JAAS в приложении задействовано несколько API:
- CallbackHandler : Используется для сбора учетных данных пользователя и дополнительно предоставляется при создании LoginContext
- Конфигурация : Отвечает за загрузку LoginModule реализаций и может быть дополнительно предоставлена в LoginContext creation
- Модуль входа : Эффективно используется для аутентификации пользователей
Мы будем использовать реализацию по умолчанию для Конфигурации API и предоставим наши собственные реализации для CallbackHandler и LoginModule API.
Обеспечение реализации обратного вызова
Прежде чем копаться в реализации LoginModule , нам сначала нужно предоставить реализацию для интерфейсаCallbackHandler, который используется для сбора учетных данных пользователя .
У него есть один метод/| handle() , который принимает массив Callback s. Кроме того, JAAS уже предоставляет множество реализаций Обратного вызова , и мы будем использовать NameCallback и PasswordCallback для сбора имени пользователя и пароля соответственно.
Давайте посмотрим на нашу реализацию интерфейса CallbackHandler :
Итак, чтобы запросить и прочитать имя пользователя, мы использовали:
Аналогично, чтобы запросить и прочитать пароль:
Позже мы увидим, как вызвать CallbackHandler при реализации модуля Login .
1. инициализация()
LoginModuleсначала загружается, а затем инициализируется с помощьюSubjectиCallbackHandler . Кроме того, LoginModule s может использовать Map для обмена данными между собой, а другой Map для хранения личных данных конфигурации:
2. вход в систему()
В методе login() мы вызываем метод CallbackHandler.handler() с помощью NameCallback и PasswordCallback для запроса и получения имени пользователя и пароля. Затем мы сравниваем эти предоставленные учетные данные с жестко закодированными:
Методlogin()должен возвращатьtrueдля успешной операции иfalseдля неудачного входа в систему .
3. фиксация()
Если все вызовы LoginModule#login завершатся успешно, мы обновимSubjectдополнительнымPrincipal :
В противном случае вызывается метод abort () .
На данный момент наша реализация модуля Login готова и должна быть настроена таким образом, чтобы ее можно было динамически загружать с помощью поставщика услуг Configuration .
Конфигурация модуля Входа в систему
JAAS использует Конфигурацию поставщика услуг для загрузки Модуля входа s во время выполнения. По умолчанию он предоставляет и использует реализацию Config File , в которой Login Module s настраиваются через файл входа. Например, вот содержимое файла, используемого для нашего модуля Login :
Как мы видим, мы предоставили полное имя классаLoginModuleimplementation , флаг required и опцию для отладки.
Наконец, обратите внимание, что мы также можем указать файл входа в систему через java.security.auth.login.config системное свойство:
Мы также можем указать один или несколько файлов входа через свойство login.config.url в файле безопасности Java, ${java.home}/jre/lib/security/java.security :
Аутентификация
Во-первых, приложение инициализирует процесс аутентификации, создаваяLoginContextэкземпляр . Для этого мы можем взглянуть на полный конструктор, чтобы иметь представление о том, что нам нужно в качестве параметров:
- имя : используется в качестве индекса для загрузки только соответствующего LoginModule s
- тема : представляет пользователя или службу, которая хочет войти в систему
- CallbackHandler : отвечает за передачу учетных данных пользователя из приложения в модуль Login
- config : отвечает за загрузку Модуля входа s, соответствующих параметру name
Здесь мы будем использовать перегруженный конструктор, в котором мы будем предоставлять нашу реализацию CallbackHandler :
Теперь, когда у нас есть CallbackHandler и настроенный Модуль входа в систему , мы можем запустить процесс аутентификации, инициализировавLoginContextобъект :
На этом этапе мы можем вызвать методlogin()для аутентификации пользователя :
Метод login () , в свою очередь, создает новый экземпляр нашего модуля Login и вызывает его метод login () . И, после успешной аутентификации, мы можем получить аутентифицированныйСубъект :
Теперь давайте запустим пример приложения с подключенным модулем Login :
Авторизация
Авторизация вступает в игру, когда пользователь впервые подключен и связан с AccessControlContext . Используя политику безопасности Java, мы можем предоставить одно или несколько прав управления доступомPrincipals.
1. Определение разрешений
Право управления доступом или разрешение-это возможность выполнить действие над ресурсом . Мы можем реализовать разрешение, создав подкласс абстрактного класса Permission . Для этого нам нужно указать имя ресурса и набор возможных действий.
Например, мы можем использовать Разрешение файла для настройки прав управления доступом к файлам. Возможные действия: чтение , запись , выполнение и так далее. Для сценариев, в которых действия не требуются, мы можем просто использовать разрешение Basic .
Затем мы предоставим реализацию разрешения через класс ResourcePermission , в котором пользователи могут иметь разрешение на доступ к ресурсу:
Позже мы настроим запись для этого разрешения с помощью политики безопасности Java.
2. Предоставление Разрешений
Обычно нам не нужно знать синтаксис файла политики, потому что мы всегда можем использовать инструмент Policy/| для его создания. Давайте взглянем на наш файл политики:
3. Проверка разрешений
Как только Субъект аутентифицирован и настроены разрешения, мы можем проверить наличие доступа, вызвавСубъект#doAsилиСубъект#doAsPriviliegedстатические методы . Для этой цели мы предоставим PrivilegedAction , где мы сможем защитить доступ к конфиденциальному коду.
Последнее, что нужно сделать, это вызвать метод Subject#doAsPrivileged :
Как и аутентификация, мы запустим простое приложение для авторизации, где в дополнение к модулю Login мы предоставим файл конфигурации разрешений:
Jaas. настройка политики безопасности в дескриптере развертывания
Теперь начинается самое интересное. Для начала нам необходимо задать в настройках параметры механизма авторизации.
Исходный код
Полный исходный код рассмотренного приложения находится на
Пользователи, группы, роли
Для тех кто уже работал с системы распределенного доступа, вполне понятна схема разделения пользователей по группам, а группы (или пользователей) по ролям. Вкратце объясню не посвященным.
Пользователь является уникальной личностью для сервера. По желанию можно кластер пользователей объединить в группы, которые можно назвать как набор авторизованных пользователей. Для того, чтобы указать, какие пользователи и/или группы имеют доступ к защищенным ресурсам, необходимо создать роли.
В официальной документации от oracle есть хороший рисунок иллюстрирующий приведенное выше описание:
Применение jaas в web-приложениях на glassfish v2
На этот раз хочется написать про применение JAAS (Java Authentification and Authorization Service) для веб-приложений. Для начала рассмотрим простой контроль доступа к веб-ресурсам и авторизацию. Я попытаюсь раскрыть основную идею, а также дам подсказку по способу развёртывания (позже из текста станет понятно в чём проблема).
Прежде чем переходить к практике, следует осветить несколько основных понятий и общую схему контроля доступа к веб-ресурсам.
Когда веб-контейнер «тречит» сессии всех подключающихся к нему машин, то с каждой такой сессией могут быть ассоциированы роли, а также user principal. Каждая роль связана с возможностью или невозможностью доступа к некоторому набору веб-ресурсов, а также осуществления некоторых действий (privileged action).
Изначально сессия пользователя не связана ни с каким user principal’ом и ни с одной ролью. Это означает, что если на доступ к некоторому набору веб-ресурсов наложено ограничениче (constraint), то он не будет иметь доступ к этим ресурсам.
Для того, чтобы пользовательская сессия стала ассоциироваться с каким-то набором ролей, пользователь должен пройти авторизацию.
Авторизация осущестляется с помощью JAAS. Во время авторизации пользователь посылает свои креденциалы (credentials, в простом случае это могут быть логин: пароль или пользовательский сертификат). На сервере с процессом контроля связаны две сущности, а именно Realm и Login Module. Login Module осуществляет проверку связи пользователя с каким-то набором групп пользователей (не путать с ролями). Кроме того, авторизация может быть пройдена успешно, однако, пользователь может быть не связан ни с одной из групп.
Веб-приложение может определять соотношение между группами и ролями. Приложение задаёт это соответствие с помощью sun-web.xml.
Login Module и Realm не являются частью веб-приложения, а являются разделяемыми ресурсами сервера приложений, так что они должны быть в classpath сервера и должны быть соответствующим образом зарегистрировны в сервере (в login.conf и domain.xml). Приложение выбирает realm по имени через web.xml.
Приложение определяет набор ограничений на доступ к своим ресурсам через web.xml и указывает: какие веб-реурсы (по шаблону URL (url pattern)) могут быть доступны для каких видов запросов (get, post, head, etc) и для каких ролей. Кроме того, приложение определяет способ авторизации. Например, можно указать страницу логина или задать использование стандартной HTTP-авторизции (браузер показывает окно авторизации).
За выполнением ограничений средит веб-контейнер, так что приложению не требуется выполнять дополнительные проверки. Поскольку ограничения накладываются на шаблон URL, то не имеет значения что подпадает под этот шаблон, будь то сервлет, JSP или же даже ничего (404). Даже если ничего (404), а ограничение требует наличия у пользователя некоторой роли, то ему придётся пройти авторизацию для того чтобы увидеть, что там ничего нет.
Каждый realm может быть ассоциирован с каким-нибудь Login Module. Для этого, в свойствах (properties) для него указывает специальная пара «jaas-context» -> «login-module-name». Иногда Realm и Login Module работают только в паре. Например, если мы захотим написать свой Login Module и Realm, то вполне возможно захочется чтобы наш Realm мог работать только с нашим же Login Module и ни с каким другим.
Для примера создадим простую пару для авторизации по паролю.
Начнём с написания Realm’а:
public class TestRealm extends AppservRealm { @Override public String getAuthType() { return "magic"; } @Override public Enumeration getGroupNames( String string ) throws InvalidOperationException, NoSuchUserException { return Collections.enumeration( Arrays.asList( "users", "guests" ) ); } @Override protected void init( Properties props ) throws BadRealmException, NoSuchRealmException { super.init( props ); System.err.println( "Realm:: Hello!!" ); if( props.containsKey( JAAS_CONTEXT_PARAM ) ) setProperty( JAAS_CONTEXT_PARAM, props.getProperty( JAAS_CONTEXT_PARAM ) ); } @Override public AuthenticationHandler getAuthenticationHandler() { return null; } }
Метод getGroupNames возвращает enum с возможными группами. Метод init вызывается при инициализации (по факту — при старте домена). В нём мы можем выполнить требуемую инициализацию (например, достать необходимые паретры из props, а затем куда-то сохранить их для последующего использования). Очень важно не забыть передать свойство JAAS_CONTEXT_PARAM («jaas-context»), иначе реальм не будет работать.
Далее, опишем наш Login Module. Будем использовать авторизацию по паролю.
public class TestLoginModule extends AppservPasswordLoginModule { @Override protected void authenticateUser() throws LoginException { if( _username == null || _password == null ) throw new LoginException( "Username of password is null" ); if( "user".equals( _username ) && "user-pass".equals( _password ) ) commitUserAuthentication( new String[]{ "users" } ); else if ( "guest".equals( _username ) && "guest".equals( _password ) ) commitUserAuthentication( new String[]{ "guests" } ); else throw new LoginException( "bad login/password" ); } }
В этом примере мы просто «забили» варианты паролей. Вместо этого можно было бы «спросить» у БД или у LDAP-сервера, а может, даже, и то, и другое.
После сборки получим простой jar с двумя классами (для успешной сборки в classpath надо иметь javaee.jar, appserv-rt.jar и appserv-ext.jar и директории glassfish-v2/lib).
После сборки, наш jar можно положить, например, в директорию lib домена.
Далее, Realm и Login Module следует зарегистрировать в домене.
Для начала, надо позаботиться о том, чтобы наш .jar был в classpath сервера. Вероятно, существует неколько способов это сделать надлежащим образом, однако, в документации по теме описывается один конкретный, вот его-то мы и будем использовать.
В файле domain.xml среди всего прочего описываются параметры jvm. Там можно найти тэг java-config. У него есть аттрибут classpath-suffix. Обычно он пуст. Вот туда-то нам и надо «вписаться».
Например:
... <java-config classpath-suffix="/home/cy6ergn0m/.domains/domain1/lib/MyTestRealm.jar" ... ....
После этого, надо добавить наш Login Module. Это делается в текстовом файле login.conf в директории домена (domain_dir/conf/login.conf). Можно просто дописать в конец, например, так:
testRealmLM { cy6ergn0m.auth.TestLoginModule required; };
Когда метод логина описан, можно зарегистрировать наш именованный Realm. Его можно добавить в domain.xml или через web admin console. Мы сделаем это через domain.xml.
Среди тэгов верхнего уровня можно найти тэг security-service. Обычно в нём уже есть несколько тэгов auth-realm. Мы добавим туда же и свой. Однако, важно, чтобы наш тэг был после auth-realm’ов, которые уже есть, т.к. схема domain.xml требует, чтобы auth-realm’ы были в начале.
<auth-realm classname="cy6ergn0m.auth.TestRealm" name="testRealm"> <property name="jaas-context" value="testRealmLM"/> <property name="auth-type" value="magic"/> </auth-realm>
Среди параметров (properties) мы можем передать и другие. Эти свойства потом попадают в метод init нашего Realm’а. Сюда мы можем положить, например, адреспорт сервера или ещё какие-то настройки.
Следует также заметить, что можно создать несколько реалмов, но с разными параметрами. Login Module в свою очередь всегда может узнать, который из реалмов его использует с помощью protected-поля _currentRealm. Также, таким способов он может получить у реалма какие-то специфичные настройки (хост, порт, и т.п.).
Теперь, следует перезапутить домен. При старте домена в логе мы сможем увидеть нашу запись: «Realm:: Hello!!». Если этого не произошло, то скорее всего вы что-то сделали неверно.
Итак, наш модуль авторизации готов к употреблению. Попробуем воспользоваться им.
Для этого напишем крошечное web приложение, которое будет использовать наш модуль.
Создадим несколько web-страниц, для начала сделаем три: index.html, secret.html и for-guests.html.
Сделаем ссылки с index.html на остальные две.
После этого, создадим ограничения на доступ к нашим «страшно секретным» страницам. Для этого придётся редактировать файлы web.xml и sun-web.xml.
Наш модуль авторизации умеет авторизовать пользователей двух групп: «user» и «guest. Давайте создадим две роли соответствующие этим группам.
Откроем файл sun-web.xml и добавим эти соотношения. Для этого, добавим в него две секции <security-role-mapping>:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 Servlet 2.5//EN" "http://www.sun.com/software/appserver/dtds/sun-web-app_2_5-0.dtd"> <sun-web-app error-url=""> <context-root>/TestRealmClient</context-root> <security-role-mapping> <role-name>user</role-name> <group-name>users</group-name> </security-role-mapping> <security-role-mapping> <role-name>guest</role-name> <group-name>guests</group-name> </security-role-mapping> <class-loader delegate="true"/> <jsp-config> <property name="keepgenerated" value="true"> <description>Keep a copy of the generated servlet class' java code.</description> </property> </jsp-config> </sun-web-app>
Теперь опишем те роли, которые хотим использовать в web.xml:
<security-role> <description/> <role-name>user</role-name> </security-role> <security-role> <description/> <role-name>guest</role-name> </security-role>
Теперь можно создавать ограничение (constraint). Для этого исправим web.xml и добавим в него ограничения:
<security-constraint> <display-name>Constraint1</display-name> <web-resource-collection> <web-resource-name>secrets</web-resource-name> <description/> <url-pattern>/secret*</url-pattern> </web-resource-collection> <auth-constraint> <description/> <role-name>user</role-name> </auth-constraint> </security-constraint> <security-constraint> <display-name>Constraint2</display-name> <web-resource-collection> <web-resource-name>guests</web-resource-name> <description/> <url-pattern>/for-guests*</url-pattern> </web-resource-collection> <auth-constraint> <description/> <role-name>guest</role-name> <role-name>user</role-name> </auth-constraint> </security-constraint>
Таким образом мы определили, что доступ к страницам /secret* будет только для пользователей с ролью user, а адреса /for-guests* для пользователей с ролями user и guest. Это означает, что пользователь с ролью user может посещать все страницы, пользователь с ролью guest только index.html и for-guests.html, а „никто“ — только index.html.
Теперь мы должны указать realm и способ авторизации. Для начала выберем простой способ (HTTP-авторизация) — BASIC. Для этого в web.xml укажем:
<login-config> <auth-method>BASIC</auth-method> <realm-name>testRealm</realm-name> </login-config>
Таким образом, в конце у нас получится следующий web.xml:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <session-config> <session-timeout> 30 </session-timeout> </session-config> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> <security-constraint> <display-name>Constraint1</display-name> <web-resource-collection> <web-resource-name>secrets</web-resource-name> <description/> <url-pattern>/secret*</url-pattern> </web-resource-collection> <auth-constraint> <description/> <role-name>user</role-name> </auth-constraint> </security-constraint> <security-constraint> <display-name>Constraint2</display-name> <web-resource-collection> <web-resource-name>guests</web-resource-name> <description/> <url-pattern>/for-guests*</url-pattern> </web-resource-collection> <auth-constraint> <description/> <role-name>guest</role-name> <role-name>user</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>BASIC</auth-method> <realm-name>testRealm</realm-name> </login-config> <security-role> <description/> <role-name>user</role-name> </security-role> <security-role> <description/> <role-name>guest</role-name> </security-role> </web-app>
В редакторе web.xml в netbeans это будет выглядеть следующим образом:
Готово. Теперь приложение можно запустить и проверить. При попытке перейти по одной из ссылок возникнет окно авторизации.
Давайте усложним задачу. Допустим, мы хотим сами сделать свою собственную страницу логина.
Достичь этого мы можем двумя способами. Расмотрим оба.
Для начала мы должны изменить способ авторизации в web.xml. Ранее вы указывать метод авторизции BASIC. Теперь мы выберем логин-форму.
<login-config> <auth-method>FORM</auth-method> <realm-name>testRealm</realm-name> <form-login-config> <form-login-page>/login.jsp</form-login-page> <form-error-page>/login.jsp?fail</form-error-page> </form-login-config> </login-config>
Теперь создадим форму логина login.jsp согласно первому способу, более простому:
<%@page contentType="text/html" pageEncoding="windows-1251"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1251"> <title>JSP Page</title> </head> <body> <h1>Hello World!</h1> <h2>Web container's login method</h2> <form action="j_security_check" method="post"> <input type="text" name="j_username" /> <input type="password" name="j_password" /> <input type="submit" /> </form> </body> </html>
Готово. Теперь, когда неавторизованный пользователь будет пытаться пройти на „защищённые“ страницы, веб-контейнер будет „редиректить“ его на нашу форму логина. После авторизции пользователь получит необходимые роли и сможет посещать „защищённые“ страницы.
В некоторых случаях нам нужем больший контроль за процессом авторизации и какой-то неконтролируемый нами j_security_check нас не устраивает. В таком случае, мы всегда можем воспользоваться вторым способом. Мы можем вручную выполнить логин. Поскольку Glassfish использует нестандартный логин-модуль (не случайно мы реализовывали AppservPasswordLoginModule вместо стандартного JAAS интерфейса), то мы не можем воспользоваться обычным путём авторизации через LoginContext, а должны использовать нестандартное API сервера (точнее можем, но это сложнее и всё равно непереносимо).
Мы создадим LoginServlet, который будет использовать ProgrammaticLogin из API Glassfish’а [7]. Следует обратить внимание, что для того, чтобы класс бы виден, необходимо добавить файлы javaee.jar, appserv-rt.jar и appserv-ext.jar в classpath при сборке (и в вашей IDE, что возможно одно и то же).
public class LoginServlet extends HttpServlet { @Override protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { response.sendError( HttpServletResponse.SC_FORBIDDEN ); } @Override protected void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { ProgrammaticLogin pl = new ProgrammaticLogin(); try { Boolean rc = pl.login( request.getParameter( "name"), request.getParameter( "pass"), "testRealm", request, response, true ); if( rc != null && rc.booleanValue() ) { response.sendRedirect( "index.jsp" ); return; } } catch( Exception ex ) { Logger.getLogger( LoginServlet.class.getName() ).log( Level.SEVERE, null, ex ); } response.sendRedirect( "login.jsp?fail" ); } @Override public String getServletInfo() { return "Login servlet"; } }
А страница login.jsp изменим соответственно так, чтобы параметры формы направляли в LoginSerlvet
<%@page contentType="text/html" pageEncoding="windows-1251"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1251"> <title>JSP Page</title> </head> <body> <h1>Hello World!</h1> <h2>Web container's login method</h2> <form action="login" method="post"> <input type="text" name="name" /> <input type="password" name="pass" /> <input type="submit" /> </form> </body> </html>
Таким образом, получим сервлет логина, который можем использовать любым удобным для нас способом, например, мы можем ещё сделать „каптчу“, или проверять логин аяксом и многое другое.
В заключение хочется осветить ещё один момент. Дело в том, что регистрация Realm и Login Module не слишком простая, то хотелось бы иметь возможность автоматически регистрировать их в произвольном домене.
Для реализации задумки можно сделать свою собственную „таску“ (Custom Task) для Ant. Её можно написать на Java и выполнить все необходимые действия.
По служебному долгу пришлось написать подобную вещь, но, по понятным причинам не могу привести тут этот код. Однако, дам несколько намёков о её содержании. К файлу login.conf можно легко дописать пару строчек через FileWriter, созданный с парметром append=true. С манипуляциями над domain.xml сложнее, однако, это ведь XML, к тому же обозримого размера… стало быть, можно с помощью DocumentBuilder’а прочеть весь XML в DOM-дерево, потом внести необходимые поправки в дерево, добавить classpath-suffix и auth-realm, а потом серилизовать DOM-дерево в domain.xml обратно. У меня получилось уложиться в 200 строк вместе с проверками входных параметов. Такую таску можно включить в ant-скрипты создания всего домена (если домен создаётся ant’ом).
Несмотря на то, что тестировал я всё в glassfish v2, однако, судя по разного рода источникам, можно надеяться, что для v3 это также актуально, хотя возможно потребует корректировок.
На этом непростая статья подошла к концу. Конечно, многое осталось за кадром (privileged actions, user principals), но я надеюсь, что мне удалось пролить свет на эту непростую нишу веб-разработки.
Успехов.
CG.
Список литературы ака ссылки:
1. Authentication Using Custom Realms in Sun Java System Application Server
developers.sun.com/appserver/reference/techart/as8_authentication
2. Using JAAS with Tomcat
www.kopz.org/public/documents/tomcat/jaasintomcat.html
3. JAAS Tomcat Login Module
www.owasp.org/index.php/JAAS_Tomcat_Login_Module
4. JavaTM Authentication and Authorization Service (JAAS). LoginModule Developer’s Guide.
java.sun.com/javase/6/docs/technotes/guides/security/jaas/JAASLMDevGuide.html
5. Sun GlassFish Enterprise Server v3 Application Development Guide
Chapter 5 Securing Applications
docs.sun.com/app/docs/doc/820-7695/beabg?l=ru&q=glassfish JAAS&a=view
6. Ветка на форуме про веб-логин через j_security_check
www.sql.ru/Forum/actualthread.aspx?tid=624508
7. Javadoc Class ProgrammaticLogin
glassfish.dev.java.net/nonav/docs/v3/api
8. Sun GlassFish Enterprise Server v3 Application Development Guide
Programmatic Login
docs.sun.com/app/docs/doc/820-7695/beacm?l=ru&a=view
9. Implement JAAS based Authentication and Authorization for ADF Faces applications on OC4J 10.1.3
technology.amis.nl/blog/1426/implement-jaas-based-authentication-and-authorization-for-adf-faces-applications-on-oc4j-1013
10. Securing a Web Application on Glassfish using JAAS — Part 1 and 2
www.developinjava.com/features/47-enterprise-java/105-securing-a-web-application-on-glassfish-using-jaas.html
www.developinjava.com/features/47-enterprise-java/106-securing-a-web-application-on-glassfish-using-jaas-pt-2.html
11. Glassfish javadoc: Class AppservRealm
glassfish.java.net/nonav/javaee5/api/com/sun/appserv/security/AppservRealm.html
Проверка работоспособности
Запускаем приложение и переходим по адресу
Регистрация клиента
Первым делом зарегистрируем наше приложение в качестве клиента в Bitbucket, чтобы получить ключ (Key) и код доступа (Client Secret).
Вводим название клиента и URL обратного вызова. Затем отмечаем, что будет доступно данному клиенту.
Полученные значения Key и ClientSecret сохраняем в application.properties:
client_id=ZJsdANfWkJ7jcktw2x
client_secret=28uUrJ9m43svbkcnXVNj8qeBjFtd8jaD
Создание страниц авторизации
Выполните следующие действия:
Тестовый endpoint
Самое время создать endpoint для проверки работоспособности того, что мы только что сделали. Наш endpoint будет состоять всего из одного запроса, который будет приветствовать текущего пользователя.
Заключение
В этой статье мы продемонстрировали, как реализовать JAAS, изучив основные классы и интерфейсы и показав, как их настроить. В частности, мы внедрили модуль входа поставщика услуг .
Как обычно, код в этой статье доступен на GitHub .