shiro登录成功后没有正确跳转

本文介绍了解决Shiro框架登录成功后未能正确跳转的问题。详细解释了Shiro如何保存请求并使用保存的请求来重定向,以及如何通过自定义过滤器确保跳转至预期页面。

最近遇到shiro校验框架成功后不进行自动跳转到指定页面;

相关配置如下:

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


我使用的是验证过滤器是authc;逻辑上只要登录成功即可跳转至“/user/center”,

实际上不行老是跳转到xxx.js,xxx.ico等等,而且每次都不固定;

主要原因是successUrl配置只是做为一种附加配置,只有session中没有用户请求地址时才会使用successUrl;

系统默认登录成功后首次跳转的地址为,访问系统时初次使用地址,例:如果用户首次访问的是http://****/aa/aa.html; 

 那么shiro校验成功后跳转的地址即可http://****/aa/aa.html; 否则shiro将跳转到默认虚拟路径:“/”;

对于应用中,如果没有注册/路径,则默认使用web.xml中配置的<welcom-list>配置;

shiro源码逻辑如下:

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("Success URL not available via saved request or via the " +
                    "successUrlFallback method parameter. One of these must be non-null for " +
                    "issueSuccessRedirect() to work.");
        }

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

上述代码红色部分表明,对于成功后地址指向,会依据会话SESSION中保留的请求地址;

解决办法: 

如果shiroFilter能够修改为拦截指定扩展名(如:*.do)的话,最好修改为用扩展名拦截,这样避开一些资源文件.

如果是用rest风格拦截("/"),则需要修改认证的filter,具体做法:复写FormAuthenticationFilter中的onLoginSuccess为:

WebUtils.issueRedirect(request, response, getSuccessUrl());

return false;

注意:对应的跳转地址应该在相应的mvc框架中配置好

/static/** = anon
### Shiro 前后端分离登录成功后的页面跳转实现 在前后端分离架构中,传统的服务器端重定向不再适用。取而代之的是,在客户端接收到成功的响应后由前端路由来处理页面跳转。 #### 修改Shiro的默认行为 为了适应前后端分离的需求,需要调整Shiro的行为使其不执行重定向而是返回JSON格式的消息给前端[^1]: ```java // 自定义过滤器继承原有认证过滤器并覆盖onLoginSuccess方法 public class CustomFormAuthenticationFilter extends ShiroFormAuthenticationFilter { @Override protected boolean onLoginSuccess(AuthenticationToken token, ServletRequest request, ServletResponse response) throws Exception { HttpServletResponse httpResponse = WebUtils.toHttp(response); httpResponse.setContentType("application/json;charset=utf-8"); PrintWriter out = httpResponse.getWriter(); Map<String,Object> resultMap=new HashMap<>(); resultMap.put("status",200); // 或者其他状态码表示成功 resultMap.put("msg","登录成功!"); out.write(new ObjectMapper().writeValueAsString(resultMap)); out.flush(); out.close(); return false; } } ``` 此代码片段展示了如何创建一个自定义的身份验证过滤器`CustomFormAuthenticationFilter`,该过滤器扩展了原有的`ShiroFormAuthenticationFilter`类,并覆写了`onLoginSuccess()`函数以改变其默认行为——不是进行HTTP重定向,而是向客户端发送带有消息体的成功响应[^2]。 #### 客户端逻辑 对于前端部分,则需监听API调用的结果来进行相应的导航动作。这里给出Vue.js环境下的例子[^3]: ```javascript methods: { login() { axios({ method:'post', url:'/api/login', data:{ username:this.username, password:this.password } }).then((response)=>{ let res=response.data; if(res.status==200){ localStorage.setItem('token',res.token); //假设服务端会回传token用于鉴权 this.$router.push({path:'/home'}); // 使用vue-router进行内部路径切换 }else{ alert(`Error:${res.message}`); } }); }, logout(){ axios.post('/wt/user/logout') .then(({data})=>{ if(data.code===2000){ sessionStorage.removeItem("token"); this.$router.push("/login"); } else { this.$message.error(data.msg); } }) } } ``` 上述JavaScript代码实现了两个功能:一是提交表单数据至后端完成身份验证;二是登出时清除存储于浏览器中的令牌信息并将用户导向登录界面。一旦登录请求得到正面反馈(即状态码为200),则保存来自服务器端分配的安全令牌,并利用前端路由器将应用内视图转向主页或其他指定位置。 #### JSON响应代替重定向 针对无权限访问资源或未登录情况,应确保这些场景同样返回结构化的JSON对象而不是尝试做任何类型的重定位操作。这可以通过配置全局异常处理器或者特定控制器内的错误捕捉机制达成目的[^4]。 #### 利用JWT简化流程 考虑到用户体验以及安全性考量,可以考虑采用基于JSON Web Token(JWT)的方式管理用户的在线状态。每次成功登录后生成签名过的JWT并发还给客户机作为凭证携带在后续请求头里。这样做的好处在于减少了频繁查询数据库的压力同时也方便实施诸如记住我的特性[^5]。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值