CAS认证/委托认证/OAuth20Client初始化流程

委托认证就是将CAS对接到第三方服务进行认证,但需要三方认证流程符合规范的流程(OAuth、OIDC),CAS已经提供了现成的github、Facebook、QQ等的对接

我们在使用委托认证的时候,会发现cas集成了N多种client(实际是 pac4j 提供的),比如现成的服务提供商Client:FacebookClient、GithubClient,基于协议的client:OAuthClient、OidcClient、SAML2Client等等,这些client包含了整个认证流程所需的组件,包括:如何跳转到认证URL、提取认证信息credentials、提取用户信息、如何跳转到登录URL这些主要流程,还包括其他组件,比如对获取到的用户属性进行重命名,使其符合我们之前配置过的属性名;

数据结构

我们先来看一下OAuth20Client内部数据结构涉及到的类型:

  • OAuth20Client:OAuth20客户端,核心类
  • Pac4jOAuth20ClientProperties:定义通用属性:各种url啦、appid、secret啦、需要保留的profile属性啦(可以定义别名),跳转到授权URL时要加的额外参数啦(这个不太受用)
  • OAuth20Service:OAuth相关流程业务类,比如请求access_token、refresh_token、设置response_type等等
  • DefaultApi20:通过继承该类,定义请求URL,定义签名类型(authorization是放在请求头还是请求参数),以及创建 Service
  • OAuth20ProfileDefinition:profile定义,用于生成profile,将授权之后获取到的用户信息设置到profile里
  • OAuth20ProfileCreator:profile创建类,包含请求profile时的参数签名,根据access_token获取profile啦这些。。。
  • OAuth20Configuration:定义 key、secret、response_type等等,也定义了api、profile definition

其他:

  • OAuth20RedirectActionBuilder:重定向行为构造器
  • OAuth20CredentialsExtractor:credential提取器
  • OAuth20Authenticator:认证类
  • OAuth20ProfileCreator:用户信息创建类
  • OAuth2AccessExtractor:access_token提取器,还有一个 OAuth2AccessJsonExtractor

认证流程

下面进入正题——认证流程:

首先是实例化入口:org.apereo.cas.support.pac4j.authentication.DelegatedClientFactory#build,通过构造函数初始化各种客户端:GithubClient, FacebookClient, OAuth20Client,通过配置的 properties 实例化对应的 client;

除了上面说的通过构造函数初始化,每个client包含一个init()函数,用来初始化其他字段,比如:

  • OAuth20RedirectActionBuilder:重定向行为构造器,用来构造重定向URL,如果需要修改授权URL的参数,需要自定义该方法
  • OAuth20CredentialsExtractor:credential提取器,在认证成功之后,要提取code;比如在开发企业微信二维码登录的时候,我暂时用不到code,要暂时保存下来,在后面使用,那就要自定义一个提取器;
  • OAuth20Authenticator:认证类,用code来换取access_token;但在qywx中,是不需要code的,而是拿appid+secret来获取,也要自定义;
  • OAuth20ProfileCreator:获取用户信息,正常流程是:access_token → user profile,qywx中是:code + access_token → user profile,所以还要自定义

解决暂时保留code 的问题,我在项目中定义了一个ThreadLocal来暂时保存code,而且是一次性的,只要get之后,立马remove

init()方法在什么地方调用呢?我们在测试过程中发现,当第一次使用该方式登录时,会进行调用init,有点懒加载的意思,感觉没必要,其实可以放在构造函数里面;

init()调用流程(这里以 GithubClient 为例):

org.apereo.cas.support.oauth.web.endpoints.OAuth20CallbackAuthorizeEndpointController#handleRequest

|

org.pac4j.core.engine.DefaultCallbackLogic#perform

|

org.pac4j.core.client.finder.DefaultCallbackClientFinder#find

|

org.pac4j.core.util.InitializableObject#init

|

org.pac4j.core.client.IndirectClient#internalInit

|

org.pac4j.oauth.client.GitHubClient#clientInit

延伸

最后插播一下企业微信的授权流程和OAuth授权流程的对比:

授权获取access_token获取profile
企业微信拿到codeappid + secret → access_tokencode + access_token → profile
OAuth拿到codecode → access_tokenaccess_token → profile

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注