项目经验分享:在 JustAuth Plus 中添加 HTTP API 的登陆方式

1,188 阅读9分钟

本次分享来自 Just Auth 社区的余志海同学(在 JustAuth Plus 中添加 HTTP API 的登陆方式)的项目经验。

项目综述

什么是 JustAuth Plus(JAP),它有什么用?

JustAuth Plus 衍生于 JustAuth 项目。JustAuth 是一个第三方授权登录的工具类库,它集成了国内外多家知名的第三方平台。JustAuth Plus 是在 JustAuth 的基础上进行开发的,是一款开源的登录认证中间件,基于模块化设计,为所有需要登录认证的 WEB 应用提供一套标准的技术解决方案,开发者可以基于 JAP 适配绝大多数的 WEB 系统(自有系统、联邦协议),就像集成 JustAuth 一样,简单方便。假如你想查看更多关于 JustAuth Plus 的信息可以点击进入其官网:justauth.plus

JustAuth Plus 目前支持多种认证登陆方式,例如 Oauth2.0、OIDC、账号密码等方式,但是还不支持通过 HTTP API 接口的形式进行登陆验证。本次的项目需求就是为 JustAuth Plus 编写 HTTP API 模块。

需求分析

在 “以 HTTP API 接口形式进行登陆验证的过程” 中,存在三个主体:

  1. 业务系统(开发者系统)
  2. 第三方系统(身份服务提供商)
  3. 用户

用户在登陆业务系统时,会向业务系统提供用户的认证信息。业务系统通过 HTTP API 接口向第三方系统发送认证请求,以此来进行用户信息的认证鉴权。示意图如下:

对于开发业务系统的开发者而言,业务系统中可能需要集成多个第三方系统,各个系统对外暴露的 HTTP API 的协议规范可能有所不同。因此在业务系统中集成第三方系统变为了一件棘手的事情。

在此次的项目开发中,我需要做的就是添加 JAP 中 HTTP API 模块,开发者在简单配置该模块之后就能很轻松地在其业务系统中集成第三方系统的登陆认证功能。

模块难点

在没有使用本模块的情况下,第三方系统向外暴露 HTTP API 接口,开发者向其发送鉴权请求时需要遵守 HTTP 认证鉴权协议。本模块需要为开发者屏蔽 HTTP 认证鉴权协议上的细节,这就是开发本模块的难点所在。

在查阅了许多资料文档(参见文末参考文献),深入学习了 HTTP 认证鉴权之后,总结出了 HTTP 认证的三大方式:

1、BASIC 认证:

Basic 认证是最简单的 HTTP 认证鉴权方式,认证过程简单明了,在认证过程中会直接发送明文密码,很容易导致密码泄漏,适用于安全性要求不高的系统。

2、DIGEST 认证

Digest 认证是为了为弥补 BASIC 认证存在的弱点,其用了一种nonce随机数字符串,双方约好对哪些信息进行哈希运算即可完成双方身份的验证。但是,假如认证报文被攻击者拦截,攻击者任然可以获取到受限资源,安全性还是不足。

3、BEARER 认证

BEAER 认证也可以称之为 Bearer Token 认证,我们经常使用的 JWT 就是一种 Bearer Token 认证方式。Token 是 Bearer 认证的核心,服务端通过校验 Token 合法性来进行认证授权。

第三方身份服务提供商向外暴露的 HTTP API 认证接口一般就是以上三种认证方式的其中之一。

模块编码

在解决了 HTTP 认证鉴权协议这个难点之后,项目代码编写也就不那么复杂了。

该模块的示意图如下:

功能特性:

  • 多 HTTP 认证协议支持:BASIC、DIGEST、BARER
  • 支持开发自定义添加请求头
  • 支持开发者自定义添加请求参数
  • 支持开发者自定义认证信息解析策略

代码设计:

  • subject包:对于 Http 认证鉴权中的请求头或响应头
  • util包:该模块需要使用到的工具类
  • HttpApiConfig:这个类是一个配置类,需要由开发者配置
  • HttpApiStrategy:该模块的核心类,向第三方身份服务提供商发起代理请求

开发者在使用 HttpApi 模块的时候需要提供 HttpApiConfig 配置,HttpApi 模块会根据配置信息结合用户认证请求向第三方系统发起认证请求。

在这里截取几段 HttpApiStrategy 中的代码,希望能帮你更好的理解 jap-http-api 模块的代码设计:

DEMO 演示

因为目前还没有将代码合并到 JustAuth Plus 官方仓库,所以还不能直接引用新的 HttpApi 模块。 最终版本或许与当前版本有差异,在这里只做演示。

运行环境说明:

  • 系统:MacOS BigSur 11.4
  • 编译器:IntelliJ IDEA 2021.1.3
  • JDK:11.0.11(备注:JAP 项目本身是以 JDK 1.8 为基础开发的)
  • Maven:3.6.3

以下的代码演示了开发者如何在自己的业务系统中集成 jap-http-api 模块。

1、导入 JAP Maven 依赖

<dependency>
    <groupId>com.fujieid</groupId>
    <artifactId>jap</artifactId>
    <version>1.0.3</version>
    <type>pom</type>
</dependency>

2、编写测试 Controller

