Статьи

Apache Shiro: безопасность приложений стала проще

Учитывая, что JAVA более 10 лет, число вариантов для разработчиков приложений, которым необходимо встроить аутентификацию и авторизацию в свои приложения, шокирующе мало.

В 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-приложение, которое выполняет некоторую аутентификацию и авторизацию. Для этого урока вам понадобятся:

  1. Апач Широ
  2. Среда разработки Java. Я использую Eclipse. Но вы также можете использовать другие IDE или инструменты командной строки.
  3. Вы можете скачать исходный код для этого примера по адресу 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

Статьи по Теме: