微服务使用openfeign调用单点的会话失效问题

服务,使用,openfeign,调用,单点,失效,问题 · 浏览次数 : 12

小编点评

## Analysis of the Problem The problem seems to be related to the authentication process between Fegin and the SSO server. The issue arises when Fegin calls the server, but the Cookie sent by the SSO server is not recognized or is not included in the Request header. ## Root Cause Analysis 1. **Multiple Client Applications:** Each microservice can register and use its own `stpUtil.isLogin()` method, potentially with different configurations. 2. **SSO Cookie:** When the user authenticates through the SSO server, an authentication cookie is set in the user's browser. 3. **Fegin Interceptor:** The interceptor handles the Fegin request and retrieves the Cookie from the request header. 4. **Missing Cookie:** Fegin may not be sending the cookie along with the request, leading to the SSO server rejecting it. 5. **Single Point of Entry:** Fegin's single entry point to the SSO server might not be properly configured to handle Cookie-based authentication. ## Solutions 1. **Ensure Consistent Cookie Sending:** Ensure that Fegin consistently sends the authentication Cookie along with each request. This can be done by configuring the interceptor to set the Cookie in the `setRequestHeader` method. 2. **Configure SSO Server to Include Cookie in Requests:** Check if the SSO server is configured to send the authentication Cookie in the HTTP request. This setting might be within the server's configuration file or through an API. 3. **Adjust Fegin Interceptor Configuration:** Modify the interceptor to handle Cookie-based authentication. This might involve checking for the presence of the Cookie in the request header and handling it appropriately. 4. **Review Microservice Configuration:** Ensure that each microservice is properly configured to use the `stpUtil.isLogin()` method and handle authentication cookies. ## Additional Points * It would be helpful to review the specific configurations of the SSO server and the Fegin interceptor to identify any potential issues. * Understanding the purpose and behavior of the `stpUtil.isLogin()` method and how it interacts with cookies would be beneficial.

正文

项目Springcloud,认证中心方式实现SSO使用开源框架Sa-Token

本身的单独访问每个客户端服务的单点就没有问题。然后单点通过Fegin调用就不好使了!

主要使用的Sa-Token的微服务单点功能
使用的依赖如下
  <!--SA-Token SSO-->
    <dependencyManagement>
        <dependencies>
            <!-- Sa-Token 权限认证, 在线文档:https://sa-token.cc -->
            <dependency>
                <groupId>cn.dev33</groupId>
                <artifactId>sa-token-spring-boot-starter</artifactId>
                <version>1.33.0</version>
            </dependency>
            <!-- Sa-Token 插件:整合SSO -->
            <dependency>
                <groupId>cn.dev33</groupId>
                <artifactId>sa-token-sso</artifactId>
                <version>1.33.0</version>
            </dependency>

            <!-- Sa-Token 整合redis (使用jackson序列化方式) -->
            <dependency>
                <groupId>cn.dev33</groupId>
                <artifactId>sa-token-dao-redis-jackson</artifactId>
                <version>1.33.0</version>
            </dependency>

            <!-- Sa-Token插件:权限缓存与业务缓存分离 -->
            <dependency>
                <groupId>cn.dev33</groupId>
                <artifactId>sa-token-alone-redis</artifactId>
                <version>1.33.0</version>
            </dependency>

        </dependencies>
    </dependencyManagement>

问题就是A服务通过Fegin调用B服务,然后 StpUtil.isLogin();是False

统一的认证处理拦截器

/**
 * @description: SA-Token 认证中心登录状态校验拦截器
 * @author: GuoTong
 * @createTime: 2022-10-05 15:40
 * @since JDK 1.8 OR 11
 **/
public class AuthenticationInterceptor implements HandlerInterceptor {
    /**
     * Description:  主要流程:
     * <p>
     * 1.从 http 请求头中取出 token,
     * 2.判断是否映射到方法
     * 3.检查是否有SkipTokenByJWT注解注释,有则跳过认证
     * 4.检查有没有需要用户登录的注解NeedTokenByJWT,有则需要取出并验证
     * 5.认证通过则可以访问,不通过会报相关错误信息
     */

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception {
        // 如果不是映射到方法直接通过
        if (!(object instanceof HandlerMethod)) {
            return true;
        }
        String requestURI = httpServletRequest.getRequestURI();
        // 判断是否是认证中心对外认证接口
        if (requestURI.contains("/sso")) {
            return true;
        }
        //  获取当前会话是否已经登录,返回true=已登录,false=未登录 ||只能获取本服务的登录状态 StpUtil.isLogin
        boolean login = StpUtil.isLogin();
        if (!login) {
            // 跳转认证中心 httpServletResponse.sendRedirect("/sso/login?back=" + httpServletRequest.getRequestURL());
            throw new NotLoginException(ContextCommonMsg.LOGIN_STATUS_EXPIRE);
        }
        return true;
    }
}

明明都已经登录了Sa-Token集成的OSSServer服务器

但是Fegin调用过程中,发现请求老是被拦截去重定向到SSO-server的登录页

按下F12看看Sa-token在浏览器上做了啥。已经登录的系统Sa-token会放一个Cookie,且所有集成于Sa-token的应用,访问的时候都会放这个玩意。所有集成Sa-token的SSo-Server的客户端的Cookie完全一致,达到单点登录目的。

