feat: 优化passkey模块配置和依赖管理

This commit is contained in:
Spock12138 2025-09-11 16:25:12 +08:00
parent 7a064e495a
commit c0d02e29e1
5 changed files with 53 additions and 296 deletions

View File

@ -6,29 +6,10 @@ dependencies {
implementation project(":maxkey-commons:maxkey-common") implementation project(":maxkey-commons:maxkey-common")
implementation project(":maxkey-commons:maxkey-crypto") implementation project(":maxkey-commons:maxkey-crypto")
implementation project(":maxkey-commons:maxkey-ldap")
implementation project(":maxkey-commons:maxkey-core") implementation project(":maxkey-commons:maxkey-core")
implementation project(":maxkey-entity") implementation project(":maxkey-entity")
implementation project(":maxkey-persistence") implementation project(":maxkey-persistence")
implementation project(":maxkey-authentications:maxkey-authentication-core") implementation project(":maxkey-authentications:maxkey-authentication-core")
implementation project(":maxkey-authentications:maxkey-authentication-provider") implementation project(":maxkey-authentications:maxkey-authentication-provider")
// WebAuthn library for Passkey support }
implementation "com.webauthn4j:webauthn4j-core:${webauthn4jVersion}"
implementation "com.webauthn4j:webauthn4j-util:${webauthn4jVersion}"
// WebAuthn4J
implementation "com.fasterxml.jackson.core:jackson-core:${jacksonVersion}"
implementation "com.fasterxml.jackson.core:jackson-databind:${jacksonVersion}"
implementation "com.fasterxml.jackson.core:jackson-annotations:${jacksonVersion}"
implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:${jacksonVersion}"
implementation "commons-codec:commons-codec:${commonscodecVersion}"
implementation "org.bouncycastle:bcprov-jdk18on:${bouncycastleVersion}"
implementation "org.bouncycastle:bcpkix-jdk18on:${bouncycastleVersion}"
implementation "org.slf4j:slf4j-api:${slf4jVersion}"
//
implementation "org.apache.commons:commons-lang3:${commonslang3Version}"
}
configurations.all { transitive = false }

View File

@ -1,4 +0,0 @@
# Spring Boot 2.x 兼容性配置
# 自动配置类
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.dromara.maxkey.passkey.autoconfigure.PasskeyAutoConfiguration

View File

@ -1,165 +0,0 @@
# MaxKey Passkey 模块配置示例
# 将此配置添加到主应用的 application.yml 中
maxkey:
passkey:
# 是否启用 Passkey 功能
enabled: true
# RP (Relying Party) 配置
relying-party:
# RP 名称,显示给用户
name: "MaxKey"
# RP ID通常是域名生产环境必须配置为实际域名
id: "localhost"
# RP 图标 URL可选
icon: "/static/images/maxkey-logo.png"
# 认证器配置
authenticator:
# 认证器附件偏好platform平台认证器, cross-platform跨平台认证器, null无偏好
attachment: "platform"
# 用户验证要求required必需, preferred首选, discouraged不鼓励
user-verification: "required"
# 证明偏好none, indirect间接, direct直接
attestation: "none"
# 是否要求驻留密钥(可发现凭据)
require-resident-key: false
# 挑战配置
challenge:
# 挑战长度(字节)
length: 32
# 挑战过期时间(分钟)
expire-minutes: 5
# 操作超时时间(毫秒)
timeout-ms: 60000
# 是否自动清理过期挑战
auto-cleanup: true
# 清理间隔(小时)
cleanup-interval-hours: 1
# 用户限制配置
user-limits:
# 每个用户最大 Passkey 数量
max-passkeys-per-user: 5
# 是否允许重复注册相同设备
allow-duplicate-devices: false
# 会话配置
session:
# 认证会话过期时间(分钟)
auth-session-expire-minutes: 30
# 是否启用会话管理
enabled: true
# 日志配置(可选)
logging:
level:
# Passkey 模块日志级别
org.dromara.maxkey.passkey: INFO
# WebAuthn 相关日志
com.webauthn4j: WARN
# 数据源配置(如果使用独立数据源)
# spring:
# datasource:
# passkey:
# url: jdbc:mysql://localhost:3306/maxkey_passkey
# username: maxkey
# password: maxkey
# driver-class-name: com.mysql.cj.jdbc.Driver
# 缓存配置(可选,用于挑战缓存)
# spring:
# cache:
# type: redis
# redis:
# host: localhost
# port: 6379
# database: 1
# timeout: 2000ms
# lettuce:
# pool:
# max-active: 8
# max-idle: 8
# min-idle: 0
# 安全配置
security:
# CORS 配置(如果需要跨域支持)
cors:
allowed-origins:
- "https://your-domain.com"
- "http://localhost:3000" # 开发环境
allowed-methods:
- GET
- POST
- PUT
- DELETE
- OPTIONS
allowed-headers:
- "*"
allow-credentials: true
# 监控配置(可选)
management:
endpoints:
web:
exposure:
include:
- health
- info
- metrics
- passkey # 自定义 Passkey 监控端点
endpoint:
health:
show-details: when-authorized
metrics:
tags:
application: maxkey-passkey
# 生产环境配置示例
---
spring:
profiles: production
maxkey:
passkey:
relying-party:
# 生产环境必须使用实际域名
id: "auth.yourcompany.com"
name: "Your Company SSO"
authenticator:
# 生产环境建议使用更严格的验证
user-verification: "required"
attestation: "indirect"
challenge:
# 生产环境可以使用更短的过期时间
expire-minutes: 3
timeout-ms: 30000
session:
# 生产环境可以使用更短的会话时间
auth-session-expire-minutes: 15
# 开发环境配置示例
---
spring:
profiles: development
maxkey:
passkey:
relying-party:
id: "localhost"
authenticator:
# 开发环境可以放宽验证要求
user-verification: "preferred"
challenge:
# 开发环境使用更长的过期时间便于调试
expire-minutes: 10
timeout-ms: 120000
logging:
level:
org.dromara.maxkey.passkey: DEBUG
root: INFO

