Широ в многопоточной среде - PullRequest
7 голосов
/ 23 марта 2012

Базовый способ работы SecurityUtils.getSubject() Широ состоит в том, что он возвращает субъект, связанный с текущим выполняющимся потоком.Тем не менее, это просто противоречит контейнеру сервлетов, такому как Tomcat, который использует пул потоков для обслуживания запросов.

Если Tomcat говорит, что использует ThreadA для обработки запросов, любые вызовы SecurityUtils.getSubject() должны работать нормально.Но как только ThreadB выбран, пользователь теряется, getSubject возвращает ноль и isAuthenticated теперь ложно.Это даже если пользователь все еще вошел в систему.

Я подтвердил это в своем заявлении.Я использую Shiro Core 1.2 и замечаю, что мой пользователь просто чудесно не проходит проверку подлинности, когда я перемещаюсь по своему приложению.Если я просматриваю логи, проблема возникает, как только другой поток используется для обслуживания запроса.

Итак, я неправильно настроил Широ?Кажется, что «текущий пользователь» должен быть привязан к чему-то более долговечному, чем текущий поток.Я ожидал бы, что это будет основано на сессиях.Я знаю, что у Shiro есть управление сеансами, но во всех найденных примерах он говорит, что нужно получить текущего пользователя, вызвав getSubject, который смотрит на ThreadContext.Я что-то упустил?

1 Ответ

13 голосов
/ 23 марта 2012

Итак, получается, что я просто не правильно настроил Широ.У меня есть веб-приложение, но я настраивал Менеджер безопасности в коде.Это привело к тому, что диспетчер безопасности был настроен только для определенного потока.Пока запросы обслуживались этим же потоком, он работал нормально.Но как только Tomcat выбрал другой поток, пользователь оказался не прошедшим проверку подлинности.

Shiro имеет фильтр для веб-приложений, который обрабатывает этот сценарий и привязывает пользователя к каждому входящему запросу.Вы должны настроить свое приложение следующим образом, вместо того, чтобы делать менеджер безопасности в коде:

<context-param>
    <param-name>shiroConfigLocations</param-name>
    <param-value>classpath:auth.ini</param-value>
</context-param>

<!--  Shiro Environment Listener -->
<listener>
    <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>

<!--  Shiro Filter Configuration -->
<filter>
    <filter-name>ShiroFilter</filter-name>
    <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>ShiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
...