Skip to content

开放接口签名认证

采用抽象责任链模式实现开放接口的多步骤签名认证流程。通过将认证过程拆分为多个独立处理阶段,每个阶段职责单一,支持灵活扩展与维护。


一、责任链基础抽象

BaseVerifyHandle 抽象类

  • 定义了责任链中处理器的统一基类。
  • 使用 nextHandle 属性维护链式结构,通过 setNextHandle() 方法实现处理器串联。
  • 提供 handleRequest(SignatureContext context) 抽象方法,由子类实现具体逻辑。
  • 提供 next(context) 工具方法,用于触发链中下一个处理器,简化调用逻辑。

关键特性

  • 支持链式调用,解耦处理逻辑与流程控制。
  • @Setter 注解自动生成 setNextHandle 方法,便于链的组装。

二、具体处理器实现

所有处理器均继承自 BaseVerifyHandle,按职责划分如下:

1. ParameterHandle(参数预处理)

  • 职责:解析并规范化签名所需参数,如参数提取、排序、过滤等。
  • 后续节点:交由签名处理器进行本地签名生成。

2. SignatureHandle(本地签名生成)

  • 依赖apiClientsService, redisCache, redisson
  • 职责:
    • 获取客户端密钥信息;
    • 解密客户端传输的安全数据;
    • 拼接标准签名字符串;
    • 执行本地签名算法(如 HMAC-SHA256)。
  • 后续节点:进入验证阶段。

3. VerifyHandle(签名验证)

  • 职责:
    • 验证时间戳合法性(防重放攻击);
    • 比对客户端签名与本地签名;
    • 校验客户端身份信息完整性;
    • 检查客户端状态(是否禁用等)。
  • 后续节点:进入权限校验。

4. PermissionHandle(权限校验)

  • 依赖apiActionsService

  • 职责:

    • 查询请求动作(action)的访问控制策略;
    • 判断当前接口是否支持匿名访问;
    • 验证客户端(App)是否具备执行该操作的权限。

三、责任链组装逻辑

verifySignature 方法中完成责任链的动态构建与执行:

组装顺序

  1. ParameterHandle
  2. SignatureHandle
  3. VerifyHandle
  4. PermissionHandle

执行流程

  • 构建 SignatureContext 上下文对象,封装请求动作与 HTTP 请求。
  • 逐级设置 nextHandle,形成完整处理链条。
  • 从首节点 parameterHandle 触发 handleRequest,流程自动向后传递。

抽象责任链

java
@Setter
public abstract class BaseVerifyHandle {
    /**
     * -- SETTER --
     *  设置下一个处理器
     *
     * @param nextHandle  下一个处理器
     */
    protected BaseVerifyHandle nextHandle;

    /**
     * 处理请求
     * @param context 签名上下文
     * @return
     */
    public abstract void handleRequest(SignatureContext context);
    // 进行签名


    public void next(SignatureContext context) {
        if (nextHandle != null) {
            nextHandle.handleRequest(context);
        }
    }
}

责任链具体实现

java

@Slf4j
@AllArgsConstructor
public class ParameterHandle extends BaseVerifyHandle {

    /**
     * 处理请求
     *
     * @param context 签名上下文
     * @return
     */
    @Override
    public void handleRequest(SignatureContext context) {
        // ... 签名参数解析 排序等等操作
        next(context);
    }
}
java

@AllArgsConstructor
@Slf4j
public class PermissionHandle extends BaseVerifyHandle {

    @Override
    public void handleRequest(SignatureContext context) {
        // ...获取请求动作详情 是否支持匿名 检查app客户端是否有该权限
        next(context);
    }
}
java
@Slf4j
@AllArgsConstructor
public class SignatureHandle extends BaseVerifyHandle {

    /**
     * 处理请求
     *
     * @param context 签名上下文
     * @return
     */
    @Override
    public void handleRequest(SignatureContext context) {
        //... 进行本地签名 拼接签名参数 读取app客户端信息  解密客户端信息 本地签名
        next(context);
    }
}
java
@Slf4j
public class VerifyHandle extends BaseVerifyHandle {
  
    @Override
    public void handleRequest(SignatureContext context) {
        // 时间戳验证 签名比对 校验客户端信息 客户端状态
        next(context);
    }
}

责任链组装

java
    /**
     * 验证签名
     *
     * @param action             请求动作
     * @param currentHttpRequest
     */
    private void verifySignature(String action, HttpServletRequest currentHttpRequest) {
        // 初始化签名参数对象
        SignatureContext context = new SignatureContext();
        // 设置请求动作
        context.setAction(action);
        context.setRequest(currentHttpRequest);
        // 责任链验证 参数初始化操作
        ParameterHandle parameterHandle = new ParameterHandle();
        // 签名操作
        SignatureHandle signatureHandle = new SignatureHandle(apiClientsService, redisCache, redisson);
        parameterHandle.setNextHandle(signatureHandle);
        // 验证操作
        VerifyHandle verifyHandle = new VerifyHandle();
        signatureHandle.setNextHandle(verifyHandle);
        // 权限操作
        PermissionHandle permissionHandle = new PermissionHandle(apiActionsService);
        verifyHandle.setNextHandle(permissionHandle);
        // 执行责任链
        parameterHandle.handleRequest(context);
    }
最近更新