本篇文章给大家带来了关于鉴权的相关知识,其中主要介绍了微服务中鉴权的实现思路是什么?又有什么好的方案来实现呢?下面一起来看一下,希望对大家有帮助。

最近刚好有小伙伴在微信上问到这个问题,我就来和大家聊一聊,本文主要和小伙伴们聊一聊思路,不写代码,小伙伴们可以结合我之前的文章,应该能够自己写出来本文的代码。当然,思路也只是我自己的一点实践经验,不一定是最完美的方案,欢迎小伙伴们在留言中一起探讨。

1. 认证与授权

首先小伙伴们知道,无论我们学习 Shiro 还是 Spring Security,里边的功能无论有哪些,核心都是两个:

  • 认证

  • 授权

所以,我们在微服务中处理鉴权问题,也可以从这两个方面来考虑。

1.1 认证

认证,说白了就是登录。传统的 Web 登录是 Cookie+Session 的方案,这种方案依赖于服务器本地内存,在微服务中,由于服务众多,这种方案显然不再合适。

所以,微服务中的认证,还是建议使用令牌的方式,可以选择 JWT 令牌,这也是目前使用较多的一种方案。但是熟悉 JWT 的小伙伴都知道,纯粹的无状态登录无法实现注销,这就很头大,所以在实际应用中,单纯的使用 JWT 是不行的,一般还是要结合 Redis 一起,将生成的 JWT 字符串在 Redis 上也保存一份,并设置过期时间,判断用户是否登录时,需要先去 Redis 上查看 JWT 字符串是否存在,存在的话再对 JWT 字符串做解析操作,如果能成功解析,就没问题,如果不能成功解析,就说明令牌不合法。

这样有状态登录+无状态登录混在一起的方式,虽然看起来有点不伦不类,但是就当下来说,这个折衷的办法算是一个可行的方案了。

这是认证方案的选择。

1.2 授权

微服务中授权,也可以使用 Shiro 或者 Spring Security 框架来做,省事一些。考虑到微服务技术栈都是 Spring 家族的产品,所以在权限框架这块也是建议大家首选 Spring Security(如果有小伙伴对 Spring Security 还不熟悉的话,可以在微信公众号后台回复 ss,有教程)。

当然,如果觉得 Spring Security 比较复杂想自己搞的话,也是可以的。自己搞的话,也是可以借助于 Spring Security 的思路的,松哥最近的一个项目就是这样:

当然,如果你使用了 Spring Security 的话,上面这个就不需要自定义注解了,直接使用 Spring Security 中自带的即可,还可以体验 Spring Security 中更多的丰富的安全功能。

2. 认证服务

那么认证和授权在哪里做?

先来说认证,认证我们可以简单分为两个步骤:

  • 登录

  • 校验

2.1 登录

一般来说,登录我们可以单独做一个认证服务。当登录请求到达网关之后,我们将之转发到认证服务上,完成认证操作。

在认证服务上,我们就去检查用户名/密码是否 OK,用户状态是否都 OK,都没问题的话,生成 JWT 字符串,同时再把数据存入到 Redis 上,然后把 JWT 字符串返回。

2.2 校验

校验是指每一个请求到达的时候,校验用户是否已经登录。

这个当然可以和 2.1 放到一起去做,但是松哥不建议。问题在于,假如是一个创建订单的请求,这个请求原本是要经过网关转发到订单服务上的,但是,此时就得先在网关上调用 2.1 小节的服务进行登录校验,没问题再转发到订单服务上,这样做很明显很费事,也不合理。

一个比较好的办法是直接在网关上去校验请求的令牌是否合法,这个校验本身也比较容易,校验令牌是否合法,我们只需要看 Redis 上是否存在这个令牌,并且这个 JWT 令牌能够被顺利解析就行,这个操作完全可以在网关上做。

以 Gateway 网关为例,我们可以自定义全局过滤器,在全局过滤器中校验每一个请求的令牌,校验通过了,再进行请求的转发,否则就不转发。

校验通过之后,在转发到具体的微服务之后,我们可以将解析出来的用户 id 以及用户名等信息放到请求头中,然后再转发,这样到达各个具体的微服务之后,就知道这个请求是谁发来的,这人都有哪些角色/权限,方便做下一步的权限校验。

大致上就是这样一个流程。

3. 授权服务

授权没法放到网关上做,还是得在各个微服务上去完成。

微服务上的授权我们又可以将之大致上分为两类:

  • 前端发送来的请求(外部请求)。

  • 别的微服务发送来的请求(内部请求)。

3.1 外部请求

对于外部请求来说,就按正常的权限校验对待就行了,自定义注解亦或者使用 Spring Security 等框架都是可以的,如果是自定义注解的话,就结合 AOP 一起,定义切面自己去处理权限注解,当然,这些功能基本上每一个微服务都是需要的,所以可以将之抽取成为一个公共的模块,在不同的微服务中依赖即可。

3.2 内部请求

对于内部的请求来说,正常是不需要鉴权的,内部请求可以直接处理。问题是如果使用了 OpenFeign,数据都是通过接口暴露出去的,不鉴权的话,又会担心从外部来的请求调用这个接口,对于这个问题,我们也可以自定义注解+AOP,然后在内部请求调用的时候,额外加一个头字段加以区分。

当然,内部请求到达微服务的时候,也是需要进行认证的,就行请求从网关转发到每一个具体的微服务上时需要认证一样,不过很明显,我们没必要每次使用 OpenFeign 调用别的服务的时候,都去传一堆认证信息,我们可以通过实现 feign.RequestInterceptor 接口来定义一个 OpenFeign 的请求拦截器,在拦截器中,统一为 OpenFeign 请求设置请求头信息。

好啦,关于微服务中的鉴权,我们目前是这么做的,欢迎小伙伴们留言一起探讨。

推荐学习:《小程序视频教程》《Java视频教程

以上就是一文详解怎么实现微服务鉴权的详细内容,更多请关注Work网其它相关文章!

09-15 12:09