V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
jiobanma
V2EX  ›  程序员

SpringMVC,redirect 重定向的问题

  •  
  •   jiobanma ·
    banmajio · 2021-10-13 09:47:50 +08:00 · 1724 次点击
    这是一个创建于 897 天前的主题,其中的信息可能已经有所发展或是发生改变。
    • 老系统是 SpringMVC 集成 shiro 做的权限认证。现在要改为集团统一认证。

    • 流程为:访问域名->跳转到登录接口->判断是否登录->跳转集团登录页->登录成功后 return 回来我们的系统首页。

    • 遇到的问题:集团登录页是个 https 的链接。登录的 Controller 最后==return "redirect:" + targetUrl;==。但是 targetUrl 改为http就可以正常跳转,如果是https虽然不影响使用,但是会一直重复调用 login 的接口。

    • 尝试使用 http://www.baidu.comhttps://www.baidu.com 也是一样的情况。现在不清楚问题到底是shiro引发的?还是SpringMVCredirect引发的。奇怪的是退出的接口不管是 http 还是 https 都是正常的。

    • 相关代码放到下面了,有懂得大手子麻烦帮忙看下给点建议!!!

    // 登录接口
    @RequestMapping(value = "${adminPath}/login", method = RequestMethod.GET)
        public String e2Login(HttpServletRequest request,
                              HttpServletResponse response, Model model) {
            User user = UserUtils.getUser();
            // 如果已经登录,则跳转到管理首页
            if (user != null) {
                if (user.getId() != null && user.getId() > -1) {
                    return "redirect:" + Global.getAdminPath();
                } else {
                    return "error/403";
                }
            } else {
                String e2state = java.util.UUID.randomUUID().toString();
                X3.Service.X3App x3app = new X3.Service.X3App(request, response);
                x3app.SetCookie("e2state", e2state);
                String targetUrl = Global.getConfig("e2.LoginUrl") + "?client_id="
                        + Global.getConfig("e2.ClientId")
                        + "&returnUrl="
                        + Global.getConfig("e2.ReturnUrl");
                model.addAttribute("targetUrl", targetUrl);
                return "redirect:" + targetUrl;
            }
        }
        
    
    // 退出接口
       @RequestMapping(value = "/logout")
        public String adminLogout(HttpServletRequest request,
                                  HttpServletResponse response) {
            logger.info("======================= logout====================");
            X3App app = new X3App(request, null);
            Subject subject = SecurityUtils.getSubject();
            subject.getSession().removeAttribute(app.GetCookie("e2state"));
            String returnUrl = WebUtilX.UrlEncode(Global.getConfig("u2.Callback"));
    
            String logoutUrl = Global.getConfig("u2.LogoutUrl") + "?ClientId="
                     + Global.getConfig("u2.ClientId") + "&ReturnUrl=" + returnUrl;
    
            String returnUrl = WebUtilX.UrlEncode(Global.getConfig("e2.ReturnUrl"));
            String logoutUrl = Global.getConfig("e2.LogoutUrl") + "?ClientId="
                    + Global.getConfig("e2.ClientId") + "&ReturnUrl=" + returnUrl;
            subject.logout();
            return "redirect:" + logoutUrl;
        }
    
    // shiro 过滤器
     <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <property name="securityManager" ref="securityManager"/>
            <property name="loginUrl" value="${adminPath}/login"/>
            <property name="successUrl" value="/index"/>
            <property name="filters">
                <map>
                    <entry key="authc" value-ref="formAuthenticationFilter"/>
                    <entry key="oauth2Authc" value-ref="oAuth2AuthenticationFilter"/>
                </map>
            </property>
            <property name="filterChainDefinitions">
                <value>
                    /report/postContent/** = anon
                    /studentlist/** = anon
                    /courseInfo/** = anon
                    /studyInfo/** = anon
                    /studyservice/** = anon
                    /newwork/** = anon
                    /workflow/** = anon
                    /static/** = anon
                    /userfiles/** = anon
                    /servlet/** = anon
                    /app/**=anon
                    /demo/**=anon
                    ${adminPath}/login = authc
                    /e2/callback = oauth2Authc
                    /admin = anon
                    ${adminPath}/logout = authc
                    /** = user
                </value>
            </property>
        </bean>
    
    16 条回复    2021-10-14 09:17:03 +08:00
    chendy
        1
    chendy  
       2021-10-13 09:55:20 +08:00
    貌似之前发过一次?
    一直重复调用 login 的接口 是啥意思?循环重定向直到浏览器报错?
    zhangchongjie
        2
    zhangchongjie  
       2021-10-13 09:59:58 +08:00
    死循环了吧,http 跳 https 或者反过来。都可能会出现问题哦
    jiobanma
        3
    jiobanma  
    OP
       2021-10-13 10:02:21 +08:00
    @chendy 昨天发过一次,没什么回应,这次我写的详细了些。重复调用就是 login 接口一直再调用,浏览器没有报错,好像系统也是可以正常访问的,但是控制台一直再打印 login 接口的内容。
    jiobanma
        4
    jiobanma  
    OP
       2021-10-13 10:04:05 +08:00
    @zhangchongjie 会和我 tomcat 配置有关系吗? 因为本地测得,没有域名,所以我 tomcat 配的是 80 端口,然后改 host:127.0.0.1 指定了一个域名。来使访问域名可以进入系统,登录完之后,returnUrl 可以跳回到系统。
    devswork
        5
    devswork  
       2021-10-13 10:05:38 +08:00
    浏览器 console 是否是一直发起 login 请求?先看看请求是哪里来的
    jiobanma
        6
    jiobanma  
    OP
       2021-10-13 10:28:16 +08:00
    @devswork 没法使用 console,服务一启动,login 接口就在一直重复调用了,浏览器不弹东西的,这时候访问域名可以正常使用的。我怀疑是不是 shiro 的问题,redirect 这个 https 失败 所以一直在调用。https://aaaaaa.xx.cn/e2/qr?client_id=00000&returnUrl=http://bbb.xx.cn/e2/callback redirect 的是这个链接,这是一个集团那边的登录页,登陆成功后 会 returnUrl 到 bbb.xx.cn 这是我们系统的域名。 难道是因为我们系统域名是 http 或者 我 tomcat 配置 80 和 host 导致的?
    sunjiayao
        7
    sunjiayao  
       2021-10-13 13:20:45 +08:00
    看下浏览器的 cookie/storage 。http 请求登陆存的 token 。调用 https 接口应该是取不到。抓包对比下 301 后请求的 http https 的 header
    devswork
        8
    devswork  
       2021-10-13 13:38:12 +08:00
    改为 http 就可以正常跳转,如果是 https 就重复 login,退出的接口不管是 http 还是 https 都是正常的。
    从上面两点,我感觉不像 https 的事,像是没有获取到登录状态,导致跳转登录(你这里是重复调用 login ),跟这个登录逻辑有关(未获取到登录状态、登录状态有误导致尝试去登录这类问题)
    pengtdyd
        9
    pengtdyd  
       2021-10-13 13:50:38 +08:00
    if (user.getId() != null && user.getId() > -1) { 这一行为什么 user 的 id 能等于 null ?你们这个 user 的表还有这种设计吗
    jiobanma
        10
    jiobanma  
    OP
       2021-10-13 15:37:38 +08:00
    @pengtdyd 老代码这么写的,可能是为了处理异常情况吧
    @devswork 正常来说不就是没有登录的时候才会跳转登录页吗
    @sunjiayao 没太懂啥意思
    DavidDee
        11
    DavidDee  
       2021-10-13 16:08:47 +08:00
    感觉是 jeesite...
    liyunyang
        12
    liyunyang  
       2021-10-13 16:36:45 +08:00
    1 、是否有配置 http 重定向 https
    2 、如果是 shrio 的问题,查看一下源码,看一下调用链
    题外话,使用 301 永久重定向会怎么样,或者换一个调整页面的方式?
    uCharles
        13
    uCharles  
       2021-10-13 16:40:11 +08:00
    @DavidDee 据说此框架假开源
    ily433664
        14
    ily433664  
       2021-10-13 16:42:42 +08:00
    检查一下 User user = UserUtils.getUser();的逻辑,感觉像是登录成功了,但是判断逻辑有问题,导致来回跳转
    ily433664
        15
    ily433664  
       2021-10-13 16:44:57 +08:00
    另外你贴的是判断登录跳转的逻辑,检查一下执行登录流程的逻辑
    jiobanma
        16
    jiobanma  
    OP
       2021-10-14 09:17:03 +08:00
    @chendy
    @zhangchongjie
    @devswork
    @sunjiayao
    @pengtdyd
    @sugz
    @liyunyang
    @ily433664
    谢谢大家,破案了,把 idea 的 tomcat 配置。after launch 的勾选去掉就没问题了 可能是因为 tomcat 里配的是 localhost,而本地是改了 host 指向了域名两边不一致导致的,具体为什么会这样还不清楚,不过程序可以正常跑了!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3089 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 12:51 · PVG 20:51 · LAX 05:51 · JFK 08:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.