В частности, я нахожу, что я реализую пользовательский AuthorizingRealm
, который объявляет методы шаблона doGetAuthenticationInfo()
и doGetAuthorizationInfo()
для возврата AuthenticationInfo
и AuthorizationInfo
объектов, соответственно.Как кэшировать данные только на время HTTP-запроса, используя apache shiro в контейнере сервлетов?
Однако, когда я извлекаю данные для объекта AuthenticationInfo (объект JPA) в doGetAuthenticationInfo(), я обнаружил, что у меня уже есть необходимая авторизация. Увы, нет надежного способа вставить на эти данные, поэтому я должен выбросить его только для выполнения другого поиска JPA, когда фильтр авторизации в конечном счете превратится в цепочку фильтров.
Вот:
public class CustomRealm extends AuthorizingRealm {
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) {
UsernamePasswordToken userPassToken = (UsernamePasswordToken) token;
String username = userPassToken.getUsername()
User user; // Contains username, password, and roles
// Perform JPA lookup by username...
return constructSimpleAuthenticationInfoFromUser(user);
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// Look up user again? :(
...
}
}
Я рассмотрел ряд возможностей:
- Использование кэширования область. Приложение будет работать в распределенной среде, чтобы могло быть произвольное количество запущенных JVM. Реализованные по умолчанию реализаторы диспетчера кэша хранилища не устраняют все присущие проблемы, и настройка корпоративных реализаций кажется недоступной для этого проекта.
- Используйте сеанс темы. Не существует состояния на стороне сервера, и я хотел бы сохранить его таким образом, если это возможно. Возможно, вы можете заставить сеанс вести себя как область запроса, но я не знаю, как это сделать, и что риски могут быть запутаны.
- Реализовать мой собственный предмет. Кажется, как правило, один экземпляр объекта для запроса, но неясно, как это сделать, и я рискую потерять много потенциальной функциональности.
- Использование объекта Shiro ThreadContext. Я мог бы привязать данные к ThreadContext как свойство threadlocal. Контейнеры с сервлетами обычно следуют модели с потоком за запрос, и сам экземпляр Subject, кажется, охлаждается здесь, ожидая его неизбежной сборки мусора. Сиро также, похоже, автоматически создает и разрушает контекст. Тем не менее, документации по этому поводу нет, и мне трудно следовать исходному коду.
И наконец, по умолчанию WebSecurityManager поддерживает одиночные экземпляры CustomRealm, по одному на JVM. Просто установка некоторого свойства локального экземпляра не является потокобезопасной.
Это похоже на общий способ поиска данных и типичный сценарий развертывания. Итак, что мне не хватает?
Спасибо!