作者简介
目录
1.概述
2.实现方案
2.1.分散鉴权
2.2.集中鉴权
1.概述
SSO,即进行一次认证,然后就可以访问所有子系统。很明显SSO只是一种具象化的目标而已,目前业内为了实现单点登录、统一鉴权,提出了一系列的打法。比如直接就有成熟的组件CAS,其可以直接开箱即食,提供了鉴权中心的服务,也提供了客户端的依赖,直接启动鉴权中心,在客户端引入依赖配置一下就可以使用。比如有标准的协议oauth2.0等,规定了整个流程里有哪些实体和步骤。
其实总的来说单点登录无非就是给登陆后的用户发放一个凭证,然后后续依靠该凭证来进行权限的校验。这个凭证可以是cookie、可以是session,也可以是token、jwt等等,具体想用什么根据自己的业务场景来定就好,目前业内用的最多的是token。本文不会讨论那些繁杂且死板的流程,比如第几步返回什么状态码之类的,博主一直以来都认为,单点登录本来就是种思想,死板的流程没意义。
以下是单点登录的一个大致流程。
第一次登录时:
请求会走到鉴权服务器进行鉴权,发现没有登录,于是就会返回登录页面给用户进行登录,用户登陆后,会返回一份凭证给用户,鉴权中心也会保存一份。
后续的访问:
后续的访问会携带凭证继续走鉴权中心去进行鉴权,鉴权中心会比对凭证来确认用户是否有访问的权限。
这里要注意的是,一般来说都是在每个服务上来实现向鉴权中心进行鉴权的逻辑,并且要处理鉴权成功和失败的一系列逻辑。之所以这样做是因为可以在服务上甄别一下那些操作是需要登录后才可以做的。比如有些操作就是不用登录就可以做的,比如你在淘宝上进行浏览是不需要登陆的,而购买商品才是要登录的。希望不将所有请求无脑的全打到鉴权中心上去,从而形成这样的逻辑架构:
从而减轻鉴权中心的压力。
2.实现方案
实现方案有两种架构:
- 分散鉴权
- 集中鉴权
2.1.分散鉴权
分散鉴权,即将鉴权能力分散到各个应用上去,不需要单独部署的鉴权中心,所有应用维护同一个凭证的存储介质即可,一般这个凭证的存储介质选用redis之类的缓存来做。各个应用自己进行鉴权,也就是说每个应用上要实现一套完整的鉴权逻辑,还要随着附带上成功和失败的逻辑处理。我猜这时候很多同学想到了,直接给每个服务上一个spring security。确实是可以这样做,用spring security的话可以省去很多我们很多的编码,直接用框架自带的能力来进行鉴权校验即可。
spring security的使用方式,博主有篇文章专门详细讲解过:
详解Spring Security-CSDN博客
当然除了使用spring security以外还有其它的方式,比如:
- 使用spring mvc的拦截器
- 使用servlet的过滤器
等等。
在分散式的鉴权中,有个问题需要注意,登录的标准必须是一致的,也就是说鉴权中心要提供登录页给没登陆的用户首次登录使用,用户提交登录请求后的数据解析逻辑、用户信息的数据组织方式,这些内容各个应用上都必须是一致的。为了标准化,最好的方式式放在一起进行统一维护,将整个鉴权能力单独抽出来做成一个依赖,每个应用引入统一的依赖做配置使用即可。怕就怕各写各的,然后分叉了。
2.2.集中鉴权
集中式的鉴权,即将鉴权统一放到一起去,比如使用:
- CAS
- 网关。
前文都说过集中式的鉴权会对鉴权中心造成压力,为什么这里还要说集中式的喃?那是因为如果你用了网关,本来所有流量就会走网关上过,也没办法分散压力了,其次,集中式的方案中,授权节点一般都对吞吐量做了优化的,是能抗住较大吞吐量的。
1.CAS
CAS是耶鲁大学发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的单点登录方法。CAS中有一个独立部署的鉴权中心(cas server),在客户端上引入依赖然后配置一下,可以使得客户端成为cas client,client和server之间依靠凭证来进行鉴权。cas的具体使用博主会在后面单独出文,网上的相关资料也是车载斗量,需要现在使用的同学,自己去搜一下即可。
2.网关
如果我们用的是带有网关的微服务架构,那么可以利用类似于gateway之类的网关自带的请求分类拦截处理的能力来进行统一鉴权。
以gateway为例,gateway是以一条条路由来处理一类类的请求的。一条理由断言和过滤器组成,断言负责进行请求的判断,判断结果为true的请求才会被放行。所以我们可以通过自定义断言的方式来进行鉴权,自定义断言可以去开源社区或者官方文档上查一下相关的实现。当然处了自定义断言,也可以在gateway上用spring security来实现鉴权,具体的方案就看业务场景的需要了。