[044][Web模块]基于 Google Authenticator 的 TOTP 双因素认证框架设计与实现

简介: 本项目为Spring Boot 3.x设计的TOTP双因素认证框架,集成Google Authenticator,支持自动配置、请求拦截、二维码绑定及REST管理接口,提供YAML/数据库双凭证仓库,开箱即用且易于扩展。(239字)

[044][Web模块]基于 Google Authenticator 的 TOTP 双因素认证框架设计与实现


在 Web 应用安全领域,双因素认证(2FA)已成为保护用户账户的常见手段。TOTP(基于时间的一次性密码算法)是其中一种主流实现,而 Google Authenticator 则是其经典客户端。本文将介绍一个 Spring Boot 集成方案——tutorials4j-framework-web-google-auth,它封装了 TOTP 服务的自动配置、请求拦截、管理接口等能力,提供开箱即用的双因素认证功能。

一、整体架构与功能概览

该框架基于 com.warrenstrange.googleauth 库,专为 Spring Boot 3.x 设计,包含以下核心能力:

  • 自动配置:根据条件自动创建 GoogleAuthenticator 实例并注入必要的依赖。
  • TOTP 业务服务:封装密钥生成、验证码校验、二维码 URL 生成。
  • 请求过滤器:统一拦截需要 2FA 保护的请求,从请求头读取用户名和验证码并执行校验。
  • 管理接口:提供 REST API 用于生成绑定二维码、测试校验。
  • 凭证仓库扩展:允许从 YAML 配置文件或自定义数据源(如数据库)读取用户密钥。
  • 配置定制:支持调整 TOTP 算法参数(时间步长、窗口大小等)。

下图展示了该框架在 Spring Boot 应用中的位置:

用户请求 → [GoogleAuthRequestFilter] → 校验 TOTP → 业务处理
                ↓ 失败
            抛出异常

二、核心组件分析

1. 自动配置类 GoogleAuthWebConfiguration

该类在类路径存在 GoogleAuthenticator 时生效,负责装配以下 Bean:

Bean 作用
GoogleAuthenticator 核心 TOTP 算法实现,绑定自定义凭证仓库
XICredentialRepository 默认使用 YAML 配置仓库,可被覆盖
GoogleAuthService 业务服务门面
FilterRegistrationBean<GoogleAuthRequestFilter> 注册过滤器,支持自定义匹配路径和顺序

关键代码片段:

@Bean
GoogleAuthenticator googleAuthenticator(XICredentialRepository repository,
                                        ObjectProvider<GoogleAuthenticatorConfigCustomizer> customizers) {
   
    GoogleAuthenticatorConfig config = new GoogleAuthenticatorConfig.Builder().build();
    customizers.orderedStream().forEach(customizer -> customizer.customize(config));
    GoogleAuthenticator authenticator = new GoogleAuthenticator(config);
    authenticator.setCredentialRepository(repository);
    return authenticator;
}

2. 凭证仓库接口 XICredentialRepository

继承自 ICredentialRepository,增加了密码校验方法,为两步验证(密码+TOTP)提供扩展点。

public interface XICredentialRepository extends ICredentialRepository {
   
    boolean verifyPassword(String userName, String password);
}

框架提供了基于 YAML 的内存实现 YamlCredentialRepository,适合小规模固定用户场景。生产环境可自行实现数据库版本。

3. TOTP 业务服务 GoogleAuthService

封装了底层库的调用,简化使用:

  • generateSecretKey():生成随机秘钥。
  • verifyByUserName() / verifyBySecretKey():校验验证码。
  • getQRBarcodeURL():生成 otpauth:// 协议 URL,用于二维码生成。

4. 请求过滤器 GoogleAuthRequestFilter

继承 OncePerRequestFilter,从请求头中获取:

  • X-Google-Auth-Username(或从 SecurityUtils.getAccount() 获取)
  • X-Google-Auth-Code

校验失败抛出 WebFrameworkException,由全局异常处理器转换为 HTTP 响应。校验通过后,将验证码请求头从 RemoveHeaderRequestWrapper 中移除,避免下游再次读取敏感信息。

