总文档 :文章目录
Github : github.com/black-ant
一 . 前言
这一篇来说说 Pac4j , 为什么说他是认证工具呢 ,因为它真的提供了满满的封装类 ,可以让大部分应用快速的集成完成 ,使用者不需要关系认证协议的流程 , 只需要请求和获取用户即可
需要注意的是 , Pac4j 中多个不同的版本其实现差距较大 ,我的源码以 3.8.0 为主 ,分析其思想 , 然后再单独对比一下后续版本的优化 , 就不过多的深入源码细节了
二 . 基础使用
Pac4j 的一大特点就是为不同供应商提供了很完善的 Client , 基本上无需定制就可以实现认证的处理 , 但是这里我们尽量定制一个自己的流程 , 来看看 Pac4j 的一个定制流程是怎样的
以OAuth 为例 :
2.1 构建 Authoriza 请求
我们先构建一个 Client ,用来发起请求 :
OAuth20Configuration : 最原生的 OAuth 配置类 , 可以自行定制符合特定规范的配置类
OAuth20Client : 最原生的客户端调用类 , 后面可以看到 pac4j 有很多定制的client 类
1 | java复制代码public class OAuthService extends BasePac4jService { |
注意 , 这里有个 DefaultOAuthAPI 和 DefaultOAuthDefinition , 定义的是 SSO 路径和 Profile 声明
DefaultOAuthAPI
DefaultOAuthAPI 中主要包含了请求的地址 , DefaultApi20 有2个抽象接口 , 我额外添加了一个自己的接口
DefaultOAuthAPI 不做任何限制 , 可以把任何需要的接口都放进去 , 用于后续取用.
1 | java复制代码public class DefaultOAuthAPI extends DefaultApi20 { |
DefaultOAuthDefinition
该声明相当于一个字典 , 用于翻译 profile 返回的数据
整个类中做了下面这些事 :
- 定义了 user profile 会返回的属性
- 定义了各种转换类和映射
- 定义了 profile 请求的地址
- 定义了 转换数据的实际实现
1 | java复制代码 |
DefaultDateConverter
该对象用于解析数据 , 例如此处解析时间类型
1 | java复制代码 |
DefaultOAuhtProfile
可以理解为一个 TO , 用于接收数据
1 | java复制代码public class DefaultOAuhtProfile extends OAuth20Profile { |
2.2 构建一个接收对象
1 | java复制代码 @GetMapping("callback") |
总结一下就是 :
- DefaultOAuthAPI : 作为 metadata , 来标识请求的路径
- DefaultOAuthDefinition : 解释器用于解释返回的含义
- DefaultDateConverter : 用于转换数据
- DefaultOAuhtProfile : to 对象用于承载数据
很简单的一个定制 , 可以适配多种不同的 OAuth 供应商
三 . 源码一览
3.1 OAuth 请求篇
3.1.1 Authoriza 流程
Authoriza 中核心类为 IndirectClient , 我们来简单看一下 IndirectClient的逻辑
发起 Authoriza 认证
1 | java复制代码C01- IndirectClient |
补充一 : OAuth20Service
OAuth20Service 是一个 OAuth 业务类 , 其中包含常用的 OAuth 操作
3.1.2 AccessToken 流程
在上文中 ,我们为 OAuth 请求构建了一个 CallBack 方法 , SSO 认证完成后会回调该方法 , 我们来看看其中的一些有趣的点 :
1 | java复制代码 public void oauthCallBack(final HttpServletRequest request, final HttpServletResponse response) throws IOException { |
来看一看 getCredentials 方法干了什么
1 | java复制代码C01- IndirectClient |
3.1.3 UserInfo
看了 AccessToken 的获取 , 再看看怎么换取 Userinfo
1 | java复制代码 |
3.2 SAML 篇
3.2.1 发起请求
1 | java复制代码// Step 1 : 发起请求 |
看一下请求的结果
3.2.2 接收数据
后面仍然是一模一样的 , 只不过 Authenticator 变成了 SAML2Authenticator
1 | java复制代码 |
四 . 深入分析
Pac4j 是一个很好的开源项目 , 从流程上讲 , 他拥有非常好的扩展性 (PS: 个人写产品很喜欢扩展性 , 什么都可配) , 这在开源里面是一个很大的优势 , 它的整体流程基本上可以看成以下几个部分
Configuration 体系
Client 体系
Credentials 体系
Profile 体系
在这么多体系的情况下 ,通过 Context 完成整体容器的协调 , 在通过 RedirectAction 做统一的 请求重定向 .
为什么专门提 RedirectAction 呢 ?
因为我认为 pac4j 把所有的请求都抽象成了2个部分 , 一个是发起认证 , 一个的 callback 返回 ,
以这2个直观的操作为边界 , 再在其中加入认证信息获取等操作 , 用户基本上对请求的调用是不可见的.
DemoSSO配置 Configuration构建 Demo client发起 OAuth 认证返回认证信息Definition 解析返回 , 拿到一个 AccessToken Credentials通过 token 发起信息获取返回用户信息解析为 ProfileDemoSSO
五 . 开源分析
那么 , 从 pac4j 里面 , 能学到哪些优点呢?
首先 , pac4j 的定位是什么?
pac4j 是一个认证工具 , 或者说 SDK , 他解决了认证过程的复杂性 , 使用者进行简单的调用就可以直接拿到用户信息.
而他的第一个优点 , 就是兼容性和可配置性 , 我提供了了这么多 client , 你可以省事直接调 , 也可以自己定制 ,都没关系.
从代码结构上说 , pac4j 的第二个优点就是结构清晰 .
我们从上面的分析中 , 就能感觉到 , 能做什么 , 怎么做 , 怎么命名 ,其实都规约好了 , 进行简单的实现就可以满足要求.
而我认为第三个优点 , 就是耦合性低.
pac4j 采用的使 maven 聚合方式 , 想实现什么协议 , 就只引用相关包即可 . 代码与代码间的依赖度也低 , 这同样对定制有很大的好处, 值得学习.
六. 总结
pac4j 这工具 , 如果为了快速集成上线 , 确实是一个很理想的工具 ,
个人在写demo 的时候 , 也经常用他做基础测试 , 别说 , 真挺好用
代码已经发在 git 上面 , case 4.6.2 , 可以直接看.
本文转载自: 掘金