网关 Spring Cloud Zuul 自定义过滤器认证转换 Token_lakernote的博客-程序员秘密

技术标签: 《Spring Cloud - 实战》  

整理思路

  • 由网关Zuul进行Token颁布
  • 由网关Zuul进行登录认证拦截
  • 拦截的配置等可以用Mysql存储配置或者配置文件,只配置默认放开的路径即可
  • 拦截后把在zuul中的token,换成跟后台用户关联的Uid等

整体分为2步

  • 创建Pre类型ZuulFilter转换token,加入Request Header中
  • 下游业务服务接收转换的Uid

Pre Zuul Filter

import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;

  • 过滤器类型 : FilterConstants.PRE_TYPE
  • 过滤器优先级:跟debug 一样 FilterConstants.DEBUG_FILTER_ORDER
  • 是否开启:可以获取path判断某些不过滤
  • 可以自定义增加请求参数或者请求头
  • 可以自定义不传递,直接返回的响应码和响应体
  • 可以根据 service-id 判断是否处理
  • 自定义header如果起始request中已有,会被zuul覆盖
@Component
public class PreTokenFilter extends ZuulFilter {
    
    @Autowired
    private RouteLocator routeLocator;

    private UrlPathHelper urlPathHelper = new UrlPathHelper();

    @Override
    public String filterType() {
     // 过滤器类型
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
     //过滤器优先级
        return FilterConstants.DEBUG_FILTER_ORDER;
    }

    @Override
    public boolean shouldFilter() {
     // 过滤器是否启用
        RequestContext ctx = RequestContext.getCurrentContext();
        final String requestURI = this.urlPathHelper
                .getPathWithinApplication(ctx.getRequest());
        Route route = this.routeLocator.getMatchingRoute(requestURI);
        if (route != null) {
    
            // roadnet-service
            String location = route.getLocation();
            if (StrUtil.equals(location, "roadnet-service")) {
    
                return true;
            }
        }

        return false;
    }

    @Override
    public Object run() {
    
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest(); // 获取请求 HttpServletRequest
        String token = request.getHeader("token");
        if (StrUtil.isBlank(token)) {
    
            token = request.getParameter("token");
        }
        if (null == token || "".equals(token)) {
    
            ctx.setSendZuulResponse(false); // 直接返回,不向后传递了 
            ctx.getResponse().setContentType("application/json; charset=utf-8");
            ctx.setResponseStatusCode(401); // 返回 http code 401
            Dict dict = Dict.create().set("code", "101").set("msg", "兄弟裂开了,token is not found");
            ctx.setResponseBody(JSONUtil.toJsonPrettyStr(dict));
        }

        setExtRequestHeader(ctx);
        setExtRequestQueryParams(ctx);
        return null;
    }

    private void setExtRequestHeader(RequestContext ctx) {
    
        ctx.addZuulRequestHeader("deptId", "lakerDept");
        ctx.addZuulRequestHeader("userId", "laker");
    }

    private void setExtRequestQueryParams(RequestContext ctx) {
    
        //将转换后的数据放入请求参数中
        Map<String, List<String>> requestQueryParams = ctx.getRequestQueryParams();
        if (requestQueryParams == null) {
    
            requestQueryParams = new HashMap<>();
        }


        //将要新增的参数添加进去,被调用的微服务可以直接 去取,就想普通的一样,框架会直接注入进去
        ArrayList<String> paramsList = new ArrayList<>();
        paramsList.add("lakerDept");
        ArrayList<String> paramsList1 = new ArrayList<>();
        paramsList1.add("laker");
        requestQueryParams.put("deptId", paramsList);
        requestQueryParams.put("userId", paramsList1);
        ctx.setRequestQueryParams(requestQueryParams);
    }
}

下游业务服务接收

@GetMapping("/info")
public String info() {
    
    System.err.println("用户ID:" + request.getHeader("userId"));
}

其内部可以使用Filter或者拦截器去验证所有请求以及存放标记当前会话的userid

public class HttpHeaderParamFilter implements Filter {
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
    
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        httpResponse.setCharacterEncoding("UTF-8");
        httpResponse.setContentType("application/json; charset=utf-8");
        String uid = httpRequest.getHeader("uid");
        if(StrUtils.isNotBlank(uid)){
    
           RibbonFilterContextHolder.getCurrentContext().add("uid", uid);
           chain.doFilter(httpRequest, response); 
        } else {
    
            throw new BusinessException("没登录玩个锤子");
        }

    }
    @Override
    public void destroy() {
    
    }
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/abu935009066/article/details/116651096

智能推荐

《推荐系统之图神经网络研究》_基于图神经网络的餐饮推荐系统_辉辉傻呆呆的博客-程序员秘密

《推荐系统中的图神经网络研究:综述》Graph Neural Networks in Recommender Systems: A Survey1.介绍 本部分主要介绍了推荐系统的基本概念情况,使读者们对推荐系统有一个基本的了解。 一个高效的推荐系统应该准确地捕捉用户的偏好,并推荐用户潜在感兴趣的项目,这样可以提高用户对平台的满意度,提高用户留存率。推荐系统根据用户的兴趣和物品属性来评估用户对物品的偏好。 近年来,图神经网络在关系提取、蛋白质界面预测等许多应用领域都取得了巨大的成功[82]。

《需求规划、分析与分解》记录090105_YoungerChina的博客-程序员秘密