5. 管理接口 GoogleAuthController

提供两个端点:

端点 方法 功能
/t4j/google-auth/check POST 手动校验用户名和验证码
/t4j/google-auth/generate/qr GET 为用户生成新秘钥并返回二维码图片(PNG)

三、配置说明

在 application.yml 中配置如下:

tutorials4j:
  web:
    google-auth:
      otp-auth-totp-url: "myapp"           # 二维码中显示的应用名称
      credentials:                          # 静态用户列表(仅用于 YAML 仓库)
        - username: admin
          password: admin123
          security-key:                     # 可选,若空则首次生成后自动填充内存
        - username: user1
          password: pass123
      filter:                               # 过滤器配置
        url-patterns:
          - "/api/secure/*"
        order: 1
        name: "googleAuthFilter"
  • otp-auth-totp-url:影响二维码 URI 中的 issuer 参数,客户端扫描后显示为“myapp (username)”。
  • credentials:仅当使用默认的 YamlCredentialRepository 时生效。注意 security-key 字段若为空,首次调用 generateSecretKey 会生成并保存在内存 Map 中,不会写回配置文件。生产环境建议实现数据库仓库。
  • filter:通过 ServletFilterOptions 配置拦截路径、过滤器顺序和名称。

四、使用流程

1. 用户首次绑定

  1. 前端调用 GET /t4j/google-auth/generate/qr?username=admin。
  2. 后端生成新秘钥,并返回二维码图片。
  3. 用户使用 Google Authenticator 等 App 扫描二维码,完成绑定。

2. 登录/受保护接口调用

客户端在后续请求的 Header 中携带:

X-Google-Auth-Username: admin
X-Google-Auth-Code: 123456

过滤器自动校验,通过后放行;校验失败抛出异常,前端可捕获并提示。

五、扩展与定制

1. 调整 TOTP 算法参数

实现 GoogleAuthenticatorConfigCustomizer Bean:

@Component
public class MyConfigCustomizer implements GoogleAuthenticatorConfigCustomizer {
   
    @Override
    public void customize(GoogleAuthenticatorConfig config) {
   
        config.setTimeStepSizeInMillis(30000);  // 30秒步长
        config.setWindowSize(2);                // 允许前后一个时间窗口
    }
}

2. 自定义凭证仓库(例如数据库)

实现 XICredentialRepository,并声明为 @Primary 或 @Component,框架将自动使用你的实现而非 YAML 版本。

@Component
public class DatabaseCredentialRepository implements XICredentialRepository {
   
    // 实现 getSecretKey, saveUserCredentials, verifyPassword
}

3. 动态获取当前用户名

默认过滤器优先从请求头获取用户名,若为空则调用 SecurityUtils.getAccount()。你可以修改该工具类以适配自己的认证上下文(如 Spring Security)。

六、总结

该框架通过 Spring Boot 自动配置将 Google Authenticator 无缝集成到 Web 应用中,具有以下优点:

  • 开箱即用:提供默认的 YAML 配置驱动,适合快速原型或小规模内网应用。
  • 安全设计:过滤器校验后自动删除验证码请求头,避免泄露;支持密码 + TOTP 双重校验扩展。
  • 灵活扩展:支持算法参数定制、凭证仓库热插拔,满足不同部署环境。
  • 开发友好:内置管理接口,方便测试和用户绑定。

在实际生产环境中,建议将凭证仓库改为数据库实现,并配合 Spring Security 等权限框架,将 TOTP 校验作为第二道防线。

通过本文的讲解,相信读者可以快速理解并集成该 TOTP 认证方案,构建更安全的 Web 应用。

