【shiro】shiro整合JWT——3.执行流程

前言

shiro整合JWT系列,主要记录核心思路–如何在shiro+redis整合JWTToken。
上一篇中,主要讲如何在shiro框架中配置Jwt,以及token执行的流程。
该篇主要梳理整个代码的执行流程。
ps:本文主要以记录核心思路为主,以下都是个人理解,有问题请各位大佬指导一下

根据token的流程,请求主要分为2个情况:

  1. 登录获取token
  2. 携带token请求

1、登录获取token

在shiro+redis+jwt中,Controller层的登录接口不用执行subject.login(token)方法(没有用到Realm的doCredentialsMatch验证,可以参照【Shiro】SimpleAuthenticationInfo如何验证password),而是在Controller层手写了校验方法。

  • 逻辑如下:
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	public xxx返回类 login(@RequestBody SysUser user) throws Exception{
	
	// 1、获取前端请求的 用户名和密码
	
	// 2、校验用户是否有效
		2.1 根据用户名查询数据库,得到用户数据库信息BDUser(用户名,加密密码,盐值...2.2 判断有效性(用户是否存在,是否注销,是否被删除)

	// 3、校验用户名或密码是否正确
		3.1 使用(前端传来的用户名,密码,DBUser.盐值)进行加密计算,得到加密密码
		3.2 判断是否正确,加密密码.equals(DBUser.getPassWord())

	// 4、生成token,并将token存入redis缓存中
	
	// 5、设置xxx返回类对象(主要把token返回去)
	
	}

从上面逻辑可以看出,这个登录接口主要就给前端返回了一个token,并将其存入redis中
这个登录接口,并没有真正进行登录操作subject.login(token),因此也没执行到Realm中的认证。

2、携带token请求

这里主要以流程介绍为主,通过简单的源码说明携带token请求的调用过程。通过【shiro】shiro整合JWT——1.需要创建的类 中的JwtFilter,我们可以看到,主要重写了preHandleisAccessAllowedexecuteLoginonAccessDenied这4个方法(该例子为简单实现)。

在JwtFilter中,这4个方法主要的执行顺序是
preHandle -> isAccessAllowed -> executeLogin -> onAccessDenied

2.1 preHandle

携带token的请求,先会被ShiroConfig中的filterChainDefinitionMap.put("/**", "jwt");给拦截,然后执行到我们定义的JwtFilter中;在JwtFilter中,会根据Filter中具体的doFilter方法实现(这里不细说,后续在细讲)。

/**
     * 对跨域提供支持
     * 过滤器链中拦截请求,判断是否为跨域请求
     */
    @Override
    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        // 判断请求方式是否为跨域请求
        if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
            httpServletResponse.setHeader("Access-Control-Allow-Origin", httpServletRequest.getHeader("Origin"));
            httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
            httpServletResponse.setHeader("Access-Control-Allow-Methods", httpServletRequest.getHeader("Access-Control-Request-Method"));
            httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
            return false;
        }
        // 继续执行过滤器链
        return super.preHandle(request, response);
    }

preHandle方法在最后return了super.preHandle(request, response);,点进去查看,可以发现它重写PathMatchingFilter中的preHandle,然后再回调回了PathMatchingFilter中的preHandle。(看上去有点绕,看下图)
在这里插入图片描述

总结:感觉就是PathMatchingFilter类是主线流程,(重写的)preHandle方法B就是在preHandle方法A中加入我们自定义的内容,然后再继续执行preHandle方法A原有的内容。

顺着源码继续往下梳理流程,先看preHandle的代码,发现执行了isFilterChainContinued方法,里面又执行了onPreHandle方法。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 疑惑:这个重写的是哪个方法?
    回答:我们顺着JwtFilter的继承方法网上查找,如下图;可以发现,是由AccessControlFilter类重写的。在这里插入图片描述
    点进去AccessControlFilter类可以看到我们重写的方法isAccessAllowedonAccessDenied,中间的关系是具有 先后顺序的或。
    在这里插入图片描述

2.2 isAccessAllowed

	/**
     * 执行登录认证
     *
     * @param request
     * @param response
     * @param mappedValue
     * @return
     */
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        try {
            executeLogin(request, response);
            return true;
        } catch (Exception e) {
            throw new AuthenticationException("Token失效请重新登录");
        }
    }

里面执行了executeLogin方法

