loginUrl:只要请求资源任何位置的一个未经认证的用户请求,都会被拦截并统一进入loginUrl配置的路径进行认证。
successUrl:是用户认证通过后将要跳转的请求或者资源位置,通常不用配置,认证通过以后会自动跳转进入上一次请求的路径。
比如:第一次请求路径为:localhost:8080/LZB/login.action,这时候因为用户没有认证,所以会拦截到登录页面:localhost:8080/LZB/login.jsp(也就是loginUrl配置的路径进行认证)进行登录认证,那么认证通过后会自动跳转上一次的请求路径,也就是再次请求localhost:8080/LZB/login.action。而这时候认证通过了,所以请求不会被拦截。
但是有时候我们想认证成功后直接跳进指定的位置,比如首页,这时候successUrl配置了但却不起作用,这是因为successUrl会根根据session存储的信息进行跳转,只要你请求被拦截了,session中的successUrl就会记住拦截之前上一次请求的路径信息,那么就会直接使用session里存储的上一次的路径信息。而不会使用我们在xml文件中配置的successUrl配置的信息。
解决办法一:请求直接请求项目名称,后面不要加任何的资源位置,这时候配置successUrl=/index.jsp,在项目根路径下新建index.jsp,请求认证完成后,由于上一次请求的资源名是项目根路径,web.xml欢迎页面会定位到index.jsp,这时候在index.jsp中直接跳转进项目首页的位置即可。
解决办法二:利用shiro定义的配置,直接规定请求地址为项目首页的位置,认证成功后会再次自动请求首页位置。
解决办法三(推荐):
自定义loginFormAuthenticationFilter,继承FormAuthenticationFilter。并重写方法
protected void issueSuccessRedirect(ServletRequest request, ServletResponse response) throws Exception {
WebUtils.issueRedirect(request, response, successUrl, null, true);
}
我们将原始的successUrl写死,例如:private final String successUrl = "/AdminController/loginSuccess.action";
这时候认证成功后就会使用重写的successUrl信息。而不是session里存储的successUrl。
然后通过<bean id="loginFormAuthenticationFilter" class="com.gjc.util.loginFormAuthenticationFilter"/>注入到容器
最后通过<!-- 自定义filter配置 -->
<property name="filters">
<map>
<!-- 将自定义 的loginFormAuthenticationFilter注入shiroFilter中,并赋予authc权限-->
<entry key="authc" value-ref="filterPages" />
</map>
</property>
解决办法四:网上说有一种办法是认证成功后清除session信息,这时候系统就会使用我们在xml中配置的successUrl,但是清除session信息跳转进首页以后,我们需要通过自定义代码将用户身份信息重新存储到session域对象中,以便后续使用。这样就失去了shiro的便捷性的意义。
本人学生一枚,最近在学习shiro框架遇到的问题,如果哪位有更好的解决办法,欢迎交流,本人水平有限,不足之处,还请多多包涵!