什么是 Passkeys?
Passkeys 是一种基于 WebAuthn 标准的现代认证方式,它提供了比传统密码更安全的身份验证机制。Spring Security 6.4 版本引入了对 Passkeys 的原生支持,让开发者能够轻松地在应用中实现无密码认证。
主要优势
- 更高的安全性:使用密码学技术,避免了传统密码易被盗取的风险
- 更好的用户体验:用户无需记忆复杂密码
- 防钓鱼:Passkeys 与特定域名绑定,有效防止钓鱼攻击
- 跨平台支持:可以在不同设备间同步使用
Passkey 认证流程
注册流程图
1 2 3 4 5 6 7 8 9 10 11 12 13
| sequenceDiagram participant U as 用户 participant C as 客户端 participant S as 服务器 U->>C: 触发注册 C->>S: 请求注册选项 (POST /webauthn/register/options) S-->>C: 返回注册选项 (challenge, rpId等) C->>U: 请求生物认证 U->>C: 完成生物认证 C->>S: 提交凭证 (POST /webauthn/register) S-->>C: 注册成功响应 C->>U: 显示注册成功
|
验证流程图
1 2 3 4 5 6 7 8 9 10 11 12 13
| sequenceDiagram participant U as 用户 participant C as 客户端 participant S as 服务器 U->>C: 触发登录 C->>S: 请求验证选项 (POST /webauthn/authenticate/options) S-->>C: 返回验证选项 (challenge等) C->>U: 请求生物认证 U->>C: 完成生物认证 C->>S: 提交验证信息 (POST /login/webauthn) S-->>C: 验证成功,返回Token/Session C->>U: 登录成功,跳转首页
|
实现步骤
1. 添加依赖
首先需要在项目中添加必要的依赖:
1 2 3 4 5 6 7 8 9
| <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> </dependency> <dependency> <groupId>com.webauthn4j</groupId> <artifactId>webauthn4j-core</artifactId> <version>${webauthn4j-core-version}</version> </dependency>
|
2. 配置 Passkeys
在 Spring Security 配置中启用 Passkeys:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @Bean SecurityFilterChain filterChain(HttpSecurity http) { http .formLogin(withDefaults()) .webAuthn((webAuthn) -> webAuthn .rpName("Your Application Name") .rpId("your-domain.com") .allowedOrigins("https://your-domain.com") ); return http.build(); }
@Bean UserDetailsService userDetailsService() { UserDetails userDetails = User.withDefaultPasswordEncoder() .username("user") .password("password") .roles("USER") .build(); return new InMemoryUserDetailsManager(userDetails); }
|
3. 注册新凭证
Passkeys 的使用需要两个步骤:
- 注册新凭证
- 验证凭证
注册流程
- 请求注册选项:
1 2
| POST /webauthn/register/options X-CSRF-TOKEN: <your-csrf-token>
|
- 使用返回的选项创建凭证:
1 2 3 4
| const credential = await navigator.credentials.create({ publicKey: publicKeyCredentialCreationOptions });
|
- 将创建的凭证发送到服务器注册:
1 2 3 4 5 6 7 8 9
| POST /webauthn/register { "publicKey": { "credential": { // 凭证详细信息 }, "label": "my-passkey" } }
|
4. 验证凭证
验证过程同样包含两个步骤:
- 请求验证选项:
1 2
| POST /webauthn/authenticate/options X-CSRF-TOKEN: <your-csrf-token>
|
- 验证凭证:
1 2 3 4
| POST /login/webauthn { // 凭证验证信息 }
|
最佳实践
- 始终使用 HTTPS
- 实现适当的错误处理
- 提供清晰的用户指导
- 考虑提供备用认证方式
- 正确配置允许的源(Origins)
总结
Spring Security 6.4 的 Passkeys 支持为开发者提供了实现现代化、安全的认证机制的便捷方式。通过简单的配置,就能为应用添加无密码认证能力,提升安全性的同时改善用户体验。
参考资料