但是Fegin调用为什么不通,难道这个Cookie没有带过去。

于是就拦截Fegin发送请求的Request,鞋带上Cookie在Request·的Header里

 @Bean
    public RequestInterceptor requestInterceptor() {
        return template -> {
            // 获取请求进入的数据
            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

            if (requestAttributes != null) {
                // fegin调用前的原始请求
                HttpServletRequest request = requestAttributes.getRequest();
                if (request != null) {
                    String cookie = request.getHeader("Cookie");
                    // 添加cookie
                    template.header("Cookie", cookie);
                    // 添加Content-Type
                    String contentType = request.getContentType();
                    template.header("Content-Type", contentType);
                }
            }

        };
    }

本身的单独访问每个客户端服务的单点就没有问题。然后单点通过Fegin调用就好使了,;

未登录访问任何一个微服务系统都会被重定向到SSO服务器的登录页

image

登录完成后会重定向回来:Fegin调用不会走到SO服务器的登录页,获取到接口数据了

image

但是任意一个系统点了注销,所有系统都会被注销

与微服务使用openfeign调用单点的会话失效问题相似的内容:

微服务使用openfeign调用单点的会话失效问题

# 项目Springcloud,认证中心方式实现SSO使用开源框架Sa-Token >本身的单独访问每个客户端服务的单点就没有问题。然后单点通过Fegin调用就不好使了! ##### 主要使用的Sa-Token的微服务单点功能 ##### 使用的依赖如下 ```xml cn.dev33 sa-tok

python 注册nacos 进行接口规范定义

背景: 一般场景 python服务经常作为java下游的 算法服务或者 数据处理服务 但是使用http 去调用比较不灵活,通过注册到nacos上进行微服务调用才是比较爽的 1.定义feginapi的接口定义 java端 定义接口请求和响应 主要关注 CommonResult 结构 和 python要

分布式事务 —— SpringCloud Alibaba Seata

Seata 简介 传统的单体应用中,业务操作使用同一条连接操作不同的数据表,一旦出现异常就可以整体回滚。随着公司的快速发展、业务需求的变化,单体应用被拆分成微服务应用,原来的单体应用被拆分成多个独立的微服务,分别使用独立的数据源,业务操作需要调用三个服务来完成。此时每个服务内部的数据一致性由本地事务

为什么要使用微服务架构?

一、传统的单体架构 1、什么是单体架构? 单体架构(Monolithic Architecture)是一种传统的软件架构模式,将整个应用程序作为一个单一的、统一的单元进行开发、部署和扩展。在单体架构中,所有的功能模块都被打包在一起,共享同一个代码库和数据库。 2、单体架构的缺点 复杂性高 一个大型的

微服务面试必读:拆分、事务、设计的综合解析与实践指南

微服务的应用级别确实相对简单,但在实际开发中仍有一些技术难点需要解决。对于微服务组件的使用,确实不存在太大差距,但在设计和开发过程中需要积累经验。学习微服务的上手时间相对较短,可能只需一周到一个月的时间。然而,设计经验和技术难点是需要个人长期积累的,不能急于求成。因此,在使用和开发微服务时,更应该关注方案思考,展示自己对该领域的理解和见解。这样能够体现出你对问题的思考深度和解决方案的创新性。希望这次面试种子题目的解答能够帮助你应对面试官的问题!

.NET微服务系统迁移至.NET6.0的故事

本次迁移涉及的是公司内部一个业务子系统,该系统是一个多样化的应用,支撑着公司的多个业务方向。目前,该系统由40多个基于.NET的微服务应用构成,使用数千个CPU核心和数TB内存,在数百个Linux容器中运行。每天,该系统需要处理数十亿次请求。 该系统其中大部分服务是在2018-2019年左右由老旧.

Postgresql使用触发器实现同步插入两张表

在有一个陈旧的系统的情况下,如果升级API可以优先使用微服务的形式,将数据库进行独立拆分,将原来的数据库原原本本地固定在旧系统中,然后在独立的微服务中运行与部署新系统。 如果原有的数据需要在更换结构的前提下在不同的版本的系统下进行共享,那可以使用数据库的卷影复制等功能。如果两个数据表的结构不完全一样

0停机迁移Nacos?Java字节码技术来帮忙

摘要:本文介绍如何将Spring Cloud应用从开源Consul无缝迁移至华为云Nacos。 本文分享自华为云社区《0停机迁移Nacos?Java字节码技术来帮忙》,作者:华为云PaaS服务小智。 1.市场迁移云环境痛点 市场微服务迁移云环境难主要有以下几点场景: • 微服务规模小,使用微服务引擎

微服务下认证授权框架的探讨

前言 市面上关于认证授权的框架已经比较丰富了,大都是关于单体应用的认证授权,在分布式架构下,使用比较多的方案是--<应用网关>,网关里集中认证,将认证通过的请求再转发给代理的服务,这种中心化的方式并不适用于微服务,这里讨论另一种方案--<认证中心>,利用jwt去中心化的特性,减轻认证中心的压力,有理

微服务实践k8s&dapr开发部署实验(1)服务调用

前置条件 安装docker与dapr: 手把手教你学Dapr - 3. 使用Dapr运行第一个.Net程序 安装k8s dapr 自托管模式运行 新建一个webapi无权限项目 launchSettings.json中applicationUrl端口改成5001,如下: "applicationUr