- 新增OAuth2.0授权框架支持 - 实现SSO单点登录核心功能 - 添加第三方应用注册和管理 - 完整的权限控制和审计日志 - 支持多种OAuth2授权模式 - JWT Token认证和会话管理 - 数据库表结构和初始化脚本 - 单元测试覆盖 - 更新RevenueBaseService保持向后兼容 🎯 解决Issue #46: [营收] SSO 单点登录 + 应用接入管理
141 lines
4.8 KiB
PL/PgSQL
141 lines
4.8 KiB
PL/PgSQL
-- 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(); |