2.3 executeLogin

	/**
     * 执行登录
     */
    @Override
    protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String token = httpServletRequest.getHeader("ACCESS_TOKEN");

        JwtToken jwtToken = new JwtToken(token);
        // 提交给realm进行登入,如果错误他会抛出异常并被捕获 
        // 这里真正实现shiro的登录,getSubject(request, response)直接SecurityUtils.getSubject()也一样
        getSubject(request, response).login(jwtToken);
        // 如果没有抛出异常则代表登入成功,返回true
        return true;
    }

对于getSubject(request, response).login(jwtToken);有疑惑的可以看下【shiro】subject.login(token)流程源码分析

PS:以防万一,遗忘却又没有看,这里根据总结图做下提示,执行getSubject(request, response).login(jwtToken)方法后,就会执行到Realm的认证方法。

2.4 onAccessDenied

根据源码,我们知道isAccessAllowed执行返回为True的话,就不会执行onAccessDenied(也就意味着登录成功,走向realm的两个方法);如果执行返回为False的话,就会执行onAccessDenied,用来处理登录失败的情况。

	/**
     * 如果没有登录,直接返回401未授权提示
     *
     */
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        // 这里是个坑,如果不设置的接受的访问源,那么前端都会报跨域错误,因为这里还没到corsConfig里面
        httpResponse.setHeader("Access-Control-Allow-Origin", ((HttpServletRequest) request).getHeader("Origin"));
        httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
        httpResponse.setCharacterEncoding("UTF-8");
        httpResponse.setContentType("application/json; charset=utf-8");
		httpResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
        try {
            // 返回到前端信息
            httpResponse.getWriter().write("未登录或登录失效,请重新登录!");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/25241.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

uCOSii消息邮箱管理

uCOSii消息邮箱管理 (MESSAGE MAILBOX MANAGEMENT) 消息邮箱主要用于中断和任务之间进行邮件传递,或者是在任务与任务之间进行邮件交换。 我个人觉得,了解uCOSii消息邮箱的几个重要函数,还是有必要的。不是所有人都给我们测试案例。 1、重…

R语言混合效应(多水平/层次/嵌套)模型及贝叶斯实现技术

回归分析是科学研究中十分重要的数据分析工具。随着现代统计技术发展,回归分析方法得到了极大改进。混合效应模型(Mixed effect model),即多水平模型(Multilevel model)/分层模型(Hierarchical Model)/嵌套…

如何快速运用R语言实现生物群落(生态)数据统计分析与绘图

R 语言作的开源、自由、免费等特点使其广泛应用于生物群落数据统计分析。生物群落数据多样而复杂,涉及众多统计分析方法。本次以生物群落数据分析中的最常用的统计方法回归和混合效应模型、多元统计分析技术及结构方程等数量分析方法为主线,通过多个来自…

Linux:查看进程。

Linux:查看进程。 windows linux TTY如果是?说明是不是终端(控制台)启动的,而是系统内部自己启动的。 TIME是启动Linux后,这个进程一共占用了cpu多少时间00…

QT 设计ROS GUI界面订阅和发布话题

QT 设计ROS GUI界面订阅和发布话题 主要参考下面的博客 ROS项目开发实战(三)——使用QT进行ROS的GUI界面设计(详细教程附代码!!!) Qt ROS 相关配置请看上一篇博客 首先建立工作空间和功能包&a…

【探索】机器指令翻译成 JavaScript

前言 前些时候研究脚本混淆时,打算先学一些「程序流程」相关的概念。为了不因太枯燥而放弃,决定想一个有趣的案例,可以边探索边学。 于是想了一个话题:尝试将机器指令 1:1 翻译 成 JavaScript,这样就能在浏览器中&am…

Java程序设计入门教程-- if 条件语句

目录 单分支选择语句(if) 双分支选择语句(if…else) 嵌套if语句 单分支选择语句(if) 情形 当判断条件满足时,执行语句体S,而不满足则什么都不做。 格式 if (条件判断表…

【计算机视觉 | 目标检测】术语理解6:ViT 变种( ViT-H、ViT-L ViT-B)、bbox(边界框)、边界框的绘制(含源代码)

文章目录 一、ViT & ViT变种1.1 ViT的介绍1.2 ViT 的变种 二、bbox(边界框)三、边界框的绘制 一、ViT & ViT变种 1.1 ViT的介绍 ViT,全称为Vision Transformer,是一种基于Transformer架构的视觉处理模型。传统的计算机视…

java企业工程项目管理系统平台源码(三控:进度组织、质量安全、预算资金成本、二平台:招采、设计管理)

工程项目管理软件(工程项目管理系统)对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营,全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#…

回调函数与钩子函数的区别,另QT中connect函数的实现,lambda的使用

1、钩子函数是回调函数的一种 广泛来说两者都是一样的 严格来说 钩子函数的函数名早已被定义好,只是函数内部需要用户在应用层来定义, 1)可以完全通过宏来实现系统是否调用该函数(底层不封闭,修改宏的参数实现是否编…

【2023 · CANN训练营第一季】MindSpore模型快速调优攻略 第二章——MindSpore调试调优

1.生态迁移 生态迁移工具使用示例 生态迁移工具技术方案 不同框架间模型定义前端表达差别巨大(相同算子的API技术难点 、 算子功能、模型构建方式差别较大); 对于同一框架,不管前端表达差异如何,最终对应的计算 图是相似的。因此提出&#x…

Kubernetes部署+kubesphere管理平台安装

Kubernetes官网;kubesphere官网 不论是Kubernetes官网还是找的其它部署步骤,基本都是推荐搭建集群的方式,是为了实现高可用.....等等,这样一来至少需要两台或三台的服务器来搭建,这样对我们的成本也是非常大的&#xf…

Axure教程——直方图(中继器)

本文将教大家如何用AXURE用中继器制作直方图 一、效果介绍 如图: 预览地址:https://yjkepz.axshare.com 下载地址:https://download.csdn.net/download/weixin_43516258/87842701 二、制作方法 (1)制作刻度表 设计5个刻…

CSDN上海城市开发者社区线下活动纪实

引言 5月27号中午,很高兴能和现CSDN副总裁、前微软 Azure 工程团队首席研发经理、技术畅销书《编程之美》及《构建之法》的作者邹欣邹老师,以及CSDN的 “上海城市开发者社区” 的部分成员齐聚一堂,参加CSDN上海城市开发者社区自5月初成立以来…

Ctfshow基础二刷(1)

前言: 前两天的信安给我整emo了,头一回打正经比赛,结果发现基础太差,代码审计烂得一踏糊涂。 寻思寻思,从头整一遍基础。又买了安恒出的新书。争取7号去吉林打省队选拔不给导儿丢脸吧呜呜 文件包含 web78: 这题一…

curl 命令-接口测试

curl 命令-接口测试 JUST DO IT 温暖春日 在linux/Unix 为代表的os上, 对后端进行测试, 模拟连接请求都会书写脚本 场景: 在Linux 上接口测试工具有ab, restClient, postman等, 最常用的方法是curl进行简单测试 curl是非常方便的Rest 客户端, 可以很方便的完成 Rest API测…

AcWing算法提高课-1.3.11二维费用的背包问题

宣传一下算法提高课整理 <— CSDN个人主页&#xff1a;更好的阅读体验 <— 本题链接&#xff08;AcWing&#xff09; 点这里 题目描述 有 N N N 件物品和一个容量是 V V V 的背包&#xff0c;背包能承受的最大重量是 M M M。 每件物品只能用一次。体积是 v i v_…

vcruntime140.dll丢失怎么办?怎么解决vcruntime140.dll丢失的问题

当您运行一个需要此文件的程序时&#xff0c;如果您的系统中不存在这个文件&#xff0c;会提示出错信息“找不到vcruntime140.dll”或“vcruntime140.dll丢失”。这种情况下&#xff0c;您需要解决这个问题&#xff0c;才能继续运行此应用程序。我们将介绍vcruntime140.dll丢失…

5.27下周黄金行情走势预测及开盘操作策略

近期有哪些消息面影响黄金走势&#xff1f;下周黄金多空该如何研判&#xff1f; ​黄金消息面解析&#xff1a;周五(5月26日)黄金大幅下跌&#xff0c;主要受到美国数据影响&#xff0c;美国公布的4月PCE和耐用品订单数据向好&#xff0c;再次强化市场对美联储的鹰派押注。现货…

(四)ArcGIS空间数据的转换与处理——数据结构转换

ArcGIS空间数据的转换与处理——数据转换 空间数据的来源很多&#xff0c;如地图、工程图、规划图、航空与遥感影像等&#xff0c;因此空间数据也有多种格式。根据应用需要&#xff0c;需对数据进行格式转换&#xff0c;不同数据结构间的转换主要包括矢量数据到栅格数据的转换…