SSO-OpenID-Connect配置与使用
wiki信息
- 创建时间: 2021-01-08
- 最近修改时间: 2021-01-09
- 当前版本:v1.0.1
- wiki作者: 向波任(C3005579)
- 联系电话: 5073+66948
- 联系邮箱:mcebg-mac1-miscdsys2@mail.foxconn.com
目录
- 参考网址
- OpenID-Connect协议
- 名词解释
- OpenID-Connect抽象流程
- OpenID-Connect的三种认证流程
- 单页应用的OpenID-Connect设置
- 后端通过access-token获取用户信息接口
参考网址
OpenID-Connect协议
什么是OpenID Connect?
OpenID Connect 1.0是一个简单的身份层,它基于OAuth 2.0协议。它允许客户端通过授权服务器执行认证过程去核实终端用户的身份,也同时通过交互式的REST-like风格去获取终端用户的基本简单的信息。
OpenID Connect允许所有类型的客户端,包括web端、移动端、JavaScript端,去请求和接收已认证的Session和终端用户信息。
OpenID Connect的整套技术规范是可扩展的,它允许加入可选择的特性,比如身份加密、OpenID Provider的服务发现、Session管理等,有些时候这些额外的特性对你的项目非常有意义和必要。
名词解释
- RP:Relying Part,依赖部分,即客户端
- OP: OpenID Provider,OpenID提供者,即服务端
- UserInfo Endpoint: 用户信息端点,提供用户信息的服务,通常OP服务器中集成了UserInfo Endpoint的功能
OpenID-Connect抽象流程
- RP客户端发送请求到OP服务器
- OP服务器认证用户并获取用户的授权
- OP服务器返回ID Token和Access Token
- RP客户端发送Access Token给OP服务器的UserInfo Endpoint服务
- OP服务器的UserInfo Endpoint服务返回用户的信息
抽象流程图如下:
1 | +--------+ +--------+ |
OpenID-Connect的三种认证流程
OpenID Connect提供了三种认证流程,如下:
- 授权码流程
- 隐式流程
- 混合流程
特定的流程决定了ID Token和Access Token返回给客户端的方式,根据自己的项目特点选择其中的一种流程。
三种流程的特点
特点 | 授权码流程 | 隐式流程 | 混合流程 |
---|---|---|---|
所有的token都从Authorization Endpoint返回 | no | yes | no |
所有token都从Token Endpoint返回 | yes | no | no |
token不透露User Agent | yes | no | no |
客户端能被认证 | yes | no | yes |
可用Refresh Token | yes | no | yes |
客户端和服务器只需要一轮通信 | no | yes | no |
大多数的通信都是服务器对服务器通信 | yes | no | varies(变化) |
三种流程的response_type
response_type值 | 流程类型 |
---|---|
code | 授权码流程 |
id_token | 隐式流程 |
id_token token | 隐式流程 |
code id_token | 混合流程 |
code token | 混合流程 |
code id_token token | 混合流程 |
授权码流程
- 当使用授权码流程时,所有的token都从Token Endpoint返回。
- 授权码流程返回授权码给客户端,然后客户端用授权码直接从服务器获取ID Token和Access Token,这样做的好处是不会暴露任何token给User Agent和其他能够访问这些User Agent的可能的恶意应用。
授权服务器也能在通过授权码交换Access Token之前认证客户端。授权码流程适合需要在客户端和授权服务器之间确保客户端密码安全的客户端。
授权码流程步骤:
- 客户端准备包含了相应请求参数的认证请求
- 客户端发送认证请求到授权服务器
- 授权服务器认证用户
- 授权服务器获取用户授权
- 授权服务器将用户返回到客户端并带上授权码
- 客户端后端使用授权码请求授权服务器的Token Endpoint服务
- 授权服务器的Token Endpoint服务返回ID Token和Access Token给客户端
- 客户端验证ID Token并获取用户信息
隐式流程
- 当使用隐式流程时,所有token都从Authorization Endpoint返回,Token Endpoint没有被使用。
- 隐式流程主要用于使用脚本语言在浏览器里实现地客户端。Access Token和ID Token都直接返回到客户端,这样可能会将这两种token暴露给用户和那些能够访问用户User Agent的应用。
授权服务器没有执行客户端认证的过程。
隐式流程步骤:
- 客户端准备好包含有需求要请求的参数的认证请求
- 客户端发送认证请求到授权服务器
- 授权服务器认证用户
- 授权服务器获取用户授权
- 授权服务器返回ID Token和Access Token给客户端
- 客户端验证ID Token并获取用户信息
混合流程
- 当使用混合流程时,一些token是从Authorization Endpoint返回,另一些是从Token Endpoint返回。
混合流程的步骤:
- 客户端准备好包含需要请求的参数的认证请求
- 客户端发送认证请求到授权服务器
- 授权服务器认证用户
- 授权服务器获取用户授权
- 授权服务器将用户返回到客户端,并带上授权码,依据响应的类型,携带一个或多个额外的参数(这里的参数就是可以直接从授权服务器获取的token,
能从授权服务器中直接获取token,这就是和授权码流程的区别) - 客户端将授权码发送到Token Endpoint
- 客户端获取Token Endpoint返回的ID Token和Access Token
- 客户端验证ID Token并获取用户信息
单页应用的OpenID-Connect设置
根据前面隐式流程的特性看出,单页应用非常符合隐式流程,所以前端是单页应用的系统或项目可以直接使用隐式流程,优点是配置简单且使用方便,缺点是暴露了各种token,显得不那么安全。
如果系统对安全要求较高的话,还是老老实实用授权码方式,所有的token都是在后端流转,前端只能够看到重定向的授权码,且所有的权限都由后端的SpringSecurity来管理。
Portal项目中的OpenID Connect客户端的实现思路如下,小伙伴们可以参考:
- OpenID Connect服务器中设置客户端使用隐式流程如下图,所有的跳转都交给前端
- 后端只负责通过HttpClient用token获取用户信息(因为大多数情况下前端没办法在当前项目中直接用token向授权服务器取用户信息,会涉及到跨域)
- 前端做好路由的前置守卫,所有前端发起的请求都要经过该守卫,功能类似后端的过滤器或拦截器。
- 登录成功后将用户信息和token都存放到前端的sessionStorage中,登出后清除sessionStorage中的这些数据。
(我知道你要吐槽这不安全,但是我们的内网项目,其实真的不用太在意这些细节,用户登录状态都交给前端,后端小伙伴们安静地做个增删改查接口仔,不香么,前端都用单页应用了,已经是前后分离了,把MVC都交给前端吧) - 其实重点在路由前置守卫,感觉讲不清楚,直接贴代码吧
大致实现思路如下:
a. 根据sessionStorage中的用户信息和access_token的有无判断用户是否登录,
b. 没有登录就跳转到OpenID Connect的授权地址, 如果未在OpenID Connect中登录,就会跳转到登录页面,
c. 用户登录成功后会重定向回设置的地址,然后在该地址会携带access_token返回,从url中获取access_token的值,
d. 调用后端的接口获取用户信息,然后将用户信息和access_token保存到sessionStorage中。
React的实现
1 | function getUrlParam (param:any) { |
Vue的实现
1 | // router/index.js |
后端通过access-token获取用户信息接口
大致实现思路:
- 通过拦截器去拦截有特定注解的请求(携带token的请求都需要使用特定的注解)
- 从请求头中获取token
- 使用HttpClient工具类去请求OpenID Connect的userinfo服务,从而获取用户信息
这里贴出拦截器和HttpClient工具类的核心代码
拦截器
1 | // AuthInterceptor.java 拦截器 |
HttpClient工具类
1 | // HttpClientUtil.java HttpClient工具类 |
- 本文标题:SSO-OpenID-Connect配置与使用
- 本文作者:Xplorist
- 创建时间:2021-01-08 10:21:00
- 本文链接:https://xplorist.tech/2021/01/08/8e06d9fd4853/
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!