我有一个典型的 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/