В JAVA и J2EE спецификация JAAS была попыткой решить проблему безопасности. Хотя JAAS работает для аутентификации, часть авторизации слишком громоздка для использования. Спецификации EJB и Servlet предлагают грубую авторизацию на уровне метода и ресурса. Но они слишком грубые, чтобы их можно было использовать в реальных приложениях. Для пользователей Spring Spring Security является альтернативой. Но это немного сложно в использовании, особенно модель авторизации. Большинство приложений создают собственные решения для аутентификации и авторизации.
Apache Shiro — это среда безопасности JAVA с открытым исходным кодом, которая решает эту проблему. Это элегантная структура, которая позволяет с легкостью добавлять в приложение аутентификацию, авторизацию и управление сеансами.
Основные моменты Широ являются:
Это чистый Java-фреймворк. Он работает со всеми видами приложений JAVA: J2SE, J2EE, Web, автономными или распределенными.
Он может легко интегрироваться с различными репозиториями, в которых могут размещаться метаданные о пользователях и разрешениях, такими как RDBM, LDAP.
Он имеет простую и интуитивно понятную модель разрешений, которая может применяться к широкому спектру проблемных областей. Это модель, которая позволяет вам сосредоточиться на проблемной области, не увязая в фреймворке.
Он имеет встроенную поддержку управления сессиями.
Он имеет встроенную поддержку для кэширования метаданных.
Он очень легко интегрируется с Spring. То же относится и к любому серверу приложений J2EE.
Самое главное, это очень просто в использовании. В большинстве случаев все, что вам нужно будет сделать для интеграции Shiro, — это внедрить REALM, который связывает Shiro с вашими метаданными User и Permissions.
Широ Концепции
SecurityManager инкапсулирует конфигурацию безопасности приложения, использующего Shiro.
Тема — это представление времени выполнения пользователя, который использует систему. Когда тема создана, она не аутентифицируется. Для аутентификации должен быть вызван метод входа в систему с передачей правильных учетных данных.
Сеанс представляет сеанс, связанный с проверенным субъектом. Сессия имеет идентификатор сессии. Приложения могут хранить произвольные данные в сеансе. Сеанс действителен до тех пор, пока пользователь не выйдет из системы или не истечет время ожидания.
Разрешение представляет, какие действия субъект может выполнять над ресурсом в приложении. Из коробки Shiro поддерживает разрешения, представленные разделенными токенами двоеточиями. Каждый токен имеет некоторое логическое значение. Например, мое приложение может определить разрешение как ResourceType: actions: ResourceInstance. Конкретнее, File: read: contacts.doc представляет разрешение на чтение файла contacts.doc. Разрешение должно быть связано с пользователем, чтобы предоставить это разрешение пользователю.
Роль — это набор разрешений, которые могут представлять способность выполнять некоторые организационные функции. Роли делают связь между пользователями и разрешениями более управляемой.
Царство абстрагирует вашего пользователя, разрешения и метаданные роли для Широ. Вы делаете эти данные доступными для Shiro, внедряя область и подключая ее к Shiro. Типичные области используют либо реляционную базу данных, либо LDAP для хранения пользовательских данных.
Руководство
Давайте создадим простое Java-приложение, которое выполняет некоторую аутентификацию и авторизацию. Для этого урока вам понадобятся:
- Апач Широ
- Среда разработки Java. Я использую Eclipse. Но вы также можете использовать другие IDE или инструменты командной строки.
- Вы можете скачать исходный код для этого примера по адресу simpleshiro.zip
Шаг 1: Создайте файл конфигурации Shiro.ini
Мы будем использовать базовую область файлов по умолчанию, которая поставляется с Shiro. Это читает метаданные пользователя / разрешения из файла shiro.ini. В следующем уроке я покажу, как построить область, которая получает данные из реляционной базы данных.
В файле Ini давайте определим некоторых пользователей и свяжем с ними некоторые роли.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
# Simple shiro.ini file [ users ] # user admin with password 123456 and role Administrator admin = 123456, Administrator # user mike with password abcdef and role Reader mike = abcdef, Reader # user joe with password !23abC2 and role Writer joe = !23abC2, Writer # ----------------------------------------------------------------------------- # Roles with assigned permissions [roles] # A permission is modeled as Resourcetype:actions:resourceinstances # Administrator has permission to do all actions on all resources Administrator = *:*:* # Reader has permission to read all files Reader = File: read :* # Writer role has permission to read and write all files Writer = File: read ,write:* |
В вышеупомянутом shiro.ini мы определили 3 пользователей и 3 роли. Разрешение моделируется
в качестве двоеточия отделяются токены. Каждый токен может иметь несколько частей, разделенных запятыми. Каждый домен и часть предоставляет разрешение для определенного домена приложения.
Шаг 2: BootStrap shiro в ваше приложение
1
2
3
|
Factory factory = new IniSecurityManagerFactory( "classpath:shiro.ini" ); SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); |
IniSecurityManagerFactory загружает конфигурацию из shiro.ini и создает одно приложение SecurityManager для приложения. Для простоты наш shiro.ini идет с конфигурацией SecurityManager по умолчанию, которая использует область на основе текста и получает метаданные о пользователях, разрешениях и ролях из файла shiro.ini.
Шаг 3: Войти
01
02
03
04
05
06
07
08
09
10
|
Subject usr = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken( "mike" , "abcdef" ); try { usr.login(token); } catch (AuthenticationException ae) { log.error(ae.toString()) ; return ; } log.info( "User [" + usr.getPrincipal() + "] logged in successfully." ); |
SecurityUtils — это фабричный класс для получения существующего субъекта или создания нового. Учетные данные передаются с использованием AuthenticationToken. В этом случае мы хотим передать имя пользователя и пароль и, следовательно, использовать UsernamePasswordToken. Затем мы вызываем метод входа в систему для субъекта, передающего токен аутентификации.
Шаг 4: Проверьте, есть ли у пользователя разрешение
01
02
03
04
05
06
07
08
09
10
|
if (usr.isPermitted( "File:write:xyz.doc" )) { log.info(usr.getPrincipal() + " has permission to write xyz.doc " ); } else { log.info(usr.getPrincipal() + " does not have permission to write xyz.doc " ); } if (usr.isPermitted( "File:read:xyz.doc" )) { log.info(usr.getPrincipal() + " has permission to read xyz.doc " ); } else { log.info(usr.getPrincipal() + " does not have permission to read xyz.doc " ); } |
У субъекта есть метод isPermitted, который принимает строку разрешения в качестве параметра и возвращает истину / ложь.
Шаг 5: Выйти
1
|
usr.logout(); |
Метод выхода из системы выводит пользователя из системы.
Чтобы познакомиться с Широ, попробуйте изменить UsernamePasswordToken и войти под другим именем. Проверьте некоторые другие разрешения. Измените файл Shiro.ini, чтобы создать новых пользователей и роли с различными разрешениями. Запустите программу несколько раз с разными метаданными и другим вводом.
В производственной среде вам не нужны пользователи и роли в INI-файле. Вы хотите, чтобы они были в безопасном хранилище, таком как реляционная база данных или LDAP. В следующей части я покажу вам, как создать Shiro Realm, который может использовать метаданные о пользователях, ролях и разрешениях из реляционной базы данных.
Ссылка: Apache Shiro: Безопасность приложений стала проще благодаря нашему партнеру по JCG Маноджу в блоге The Khangaonkar Report
Статьи по Теме:
- Услуги, практики и инструменты, которые должны существовать в любом доме разработки программного обеспечения, часть 2
- Защита приложений GWT с помощью Spring Security
- Управление конфигурацией в Java EE
- 25 самых опасных программных ошибок — 2011
- Пример Spring MVC Interceptors
- Google ClientLogin Утилита в Java