feat: 实现SSO单点登录+应用接入管理功能 (Issue #46)
- 新增OAuth2.0授权框架支持 - 实现SSO单点登录核心功能 - 添加第三方应用注册和管理 - 完整的权限控制和审计日志 - 支持多种OAuth2授权模式 - JWT Token认证和会话管理 - 数据库表结构和初始化脚本 - 单元测试覆盖 - 更新RevenueBaseService保持向后兼容 🎯 解决Issue #46: [营收] SSO 单点登录 + 应用接入管理
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
-- SSO单点登录表结构
|
||||
-- 创建SSO令牌表
|
||||
CREATE TABLE IF NOT EXISTS sso_token (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
user_id VARCHAR(50) NOT NULL,
|
||||
username VARCHAR(100) NOT NULL,
|
||||
token VARCHAR(500) NOT NULL,
|
||||
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
expire_time TIMESTAMP NOT NULL,
|
||||
status INTEGER DEFAULT 1,
|
||||
last_use_time TIMESTAMP,
|
||||
INDEX idx_token (token),
|
||||
INDEX idx_user_id (user_id),
|
||||
INDEX idx_expire_time (expire_time)
|
||||
);
|
||||
|
||||
-- 创建应用注册表
|
||||
CREATE TABLE IF NOT EXISTS app_registry (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
app_name VARCHAR(100) NOT NULL UNIQUE,
|
||||
app_key VARCHAR(200) NOT NULL UNIQUE,
|
||||
app_secret VARCHAR(500) NOT NULL,
|
||||
redirect_uri VARCHAR(500) NOT NULL,
|
||||
description TEXT,
|
||||
status INTEGER DEFAULT 1,
|
||||
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
admin_user VARCHAR(100),
|
||||
INDEX idx_app_key (app_key),
|
||||
INDEX idx_status (status)
|
||||
);
|
||||
|
||||
-- 创建SSO访问日志表
|
||||
CREATE TABLE IF NOT EXISTS sso_access_log (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
user_id VARCHAR(50),
|
||||
username VARCHAR(100),
|
||||
app_name VARCHAR(100),
|
||||
action VARCHAR(50) NOT NULL, -- login, logout, validate, token_exchange
|
||||
ip_address VARCHAR(50),
|
||||
user_agent TEXT,
|
||||
token_used VARCHAR(500),
|
||||
status INTEGER DEFAULT 1, -- 1:成功, 0:失败
|
||||
error_message TEXT,
|
||||
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
INDEX idx_user_id (user_id),
|
||||
INDEX idx_username (username),
|
||||
INDEX idx_app_name (app_name),
|
||||
INDEX idx_create_time (create_time)
|
||||
);
|
||||
|
||||
-- 创建应用接入记录表
|
||||
CREATE TABLE IF NOT EXISTS app_access_log (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
app_key VARCHAR(200) NOT NULL,
|
||||
app_name VARCHAR(100) NOT NULL,
|
||||
client_id VARCHAR(200),
|
||||
action VARCHAR(50) NOT NULL, -- register, validate, auth, token_request
|
||||
ip_address VARCHAR(50),
|
||||
user_agent TEXT,
|
||||
request_data TEXT,
|
||||
response_data TEXT,
|
||||
status INTEGER DEFAULT 1,
|
||||
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
INDEX idx_app_key (app_key),
|
||||
INDEX idx_create_time (create_time)
|
||||
);
|
||||
|
||||
-- 创建权限配置表
|
||||
CREATE TABLE IF NOT EXISTS app_permission (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
app_key VARCHAR(200) NOT NULL,
|
||||
permission_name VARCHAR(100) NOT NULL,
|
||||
permission_code VARCHAR(200) NOT NULL,
|
||||
resource_type VARCHAR(50), -- api, menu, button
|
||||
resource_id VARCHAR(200),
|
||||
is_enabled INTEGER DEFAULT 1,
|
||||
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY uk_app_key_permission (app_key, permission_code),
|
||||
INDEX idx_app_key (app_key),
|
||||
INDEX idx_permission_code (permission_code)
|
||||
);
|
||||
|
||||
-- 创建Token刷新记录表
|
||||
CREATE TABLE IF NOT EXISTS refresh_token (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
user_id VARCHAR(50) NOT NULL,
|
||||
username VARCHAR(100) NOT NULL,
|
||||
access_token VARCHAR(500) NOT NULL,
|
||||
refresh_token VARCHAR(500) NOT NULL,
|
||||
client_id VARCHAR(200) NOT NULL,
|
||||
scope VARCHAR(500),
|
||||
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
expire_time TIMESTAMP NOT NULL,
|
||||
last_use_time TIMESTAMP,
|
||||
is_revoked INTEGER DEFAULT 0,
|
||||
INDEX idx_access_token (access_token),
|
||||
INDEX idx_refresh_token (refresh_token),
|
||||
INDEX idx_user_id (user_id),
|
||||
INDEX idx_client_id (client_id)
|
||||
);
|
||||
|
||||
-- 插入默认的OAuth2客户端配置
|
||||
INSERT INTO app_registry (app_name, app_key, app_secret, redirect_uri, description, admin_user) VALUES
|
||||
('营收管理前端', 'revenue-frontend', 'revenue-frontend-secret-2026', 'http://localhost:3000/oauth/callback', '营收管理平台前端应用', 'admin'),
|
||||
('微信网厅', 'wechat-mall', 'wechat-mall-secret-2026', 'http://localhost:8080/wechat/callback', '微信网上营业厅应用', 'admin'),
|
||||
('移动端应用', 'mobile-app', 'mobile-app-secret-2026', 'http://localhost:4000/auth/callback', '移动端应用', 'admin')
|
||||
ON CONFLICT (app_name) DO NOTHING;
|
||||
|
||||
-- 创建SSO触发器:自动清理过期Token
|
||||
CREATE OR REPLACE FUNCTION clean_expired_tokens()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
DELETE FROM sso_token WHERE expire_time < NOW();
|
||||
DELETE FROM refresh_token WHERE expire_time < NOW();
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
-- 创建SSO触发器:当插入token时更新最后使用时间
|
||||
CREATE OR REPLACE FUNCTION update_last_use_time()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
IF NEW.status = 1 THEN
|
||||
UPDATE sso_token SET last_use_time = NOW()
|
||||
WHERE token = NEW.token AND id != NEW.id;
|
||||
END IF;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
-- 创建触发器
|
||||
CREATE TRIGGER trigger_clean_expired_tokens
|
||||
BEFORE INSERT OR UPDATE OR DELETE ON sso_token
|
||||
EXECUTE FUNCTION clean_expired_tokens();
|
||||
|
||||
CREATE TRIGGER trigger_update_last_use_time
|
||||
AFTER UPDATE ON sso_token
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION update_last_use_time();
|
||||
Reference in New Issue
Block a user