参加公司组织的《需求规划、分析与分解》培训。做了几点记录:(还需要深入学习)认识干系人我们设计的产品或服务,往往需要满足其中涉及到的关键性人物或组织的某些需求,从而为他们提供理想的价值。他们的需求和利益可能影响着设计的方向、结果,他们也可能直接或间接地参与设计过程。由此,我们总结出干系人的定义:干系人,又叫利益相关者,包括对产品或服务的使用、体验、或结果有影响或有兴趣的人或组织。...

soar 启发规则汇总 && 常见 MySQL 优化案例_soar规则_ROVAST的博客-程序员秘密

前言最近偶然翻翻一些博客,发现依然有一些介绍 mysql 常见优化场景的东西,甚是有趣。想起了之前在公司做的 SQL 规范相关工作。独乐了不如众乐乐,独学习不如众分享,跟大家分享下自己在这个环节的一些心得。之前无非是根据一些经验和书籍,列出常见的场景。直到有一次看到了小米的开源工具,SOAR,简直是被震惊的感觉。这个工具通过是 SQL 语法树的分析,结合小米 DBA 多年经验的总结,进行了一系...

Gulp-Node.js界的Jenkins 入门_coding_forever的博客-程序员秘密

Gulpgulp是前端开发过程中一种基于流的代码构建工具,是自动化项目的构建利器;她不仅能对网站资源进行优化,而且在开发过程中很多重复的任务能够使用正确的工具自动完成;使用它,不仅可以很愉快的编写代码,而且大大提高我们的工作效率。gulp是基于Nodejs的自动任务运行器, 它能自动化地完成 javascript、coffee、sass、less、html/image、css 等文件的测试、检查、合

关于前端职业规划的一点思考_码飞_CC的博客-程序员秘密

自己目前已经工作3年了,最近也刚换了新工作,日常也一直在考虑自己的前端职业规划到底是怎样的,个人目前视角还不是很宽广,以下这篇文章有点启发,故转发供大家借鉴。正文:不知道你上次思考前端职业规划是什么时候?如果你是一位学生,你肯定对前端这个职业感到陌生,你虽然没有经验,但却对未来充满好奇,你有大把时间来思考,但可能摸不着方向,有种拳头打在棉花上的无力感。如果你已经参加了工作,不论是刚开始实习,还是工作了 3 年、5 年甚至 10 年,一定觉得非常充实,但真正用于思考的时间足够吗?如果维持现状,再过 5

随便推点

服务器响应相关的状态码_爆米花机枪手的博客-程序员秘密

常见HTTP状态码200 OK301 Moved Permanently302 Found304 Not Modified307 Temporary Redirect400 Bad Request401 Unauthorized403 Forbidden404 Not Found410 Gone500 Internal Server Error

海思开发板上挂载额外的存储空间_mmcblk0p4_永兴呵呵哒的博客-程序员秘密

注:海思开发板烧写好系统以后,只能使用90M大小的空间,这是在烧写文件系统时创建的。其实还有很大的存储空间没有用到,需要进行挂载。一、使用如下命令可以查看开发板的存储空间使用情况df -h二、查看需要将额外的存储空间挂载到哪里输入reboot命令进入uboot输入print命令,可以在显示结果中看到下面这一行root=/dev/mmcblk0p3 rootfstype=ext4 rw init=/linuxrc rootwait blkdevparts=mmcblk0:1M(boot),12

面向对象程序设计(C++)_实验5_类的继承、派生和多态(2)_weixin_30325971的博客-程序员秘密

实验结论Part1 验证性实验(1)通过对象名.成员名的方式,访问的是派生类中新增的同名成员。在基类中成员函数无关键字virtual的情况下,通过基类指针访问派生类对象时,访问的是基类Base1中定义的成员函数。在基类中成员函数有关键字virtual修饰的情况下,通过基类指针访问派生类对象时,访问的则是该指针所指对象实际所属类的成员函数。Part2 验证性实验(2)在本...

ant-design V3升级V4记录(成功篇)_antd 升级_ime33的博客-程序员秘密

原因:babel版本兼容问题以及.babelrc文件配置,可在下方沿用我的babel相关版本。一是antd是一个开源性生态框架,人家社区一直在更新迭代,如果产品不及时更新,一直在使用不维护的,甚至有问题的框架,后果可想而知。原因:检查style-loader\less-loader\css-loader版本,挨个尝试。这篇博客没有一步步记录升级过程中的错误以及解决办法,所以只罗列的大致的错误项,希望对在升级之路上的你有所帮助。另外在我升级V4时,其实框架已经到了V5了,无奈升级到V5前,必须先升级V4。

P1972 [SDOI2009]HH的项链 莫队or树状数组_diaohan2969的博客-程序员秘密

用什么树状数组莫队多帅思路:树状数组\(or\)莫队(其实还是推荐树状数组\(QwQ\))提交:我告诉你我卡了一会儿常卡不满原因:没有用奇偶性排序题解:莫队:就是裸的莫队,把询问排序\(etc.\)// luogu-judger-enable-o2#include&lt;cstdio&gt;#include&lt;iostream&gt;#include&lt;al...

Bean生命周期_在应用程序上下文容器内bean的生命周期中,一下哪个步骤在设置应用程序上下文步骤之后_Switchvov的博客-程序员秘密

Bean生命周期基本概述    生命周期一直是很重要的内容,从以前Java对象、Servlet的生命周期可以看出,只有理解了其生命周期,才能知道应该在哪阶段完成哪阶段的事。Bean被载入到容器的时候,它的生命周期就开始了。  Bean生命周期Bean在应用上下文的生命周期原理图详细步骤1、实例化(当程序加载applicationCon