@GetMapping("/basic")
public ResponseEntity authBasic(HttpServletRequest request, HttpServletResponse response ){
    HttpApiStrategy httpApiStrategy = new HttpApiStrategy(new JapHttpApiUserService(), new JapConfig());
    // 配置 HttpApi 模块
    HttpApiConfig httpApiConfig = new HttpApiConfig()
            // 指定第三方 Http认证类别
            .setAuthSchema(HttpApiConfig.AuthSchemaEnum.BASIC)
            // 指定第三方 Http认证方式
            .setHttpMethod(HttpApiConfig.HttpMethodEnum.GET)
            // 指定用户传入认证信息存放的位置
            .setAuthInfoField(HttpApiConfig.AuthInfoFieldEnum.BODY)
             // 指定第三方的登陆地址(我启动了一个本地服务当作第三方系统)
            .setLoginUrl("localhost:8088/api/v1/source1");

    // 将认证信息交给 http-api 模块,http-api 模块负责代理验证
    JapResponse authenticate = httpApiStrategy.authenticate(httpApiConfig, request, response);
    // 获得认证结果
    if(authenticate.isSuccess()){
        return new ResponseEntity(200,"login success",authenticate.getData());
    }else{
        return new ResponseEntity(403,"login failure",authenticate.getData());
    }
}

3、模拟用户发送登陆请求,进行测试

项目总结

首先,最最最重要的就是明确需求。最开始接到项目的时候,我对项目需求的理解其实是产生了一些偏差的。我起初以为是实现一个 RESTFul 风格的完整的认证鉴权框架,但是项目的实际需求和我理解的完全不同。在没有透彻的理解需求的情况下就开始了编码工作,做了很多无用功,也浪费了时间精力,我想这也是很多小伙伴在初次接触项目开发时常犯的错误吧,哈哈。

其次,这个项目主要就是 Http 认证鉴权协议的落地实现,所以需要查阅很多权威资料,包括但不限于各种文献、RFC文档、百科,在此期间接触到很多了新的名词、概念。而且需要在理解需求之后将其转化为编码实现。

关于编码方面,设计一个框架,需要考虑到框架的易用性、代码的健壮性、代码的规范性等,能够做好这些,对编码能力有很大的提升。在进行编码的过程中还需要做好规划,那一部分代码编写优先级最高,比如我在编码开始之前就进行了规划安排。

关于 JAP

JAP 是什么?

JAP 是一款开源的登录认证中间件,基于模块化设计,为所有需要登录认证的 WEB 应用提供一套标准的技术解决方案,开发者可以基于 JAP 适配绝大多数的 WEB 系统(自有系统、联邦协议)。

JAP 有哪些功能?

JAP 开源的统一登录认证标准组件 - 包含的功能

JAP 有什么优势?

  • 易用性:JAP 的 API 沿袭 JustAuth 的简单性,做到了开箱即用的程度。JAP 高度抽象各种登录场景,提供了多套简单使用的 API,极大程度的降低了开发者的学习成本和使用成本
  • 全面性:JAP 全量适配 JustAuth 支持的第三方平台,实现第三方登录。同时也支持所有基于标准OAuth2.0 协议或者 OIDC 协议或者 SAML 协议的应用、系统,同时 JAP 还提供不同语言版本的项目 SDK,适配多种研发场景
  • 模块化:JAP 基于模块化设计开发,针对每一种登录场景,比如账号密码、OAuth、OIDC等,都单独提供了独有的模块化解决方案
  • 标准化:JAP 和业务完全解耦,将登录认证相关的逻辑抽象出一套标准的技术解决方案,针对每一种业务场景,比如用户登录、验证密码、创建并绑定第三方系统的账号等,都提供了一套标准的策略或者接口,开发者可以基于 JAP,灵活并方便的完成相关业务逻辑的开发和适配
  • 通用性:JAP 不仅可以用到第三方登录、OAuth授权、OIDC认证等业务场景,还能适配开发者现有的业务系统的普通账号密码的登录场景,基本将所有登录相关的业务场景都已经涵盖。针对 WEB 应用,JAP 将提供满足各种不同登录场景的解决方案(和开发语言无关)

JAP 适用于哪些场景?

JAP 适用于所有需要登录认证功能的场景。比如:

  • 要求规范:新项目立项,你们需要研发一套包含登录、认证的系统,并且从长远方面考虑,你们需要一套标准的、灵活的、功能全面的登录认证功能。
  • 需求灵活:现有登录模块为自研,但是新一轮的技术规划中,你们想将登录认证模块重构,以更加灵活的架构适应后面的新需求,比如:集成 MFA 登录、集成 OAuth 登录、SAML登录等。
  • 力求省事:你们的项目太多(或者是开发语言较多,比如:Java、Python、Node 等),每个项目都需要登录认证模块,想解决这种重复劳动的问题,使研发人员有更多的时间和精力投入到业务开发中,提高研发产能和研发效率。 关于 JAP 的更多内容,可以参考《JAP 产品技术白皮书

相关链接

参考文献

  • RFC7617-The 'Basic' HTTP Authentication Scheme
  • RFC7235-Hypertext Transfer Protocol (HTTP/1.1): Authentication
  • RFC7519-JSON Web Token (JWT)
  • RFC2069-An Extension to HTTP : Digest Access Authentication
  • HTTP 身份验证 - HTTP | MDN (mozilla.org)
  • Other authentication methods - GitHub Docs
  • HTTP摘要认证 - 维基百科,自由的百科全书 (wikipedia.org)