单点登录、oauth2、SpringCloudSecurity理解

之前对这些概念不理解,互相的关系,oauth2怎么用到项目中等等。

脱离框架的束缚,先理解了概念,再设计思路,最后再看现有的框架。

一.单点登录

公司有两个应用,原先是不同的系统、不同的账号、不同的网站,现在希望合二为一,在一个系统登录过后,就可以直接用第二个系统。 比如淘宝网和支付宝,我记得最初使用时,他们有各自的账号,现在在支付宝登录后,就默认在淘宝登录了。

实现这个功能,(对原有系统改造)需要注意三点:

  • 共同认证系统:需要把认证系统单独抽象,用于发放令牌、校验令牌,每个业务系统都用它。原系统可能有各自的认证流程,现在抽象为一个。
  • 进入下游业务系统前,先调用认证服务认证:方式很多,比如业务系统前拦截器(拦截请求,先调用认证服务);现在的微服务系统,在网关拦截器中调用认证系统。不管怎样的方式,就是得先调用认证服务
  • 认证服务的多账号体系:原有系统可能是不同账号体系,所以认证系统必须能访问多个数据库,能够分清请求是哪个业务账号。

即使新系统加入已有的单点登录,也只要注意这几点就行。

二.oauth2的好处

oauth2协议,具体协议格式,有四种方式,就不细讲了,推荐看一下http://www.ruanyifeng.com/blog/2019/04/oauth_design.html,从概念到借助github账号登录案例。

谈一下为什么系统要用oauth2,如果方便了第三方那系统本身账号体系该怎么登录?

都说这是为了第三方登录使用的,但springcloud官方推荐这种方式,有一段时间不明白为什么这么做,我自己的系统为啥要方便第三方。

举两个常见例子:

1.我的系统没有账号体系,在我的app上只有微信登录,这个很简单,照着微信文档,它那套流程就是oauth2,拿到微信的access_token(微信的令牌名称),就可以访问微信的数据,也代表在我的系统登录成功。  

2.我的系统有自己的账号体系,登录成功后给用户令牌,假设叫token_A。  现在还在让用户可以微信登录,获得了微信的access_token,但微信登录成功后,(肯定会保存用户信息、用户注册等等)我还会下发一个token_A,表示他在我的系统也登录成功了。   

注微信登录大概的oauth2流程:微信开发者注册账号,会有app_id,和app_secret,这两个理解为oauth2协议中的client_id和client_secret。 app中发起调用微信方法,手机就会拉起微信授权页面,这时用户点击授权,用户点击这一步就是获得code的一步,后台会携带app_id、client_id访问oauth/authorize接口。  拿到code后,携带app_id 和app_secret 和code 获得access_token。不细说了,可以对比微信文档和oauth2,流程是一样的

以上是工作常见需求,我们的系统想用微信登录,但如果其他的系统想用我们的账号登录呢?

如果我的系统很火,别的新应用想直接用我的账号体系,(毕竟现在用户不喜欢新祖册),或者公司的新系统不想再设计一套账号体系,想用老系统的;

在这种场景中,老系统、我的系统就变成了第三方,新系统借助第三方账号(老应用账号)完成登录。

所以如果我的系统使用了oauth2 认证,那就很方便让其他系统使用我的账号,这就是我们系统采用它的好处。

三.原系统用户怎么登陆

oauth2 很方便第三方,那我们系统本身怎么认证呢?和原有的单体shiro那些对比账号密码有什么不同?

不同点只有一个,client_id。

假设我的应用叫A,其他应用BC,想用A系统账号,首先B要在系统A注册这里应用表,比如A一个client表,表示都有哪些系统在用A系统进行第三方登录。里面字段有client_id,client_secret(秘钥).

B应用注册了,有了client_id,client_secret,就可以按照oauth2 四种流程,获取token。那A应用的登录流程是怎样的?

其实和B没有差异,因为A本身在client表也有记录,A有自己的client_id和client_secret,A系统用户登录也走oauth2的四种流程,区别只是把B的client_id换成了A的client_id和秘钥。

但是为了方便,毕竟A用户登录,A用户自己都没登录,无法直接授权得到code,还得输密码才能拿到code,所以A系统用户登录就直接用密码式登录比较方便。 而B应用 用授权码式登录最方便。

四种方式:http://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html

授权码(authorization-code)隐藏式(implicit)密码式(password):客户端凭证(client credentials)

四.SpringCloudSecurity

SpringCloudSecurity 框架中已经对oauth2做了实现,通过zuul或者gateway,再加个认证服务。

我对security不熟悉,这里参考一本书,《重新定义springcloud》,里面有一个用SpringCloudSecurity和zuul直接写好的demo,拉下来就能运行,不需要配置数据库:https://github.com/SpringCloud/spring-cloud-code/tree/master/ch8-2(如果不想拉整个仓库代码,可以用svn拉去单独文件夹)

SpringCloudSecurity这个框架已经实现了四种登录方式,同时可以使用这四种方式,只要配置好client_id\client_secret,账号等。

这个demo里,zuul中有配置client_id,名为zuul_server, 其他业务服务没有配置, 就和我说得第三点一样,其他业务服务和zuul的client_id都是zuul_server,这些业务服务是一个应用,如果其他应用想借账号,就得注册client,在auth服务中配置。

看一下,运行这个demo后,对oauth2的实现效果:

这里还得注意postman对oauth2的使用,post设置Authorization,为basic 和oauth2:

1.密码式登陆:

注意postman设置, client——id

设置grant_type 为password, 输入用户密码,获得了 token

2.授权码式登陆 

http://localhost:7777/uaa/oauth/authorize?response_type=code&client_id=zuul_server&redirect_uri=http://www.baidu.com&scope=read

把这个链接用浏览器访问,如果之前没有登陆,会进入登陆页面,登陆后,就会得到code。  如果登录过,直接获得code。

再携带code 获得token

但这一步我访问失败了 ,还是对这个框架不了解,不知道哪里设置错了。

不过我发现,postman直接可以帮我们完成这些流程,在Authorization页面,有下面这个按钮

把grant_type调整为授权码(下拉项就是那几种 方式),把client_id等都填写上,

点击请求token,就会让你输入用户名密码,

输入后,就登录成功了,postman太强了。

五。一定要用框架吗

明白oauth2的流程,和四种登录方式后,其实可以按照协议自己设计程序,只要满足协议要求,毕竟其他系统根据这个协议用你的账户,而不是你的应用自个玩。而且也不一定四种都得实现,需要哪个实现哪个。

用户同意后获取授权码,这路径和参数的格式得遵守。

https://b.com/oauth/authorize?
  response_type=code&
  client_id=CLIENT_ID&
  redirect_uri=CALLBACK_URL&
  scope=read

获取令牌

https://b.com/oauth/token?
 client_id=CLIENT_ID&
 client_secret=CLIENT_SECRET&
 grant_type=authorization_code&
 code=AUTHORIZATION_CODE&
 redirect_uri=CALLBACK_URL

猜你喜欢

转载自blog.csdn.net/u014203449/article/details/107536737