目录
相关文章
|
2月前
|
JSON 安全 Java
[024][Web模块]基于 AntiSamy 的 Spring Boot XSS 防护实践:从过滤器到反序列化的多层防御
本文介绍基于OWASP AntiSamy的Spring Boot XSS多层防护方案:通过Servlet过滤器清洗表单/查询参数,结合Jackson反序列化器净化JSON数据,实现非侵入、全覆盖的输入清洗,业务代码零修改。(239字)
393 2
|
监控 物联网 应用服务中间件
流媒体方案之Nginx——实现物联网视频监控项目
流媒体方案之Nginx——实现物联网视频监控项目
流媒体方案之Nginx——实现物联网视频监控项目
|
2月前
|
SQL Java 数据库连接
[026][数据模块]基于 MyBatis Plus 的企业级数据访问框架设计与实现
本文介绍基于MyBatis Plus二次封装的企业级数据访问框架,支持多租户隔离、分页、乐观锁、SQL防攻击及审计字段自动填充。通过有序拦截器链、条件化配置与开放扩展点,实现可插拔、易维护的统一数据访问能力。(239字)
181 2
|
2月前
|
算法 Java 数据安全/隐私保护
[045][Crypto模块]设计一个可扩展的加解密框架:策略模式与工厂模式实战
本文基于Spring Boot,运用策略模式与工厂模式设计可扩展加解密框架:统一`CryptoProcessor`接口封装AES、RSA、SM2等算法;通过`CryptoProcessorFactory`按枚举类别自动注册/查找处理器;结合Spring自动装配,新增算法(如SM9)仅需实现接口并声明Bean,零侵入扩展。高内聚、低耦合、易维护。(239字)
196 2
|
2月前
|
JSON 前端开发 Java
[048][Crypto模块]Spring Boot 请求体自动解密:@Crypto 注解 + RequestBodyAdvice 实现
本文介绍基于Spring Boot的请求体自动解密方案:通过自定义`@Crypto`注解与`RequestBodyAdvice`,在Controller入参前透明解密RSA/SM2加密的JSON请求体,实现业务代码零侵入、算法可插拔、开关灵活的安全传输机制。(239字)
198 1
|
2月前
|
算法 安全 Java
[047][Crypto模块]基于 Hutool 的常见加解密算法封装与密钥自动生成
本文基于Hutool封装统一加解密框架,提供AES/RSA/SM2/SM4/HMAC等算法的`CryptoProcessor`标准接口,支持密钥自动生成与动态切换,解耦业务代码,兼顾国密合规与易用性,提升安全性与可测试性。(239字)
148 1
|
2月前
|
设计模式 Java Spring
[046][Crypto模块]Spring Boot 自动配置进阶:按需装配加解密处理器
本文详解Spring Boot自动配置进阶实践:基于Crypto模块,通过`@ConditionalOnMissingBean`、`@EnableConfigurationProperties`等注解,实现加解密处理器的按需装配与灵活覆盖。涵盖配置属性绑定、多配置类拆分、条件加载(Web/非Web)、日志调试及Hutool集成,助力构建高可扩展Starter。
200 2
|
2月前
|
缓存 监控 安全
[025][Web模块]基于 Spring Boot 的请求日志过滤器设计与实现
本文介绍基于Spring Boot的可配置请求日志过滤器,通过自定义`WebHttpProperties`、扩展`CommonsRequestLoggingFilter`及自动配置类,支持时间戳、客户端信息、请求头/体记录、动态前缀等灵活配置,开箱即用,兼顾可维护性与生产安全性。(239字)
433 1
|
2月前
|
设计模式 缓存 安全
[043][数据模块]基于 Spring Data JPA 的企业级数据访问层设计——实体、审计、状态与服务抽象
本项目基于Spring Data JPA构建企业级数据访问层,通过分层接口(Entity/IdEntity/AuditingEntity/StatusEntity)与抽象基类(BaseEntity/BaseService),统一处理主键生成、乐观锁、审计字段、数据状态及CRUD逻辑,显著减少样板代码,提升可维护性与复用性。(239字)
251 1
|
2月前
|
算法 NoSQL Java
[022][数据模块]基于雪花算法的 MyBatis-Plus 主键生成器设计与实现
本项目基于Hutool雪花算法,为MyBatis-Plus定制轻量级分布式主键生成器,含`SnowflakeUtils`(单例+JVM参数配置)、`DefaultIdentifierGenerator`(无缝接入MP)及自动配置类,支持全局有序、高性能ID生成,已落地多个微服务系统。(239字)
383 1

热门文章

最新文章