2013-04-13 1 views
0

В частности, я нахожу, что я реализую пользовательский 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? :(
    ... 
    } 
} 

Я рассмотрел ряд возможностей:

  1. Использование кэширования область. Приложение будет работать в распределенной среде, чтобы могло быть произвольное количество запущенных JVM. Реализованные по умолчанию реализаторы диспетчера кэша хранилища не устраняют все присущие проблемы, и настройка корпоративных реализаций кажется недоступной для этого проекта.
  2. Используйте сеанс темы. Не существует состояния на стороне сервера, и я хотел бы сохранить его таким образом, если это возможно. Возможно, вы можете заставить сеанс вести себя как область запроса, но я не знаю, как это сделать, и что риски могут быть запутаны.
  3. Реализовать мой собственный предмет. Кажется, как правило, один экземпляр объекта для запроса, но неясно, как это сделать, и я рискую потерять много потенциальной функциональности.
  4. Использование объекта Shiro ThreadContext. Я мог бы привязать данные к ThreadContext как свойство threadlocal. Контейнеры с сервлетами обычно следуют модели с потоком за запрос, и сам экземпляр Subject, кажется, охлаждается здесь, ожидая его неизбежной сборки мусора. Сиро также, похоже, автоматически создает и разрушает контекст. Тем не менее, документации по этому поводу нет, и мне трудно следовать исходному коду.

И наконец, по умолчанию WebSecurityManager поддерживает одиночные экземпляры CustomRealm, по одному на JVM. Просто установка некоторого свойства локального экземпляра не является потокобезопасной.

Это похоже на общий способ поиска данных и типичный сценарий развертывания. Итак, что мне не хватает?

Спасибо!

ответ