spring-mvc - 当 @Controller 重定向到登录页面时如何配置 Shiro + Spring MVC

标签 spring-mvc http-headers spring-webflow shiro

我有一个典型的 Spring MVC + GWT 架构,并以 Apache Shiro 作为安全层。

问题: 无论使用什么协议(protocol)向应用服务器发出请求,页面都应该按照请求的“X-Forwarded-Proto” header 中指定的协议(protocol)返回(因此,应用服务器可以接收 HTTP 请求,但如果 header 显示 HTTPS ,它应该使用 HTTPS 进行响应)。显然,Shiro-Spring 教程中指定的配置不起作用,因为它与协议(protocol)无关(login.jsp 将使用请求中使用的协议(protocol)返回):

<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重定向到指定协议(protocol)的登录 View :

@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());
}

并将shiro配置中的loginUrl更改为指向/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) 根本不会触发(意味着不会检查凭据),并且登录总是失败。似乎重定向的页面失去了对该领域的“钩子(Hook)”。

关于我做错了什么有什么想法吗?

最佳答案

失败的原因是 Shiro authc 过滤器(a FormAuthenticationFilter )期望 loginUrl 是发生登录尝试的位置。

即当authc过滤出与loginUrl匹配的请求时,会自动支持基于表单的认证。因为您将最终用户重定向到与 loginUrl 不匹配的 URL(即 loginUrl=/login,但您将它们重定向到/login.jsp),authc 过滤器不会执行登录。

我认为你最好的选择:

子类 FormAuthenticationFilter 并重写 redirectToLogin 方法以使用您的 X-Forwarded-Proto 逻辑。然后将“authc”重新定义为您的自定义子类。例如,使用shiro.ini:

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

此外,如果您希望直接在 Shiro 中实现此行为(因此 Shiro 在默认情况下执行重定向时会查找该 header )以便可以删除您的子类,请在 Apache Shiro's Jira 中打开功能请求.

关于spring-mvc - 当 @Controller 重定向到登录页面时如何配置 Shiro + Spring MVC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7502837/

相关文章:

spring - 如何将 Spring HATEOAS "linkTo"与 Kotlin DSL 一起使用?

http - 我需要 Content-Type : application/octet-stream for file download? 吗

grails - grails Webflow请求的资源不可用

spring-webflow - Spring Webflow,从任意子流返回主流

java - 从 Spring 3.1.9 迁移到 Spring 4.2.4 时,@Autowired 不起作用。但适用于 Spring 3 和 Java7

java - 下面的 SpEL 表达式到底做什么?

java - 将excel读入java - 如何简化

javascript - 加载可能重定向到 HTTP 的 HTTPS 图片 url

javascript - HTTP header 使浏览器显示 "save as"对话框并保存文件

java - Spring/Webflow 验证问题