shiro登陆后没有返回设置的successUrl

今天做项目的时候,发现使用shiro时候,session失效后shiro配的successUrl不生效的问题。

<!-- web.xml中shiro的filter对应的bean -->
	<!-- Shiro 的Web过滤器 -->
	<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<!-- 注入securityManager的bean -->
		<property name="securityManager" ref="securityManager"></property>
		<!-- loginUrl认证提交地址,如果没有认证将会请求此地址进行认证,请求此地址将由formAuthenticationFilter进行表单认证 -->
		<property name="loginUrl" value="/login/userlogin.do"></property>
		<!-- 认证成功统一跳转url,不配置shiro认证成功自动跳转到上一个请求路径 -->
		<property name="successUrl" value="/main/index.do"></property>
		<!-- 通过unauthorizedUrl 制定没有权限操作时跳转页面 -->
		<property name="unauthorizedUrl" value="/refuse.jsp"></property>
		<!-- 过滤器链定义,从上向下顺序执行,一般将/**放在最下边 -->
		<property name="filterChainDefinitions">
			<value>
				<!-- 对静态资源设置匿名访问 -->
				/img/** = anon

经过上网查询:

原因一:http://www.cnblogs.com/yeming/p/5480639.html

原因二:http://www.bubuko.com/infodetail-1421844.html (有源码解释)


粘贴原因一内容:

用上面的配置会有这样的情况:


  1.如果是访问其他已存在的页面被拦截到登录页面,登录后就会跳转到之前的页面。


  2.如果是直接访问登录页面或者是通过退出登录到登录页面,再次登录就会跳转到“/”。


  3.不管怎么样,都没有跳转到successUrl指定的url。



原因是这样的:


  successUrl配置只是做为一种附加配置,只有session中没有用户请求地址时才会使用successUrl。系统默认的是认证成功后跳转到上一次请求的路径,如果是首次请求,那shiro就会跳转到默认虚拟路径“/”,也就是跳转到index.jsp。


解决方法:


  简单一点的话就可以直接在index.jsp里面把请求重定向到你指定的页面


粘贴原因二内容:

做项目的时候,特别是当访问的url是iframe的页面的时候,session又过期了,跳转到登陆页,完成登陆操作后,返回了只有iframe的页面,相当不好看。虽然在shiro里设

置了successUrl,但是没有起作用。

debug后跟进去观察后发现FormAuthenticationFilter成功登陆后,会调用它的onLoginSuccess方法,最后会调用下面这个实际执行的方法

	WebUtils.redirectToSavedRequest(request, response, getSuccessUrl());
这个方法实际做什么了。

public static void redirectToSavedRequest(ServletRequest request, ServletResponse response, 
 String fallbackUrl)throws IOException {
        String successUrl = null;
        boolean contextRelative = true;
        SavedRequest savedRequest = WebUtils.getAndClearSavedRequest(request);
        if (savedRequest != null && 
      savedRequest.getMethod().equalsIgnoreCase(AccessControlFilter.GET_METHOD)){
            successUrl = savedRequest.getRequestUrl();
            contextRelative = false;
        }

        if (successUrl == null) {
            successUrl = fallbackUrl;
        }

        if (successUrl == null) {
            throw new IllegalStateException(".....");
        }

        WebUtils.issueRedirect(request, response, successUrl, null, contextRelative);
    }


可以看出如果由之前的页面跳转到登陆页的话,savedRequest保存了原来的地址,这个地址会取代我们设置的successUrl;只有当savedRequest为null的时候,

successUrl才会是我们设置的地址。

好了,那我们要怎么做避免它返回页面,只返回到我们指定的页面呢?如果要我选的话,我会选择继承FormAuthenticationFilter并重写父类的方法AuthenticationFilter的

issueSuccessRedirect方法,最后差不多就是

package util.shrio;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;

/**
 * @Description	MyFormAuthenticationFilter 自定义session失效跳转页面
 * @Date		2017年9月18日 下午4:48:03
 */
public class MyFormAuthenticationFilter extends FormAuthenticationFilter {

	// 制定session跳转url
	private final String successUrl = "/main/index.do";
	
	@Override
	protected void issueSuccessRedirect(ServletRequest request, ServletResponse response) throws Exception {
		WebUtils.issueRedirect(request, response, successUrl, null, true);
	}

	
	
}
在原来的配置上增加:

<!-- web.xml中shiro的filter对应的bean -->
	<!-- Shiro 的Web过滤器 -->
	<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<!-- 注入securityManager的bean -->
		<property name="securityManager" ref="securityManager"></property>
		<!-- loginUrl认证提交地址,如果没有认证将会请求此地址进行认证,请求此地址将由formAuthenticationFilter进行表单认证 -->
		<property name="loginUrl" value="/login/userlogin.do"></property>
		<!-- 认证成功统一跳转url,不配置shiro认证成功自动跳转到上一个请求路径 -->
		<property name="successUrl" value="/main/index.do"></property>
		<!-- 通过unauthorizedUrl 制定没有权限操作时跳转页面 -->
		<property name="unauthorizedUrl" value="/refuse.jsp"></property>
		<!-- 自定义filter配置 -->
		<property name="filters">
			<map>
				<!-- 将自定义 的FormAuthenticationFilter注入shiroFilter中-->
				<entry key="authc" value-ref="filterPages" />
			</map>
		</property>
		<!-- 过滤器链定义,从上向下顺序执行,一般将/**放在最下边 -->
		<property name="filterChainDefinitions">
			<value>
				<!-- 对静态资源设置匿名访问 -->
				/img/** = anon
<!-- session失效配置自定义路径 -->
	<bean id="filterPages" class="util.shrio.MyFormAuthenticationFilter"/>

以上 就是解决办法,推荐第二种。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值