View File

@ -1,107 +0,0 @@
-- Passkey模块数据库表结构
-- 用于存储用户Passkey凭据和认证挑战信息
-- 用户Passkey凭据表
CREATE TABLE mxk_user_passkeys (
ID VARCHAR(40) NOT NULL,
USER_ID VARCHAR(40) NOT NULL COMMENT '用户ID',
CREDENTIAL_ID VARCHAR(1024) NOT NULL COMMENT 'WebAuthn凭据ID',
PUBLIC_KEY TEXT NOT NULL COMMENT '公钥信息',
SIGNATURE_COUNT BIGINT DEFAULT 0 COMMENT '签名计数器',
AAGUID VARCHAR(100) COMMENT '认证器AAGUID',
DISPLAY_NAME VARCHAR(200) COMMENT '显示名称',
DEVICE_TYPE VARCHAR(50) DEFAULT 'platform' COMMENT '设备类型platform/cross-platform',
CREATED_DATE DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
LAST_USED_DATE DATETIME COMMENT '最后使用时间',
STATUS INT DEFAULT 1 COMMENT '状态0-禁用1-启用',
INST_ID VARCHAR(40) DEFAULT '1' COMMENT '机构ID',
PRIMARY KEY (ID),
UNIQUE KEY UK_USER_CREDENTIAL (USER_ID, CREDENTIAL_ID),
KEY IDX_USER_ID (USER_ID),
KEY IDX_CREDENTIAL_ID (CREDENTIAL_ID(255)),
KEY IDX_STATUS (STATUS),
KEY IDX_INST_ID (INST_ID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户Passkey凭据表';
-- 添加索引优化查询性能
CREATE INDEX IDX_USER_STATUS ON mxk_user_passkeys(USER_ID, STATUS);
CREATE INDEX IDX_CREATED_DATE ON mxk_user_passkeys(CREATED_DATE);
CREATE INDEX IDX_LAST_USED ON mxk_user_passkeys(LAST_USED_DATE);
-- Passkey认证挑战表
CREATE TABLE mxk_passkey_challenges (
ID VARCHAR(40) NOT NULL,
USER_ID VARCHAR(40) COMMENT '用户ID可为空支持无用户名登录',
CHALLENGE VARCHAR(1024) NOT NULL COMMENT '挑战字符串',
CHALLENGE_TYPE VARCHAR(20) NOT NULL COMMENT '挑战类型REGISTRATION/AUTHENTICATION',
SESSION_ID VARCHAR(100) COMMENT '会话ID',
CREATED_DATE DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
EXPIRE_DATE DATETIME NOT NULL COMMENT '过期时间',
STATUS INT DEFAULT 0 COMMENT '状态0-未使用1-已使用',
INST_ID VARCHAR(40) DEFAULT '1' COMMENT '机构ID',
PRIMARY KEY (ID),
KEY IDX_USER_ID (USER_ID),
KEY IDX_CHALLENGE_TYPE (CHALLENGE_TYPE),
KEY IDX_SESSION_ID (SESSION_ID),
KEY IDX_EXPIRE_DATE (EXPIRE_DATE),
KEY IDX_STATUS (STATUS),
KEY IDX_INST_ID (INST_ID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Passkey认证挑战表';
-- 添加复合索引优化查询
CREATE INDEX IDX_CHALLENGE_STATUS ON mxk_passkey_challenges(CHALLENGE_TYPE, STATUS);
CREATE INDEX IDX_USER_TYPE ON mxk_passkey_challenges(USER_ID, CHALLENGE_TYPE);
CREATE INDEX IDX_EXPIRE_STATUS ON mxk_passkey_challenges(EXPIRE_DATE, STATUS);
-- 为现有用户表添加Passkey相关字段可选方案
-- 如果选择在现有mxk_userinfo表中添加字段可以使用以下SQL
/*
ALTER TABLE mxk_userinfo ADD COLUMN PASSKEY_ENABLED INT DEFAULT 0 COMMENT 'Passkey功能是否启用0-禁用1-启用';
ALTER TABLE mxk_userinfo ADD COLUMN PASSKEY_COUNT INT DEFAULT 0 COMMENT '用户Passkey数量';
ALTER TABLE mxk_userinfo ADD COLUMN LAST_PASSKEY_LOGIN DATETIME COMMENT '最后一次Passkey登录时间';
-- 添加索引
CREATE INDEX IDX_PASSKEY_ENABLED ON mxk_userinfo(PASSKEY_ENABLED);
CREATE INDEX IDX_LAST_PASSKEY_LOGIN ON mxk_userinfo(LAST_PASSKEY_LOGIN);
*/
-- 创建清理过期挑战的存储过程
DELIMITER //
CREATE PROCEDURE CleanExpiredPasskeyChallenges()
BEGIN
DECLARE affected_rows INT DEFAULT 0;
-- 删除过期的挑战记录
DELETE FROM mxk_passkey_challenges
WHERE EXPIRE_DATE < NOW();
-- 获取影响的行数
SET affected_rows = ROW_COUNT();
-- 记录清理结果
SELECT CONCAT('Cleaned ', affected_rows, ' expired passkey challenges') AS result;
END //
DELIMITER ;
-- 创建定时清理事件(可选)
/*
CREATE EVENT IF NOT EXISTS CleanPasskeyChallengesEvent
ON SCHEDULE EVERY 1 HOUR
DO
CALL CleanExpiredPasskeyChallenges();
*/
-- 插入一些示例数据(仅用于测试)
/*
INSERT INTO mxk_user_passkeys (
ID, USER_ID, CREDENTIAL_ID, PUBLIC_KEY, DISPLAY_NAME, DEVICE_TYPE, INST_ID
) VALUES (
'test-passkey-001',
'admin',
'test-credential-id-001',
'test-public-key-data',
'Test Passkey Device',
'platform',
'1'
);
*/

View File

@ -0,0 +1,52 @@
-- MaxKey Passkey 模块数据库表创建脚本
-- 创建用户 Passkey 表和挑战表
-- 用户 Passkey 表
CREATE TABLE IF NOT EXISTS mxk_user_passkeys (
id VARCHAR(40) NOT NULL COMMENT '主键ID',
user_id VARCHAR(40) NOT NULL COMMENT '用户ID',
credential_id VARCHAR(500) NOT NULL COMMENT '凭据IDBase64编码',
public_key TEXT NOT NULL COMMENT '公钥数据Base64编码',
display_name VARCHAR(100) COMMENT '显示名称',
device_type VARCHAR(50) DEFAULT 'unknown' COMMENT '设备类型',
signature_count BIGINT DEFAULT 0 COMMENT '签名计数器',
created_date DATETIME NOT NULL COMMENT '创建时间',
last_used_date DATETIME COMMENT '最后使用时间',
aaguid VARCHAR(100) COMMENT 'AAGUID',
inst_id VARCHAR(40) DEFAULT '1' COMMENT '机构ID',
status INT DEFAULT 1 COMMENT '状态1-正常0-禁用',
PRIMARY KEY (id),
UNIQUE KEY uk_credential_id (credential_id),
KEY idx_user_id (user_id),
KEY idx_inst_id (inst_id),
KEY idx_created_date (created_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户Passkey凭据表';
-- Passkey 挑战表
CREATE TABLE IF NOT EXISTS mxk_passkey_challenges (
id VARCHAR(40) NOT NULL COMMENT '挑战ID',
user_id VARCHAR(40) COMMENT '用户ID认证时可为空',
challenge TEXT NOT NULL COMMENT '挑战数据Base64编码',
challenge_type VARCHAR(20) NOT NULL COMMENT '挑战类型REGISTRATION-注册AUTHENTICATION-认证',
created_date DATETIME NOT NULL COMMENT '创建时间',
expires_date DATETIME NOT NULL COMMENT '过期时间',
status INT DEFAULT 0 COMMENT '状态0-未使用1-已使用',
inst_id VARCHAR(40) DEFAULT '1' COMMENT '机构ID',
PRIMARY KEY (id),
KEY idx_user_id (user_id),
KEY idx_challenge_type (challenge_type),
KEY idx_expires_date (expires_date),
KEY idx_inst_id (inst_id),
KEY idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Passkey挑战表';
-- 创建索引以优化查询性能
CREATE INDEX idx_user_passkeys_user_status ON mxk_user_passkeys(user_id, status);
CREATE INDEX idx_passkey_challenges_expires_status ON mxk_passkey_challenges(expires_date, status);
CREATE INDEX idx_passkey_challenges_user_type ON mxk_passkey_challenges(user_id, challenge_type);
-- 插入示例数据(可选)
-- INSERT INTO mxk_user_passkeys (id, user_id, credential_id, public_key, display_name, device_type, signature_count, created_date, inst_id)
-- VALUES ('test_passkey_1', 'test_user_1', 'test_credential_id_1', 'test_public_key_1', 'Test Device', 'platform', 0, NOW(), '1');
COMMIT;