配置主从域名网站单点登录
基本概念与准备
主从域名(Primary Domain & Secondary Domain)是指同一应用下,主域名作为核心认证中心(如main.com),从域名(如sub.main.com)作为业务子域,单点登录(SSO)的核心目标是让用户只需一次登录,即可访问所有关联域名下的资源,提升用户体验与安全性。

核心流程
用户访问从域名网站时,系统会重定向至主域名的SSO认证中心完成身份验证;认证成功后,认证中心返回授权令牌(如JWT),从域名通过该令牌验证用户身份,无需重复登录。
准备工作
- 环境准备:
- 主域名服务器(部署认证服务器,如Keycloak)、从域名服务器(部署业务网站,如Nginx+PHP/Node.js);
- 数据库(MySQL/PostgreSQL,用于存储用户信息);
- HTTPS证书(确保传输安全)。
- 域名解析:
- 主域名(如
main.com)指向主服务器IP; - 从域名(如
sub.main.com)指向从服务器IP。
- 主域名(如
- 基础配置:
- 安装Nginx(从域名反向代理)、Keycloak(主域名SSO服务器)、PHP(从域名后端);
- 配置数据库连接(Keycloak与从域名后端均需访问数据库)。
主域名(认证中心)配置步骤
主域名作为SSO认证中心,需部署并配置认证服务器(以Keycloak为例),实现用户身份验证与令牌生成。
安装与初始化Keycloak
# 下载Keycloak wget https://github.com/keycloak/keycloak/releases/download/21.1.3/keycloak-21.1.3.tar.gz tar -xzf keycloak-21.1.3.tar.gz cd keycloak-21.1.3 # 启动服务器 ./bin/start-keycloak.sh
访问http://main.com:8080,进入初始化界面,设置管理员密码、数据库连接(默认使用H2内存数据库,需切换为MySQL/PostgreSQL)。
创建用户存储与用户组
- 进入Keycloak管理界面,选择“Realm”(如
main),点击“Users”→“Add User”,添加管理员用户(用于后续配置); - 在“Groups”中创建“admin”组(用于从域名用户)。
配置SSO客户端(从域名)
- 在Keycloak中,选择“Clients”→“Create”;
- 客户端ID:
sub-client(从域名SSO客户端标识); - 会话管理:选择“Remember me”(允许记住用户);
- 授权协议:选择“OAuth 2.0”;
- 授权码模式:启用(SSO常用模式);
- 重定向URI:添加从域名的回调URL(如
http://sub.main.com/callback); - 客户端密钥:生成并保存(后续从域名配置需使用)。
- 客户端ID:
配置安全规则
- 进入“Realm”→“Security”→“Authorization”,添加规则:
{ "rules": [ { "type": "custom", "condition": { "function": "hasRole", "values": ["admin"] }, "action": "permit" } ] }(仅允许“admin”组用户访问受保护资源)。
从域名(客户端)配置步骤
从域名作为业务应用,需集成Keycloak的OAuth2客户端,实现用户认证与令牌验证。

Nginx反向代理配置
在从域名Nginx配置文件中添加SSL与反向代理:
server {
listen 443 ssl http2;
server_name sub.main.com;
ssl_certificate /etc/ssl/certs/sub.crt;
ssl_certificate_key /etc/ssl/private/sub.key;
location / {
proxy_pass http://localhost:3000; # 假设后端服务运行在3000端口
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /callback {
proxy_pass http://main.com:8080/realms/main/protocol/openid-connect/token;
proxy_set_header Host main.com;
proxy_set_header X-Forwarded-Proto $scheme;
}
}(需生成sub.main.com的SSL证书,并配置反向代理到后端服务)。
后端集成OAuth2客户端
以Node.js(Express)为例,配置OAuth2客户端:
const express = require('express');
const axios = require('axios');
const session = require('express-session');
const passport = require('passport');
const OAuth2Strategy = require('passport-oauth2').Strategy;
const app = express();
app.use(session({ secret: 'secret-key', resave: false, saveUninitialized: false }));
app.use(passport.initialize());
app.use(passport.session());
// 配置Keycloak OAuth2策略
passport.use(new OAuth2Strategy({
authorizationURL: 'http://main.com:8080/realms/main/protocol/openid-connect/auth',
tokenURL: 'http://main.com:8080/realms/main/protocol/openid-connect/token',
clientID: 'sub-client',
clientSecret: 'your-client-secret',
callbackURL: 'http://sub.main.com/callback'
}, async (accessToken, refreshToken, profile, done) => {
// 获取用户信息并存储会话
done(null, { id: profile.sub, username: profile.name });
}));
passport.serializeUser((user, done) => done(null, user));
passport.deserializeUser((user, done) => done(null, user));
// 登录页面
app.get('/', (req, res) => {
res.send('<a href="/login">登录</a>');
});
// 登录回调
app.get('/login', passport.authenticate('oauth2'));
// 认证成功回调
app.get('/callback', passport.authenticate('oauth2', {
successRedirect: '/',
failureRedirect: '/login'
}));
// 受保护资源
app.get('/protected', (req, res) => {
if (req.isAuthenticated()) {
res.send(`欢迎, ${req.user.username}!`);
} else {
res.send('请先登录');
}
});
app.listen(3000, () => console.log('Server running on port 3000'));(需替换clientSecret为Keycloak中SSO客户端的密钥,并确保回调URL与Keycloak配置一致)。
令牌验证
在受保护资源(如/protected)中,通过req.user验证用户身份(已由passport完成令牌验证),无需额外调用Keycloak。

关键技术点解析
SSO协议选择
- OAuth2:适用于Web应用与API,支持授权码模式、隐式模式等,适合从域名与主域名的交互;
- SAML:适用于企业内部系统,通过断言传递用户信息,需配置X.509证书;
- OpenID Connect:OAuth2的扩展,增加用户信息端点(
/userinfo),适合需要用户名/邮箱的场景。
安全性保障
- HTTPS:所有通信必须通过HTTPS,防止令牌泄露;
- CSRF保护:在回调URL中添加CSRF令牌(如
state参数); - 令牌过期:设置短效令牌(如5-15分钟),避免长期滥用;
- 密钥管理:定期更换Keycloak客户端密钥,防止密钥泄露。
验证与测试
- 访问从域名:打开
http://sub.main.com,点击“登录”链接,应重定向至http://main.com:8080/realms/main/protocol/openid-connect/auth; - 登录验证:输入主域名用户名/密码(如
admin),成功后返回http://sub.main.com/callback,显示登录成功; - 受保护资源访问:访问
http://sub.main.com/protected,应显示欢迎信息(如“欢迎, admin!”),未登录则提示“请先登录”。
常见问题与解答
Q1:配置后,从域名无法获取用户信息怎么办?
解答:
- 检查回调URL是否与Keycloak配置一致(如
http://sub.main.com/callback); - 确认Keycloak客户端密钥是否正确(需与从域名后端配置匹配);
- 检查Nginx反向代理是否将回调请求正确转发至Keycloak(需配置
proxy_pass指向main.com:8080); - 验证Keycloak中“从域名”客户端的“重定向URI”是否包含
http://sub.main.com/callback。
Q2:如何确保SSO的安全性?
解答:
- 强制HTTPS:所有域名(主域名、从域名)均需配置SSL证书,避免明文传输;
- 令牌签名:Keycloak使用RSA/ECDSA密钥对签名令牌,从域名需验证签名(如通过
req.user的sub字段); - CSRF防护:在回调URL中添加
state参数(如http://main.com:8080/...?state=abc),并在从域名中验证state参数是否匹配; - 定期更新密钥:Keycloak客户端密钥每3-6个月更换一次,避免长期使用导致安全风险。
通过以上步骤,可实现主从域名间的单点登录,提升用户体验与系统安全性。
图片来源于AI模型,如侵权请联系管理员。作者:酷小编,如若转载,请注明出处:https://www.kufanyun.com/ask/208887.html


