Как настроить Shiro + Spring MVC, когда @Controller перенаправляет на страницу входа - PullRequest
2 голосов
/ 21 сентября 2011

У меня типичная архитектура Spring MVC + GWT с Apache Shiro в качестве уровня безопасности.

Проблема: независимо от того, какой протокол используется для запроса к серверу приложений, страницы должны возвращаться в указанном протоколев заголовке запроса «X-Forwarded-Proto» (то есть сервер приложений может получить HTTP-запрос, но если в заголовке указано HTTPS, он должен ответить с использованием HTTPS).Очевидно, что конфигурация, указанная в учебнике Shiro-Spring, не будет работать, поскольку она не имеет ничего общего с протоколами (login.jsp будет возвращен с использованием протокола, используемого в запросе):

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
  <property name="securityManager" ref="securityManager"/>
  <property name="loginUrl" value="/login.jsp"/>
  <property name="filterChainDefinitions">
    <value>
        /** = authc
    </value>
  </property>
</bean>

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
  <property name="realm" ref="myRealm"/>
</bean>

<bean id="myRealm" class="com.myapp.security.DBRealm">
   <property name="credentialsMatcher" ref="sha256Matcher"/>
</bean>

Возможное решение:

Используйте @Controller, чтобы перенаправить на страницу входа с указанным протоколом:

@RequestMapping(value="/login", method=RequestMethod.GET)
public RedirectView doLogin(HttpServletRequest req) throws MalformedURLException {
  URL originalURL = new URL(req.getRequestURL().toString());
  return new RedirectView(new URL(req.getHeader("X-Forwarded-Proto"), originalURL.getHost(), "/login.jsp").toString());
}

и изменить loginUrl в конфигурации shiro, указав на / login, чтобы @controller перехватил его:

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
  <property name="securityManager" ref="securityManager"/>
  <property name="loginUrl" value="/login"/>
  ... leave everything else the same
</bean>

Но при такой конфигурации, хотя я получаю ту же страницу входа, myRealm (com.myapp.security.DBRealm) вообще не запускается (то есть учетные данныене проверено), и вход в систему всегда не удается.Похоже, что перенаправленная страница теряет «крючок» для царства.

Есть идеи, что я делаю не так?

1 Ответ

3 голосов
/ 22 сентября 2011

Причина этого сбоя заключается в том, что фильтр Shiro authc (a FormAuthenticationFilter ) ожидает, что loginUrl будет тем, где происходит попытка входа в систему.

То естьКогда authc фильтрует запрос, соответствующий loginUrl, он автоматически поддерживает аутентификацию на основе форм.Поскольку вы перенаправляете конечного пользователя на URL-адрес, который не соответствует loginUrl (то есть loginUrl = /login, но вы перенаправляете их на /login.jsp), фильтр authc не будет выполнять вход в систему.

Ваш лучший вариант IMO:

Подкласс FormAuthenticationFilter и переопределите метод redirectToLogin для использования вашей логики X-Forwarded-Proto.Затем переопределите 'authc', чтобы он стал вашим подклассом.Например, используя shiro .ini:

    [main]
    ...
    authc = com.foo.my.FormAuthenticationFilterSubclass

Кроме того, если вы хотите, чтобы это поведение выполнялось непосредственно в Shiro (поэтому Shiro ищет этот заголовок при выполнении перенаправления по умолчанию), чтобы вы могли удалить свой подкласс, откройтезапрос функции в Apache Shiro's Jira .

...