//首先,我们需要安装一些依赖:
//Express框架:用于构建Web应用程序
//npm install express --save
//Passport模块:用于处理认证和授权
//npm install passport passport-saml express-session --save
//用于存储和读取cookie的中间件
//npm install cookie-parser --save
//接下来,我们创建一个名为app.js的文件,并添加以下代码:
const express = require("express");
const passport = require("passport");
const SamlStrategy = require("passport-saml").Strategy;
const cookieParser = require("cookie-parser");
const session = require("express-session");
// 创建Express应用程序
const app = express();
// 配置视图引擎
app.set("view engine", "html");
app.engine("html", require("ejs").renderFile);
// 设置cookie解析器和会话中间件
app.use(cookieParser());
app.use(
session({
secret: "yourSecretKey",
resave: false,
saveUninitialized: true,
})
);
// 配置Passport和SAML策略
passport.use(
new SamlStrategy(
{
// ADFS提供的元数据URL
entryPoint: "https://sts.secsso.net/adfs/ls",
issuer: "yourIssuer",
callbackUrl: "http://localhost:3000/login/callback",
cert: "yourSigningCertificate",
},
function (profile, done) {
// 在这里处理验证成功后的逻辑
// 可以根据需要从profile中取出相关的用户信息并保存在cookie中
return done(null, profile);
}
)
);
// 初始化Passport
app.use(passport.initialize());
app.use(passport.session());
// 序列化和反序列化用户对象
passport.serializeUser(function (user, done) {
done(null, user);
});
passport.deserializeUser(function (user, done) {
done(null, user);
});
// 定义登录和回调路由
app.get("/login", passport.authenticate("saml"));
app.post(
"/login/callback",
passport.authenticate("saml", { failureRedirect: "/", successRedirect: "/" })
);
// 定义默认路由,重定向到登录
app.get("/", function (req, res) {
res.redirect("/login");
});
// 启动服务器
app.listen(3000, function () {
console.log("Server started on port 3000");
});
在上面的代码中,我们首先引入所需的模块,然后创建一个Express应用程序。我们设置了视图引擎为HTML,并配置了cookie解析器和会话中间件。
接下来,我们配置Passport和SAML策略。在SAML策略的构造函数中,我们提供了ADFS的元数据URL、签名证书等配置信息。在验证成功后的回调函数中,我们可以根据需要从profile对象中获取相关的用户信息,并将其保存在cookie中。
然后,我们初始化Passport,并设置了序列化和反序列化用户对象的逻辑。
接着,我们定义了登录和回调路由。当用户访问/login路由时,Passport会将用户重定向到ADFS进行登录。登录成功后,ADFS会将用户重定向回我们指定的回调URL,并在URL中包含SAML响应。我们在回调路由中通过调用passport.authenticate方法来处理SAML响应,如果验证失败则重定向到登录页面,如果验证成功则重定向到系统的入口页面。
最后,我们定义了默认路由,当用户访问系统时会自动重定向到登录页面。
你需要将yourIssuer和yourSigningCertificate替换为实际的值。yourIssuer是你的应用程序的标识符,yourSigningCertificate是你使用的签名证书。
同时,你还需要创建一个名为login.html的HTML文件,作为登录页面。在该文件中,你需要添加一个登录按钮,点击按钮时将用户重定向到/login路由。
在使用Express框架实现登录功能前,需要先安装相应的依赖包。在项目根目录下打开命令行,执行以下命令:
npm install express express-session passport passport-saml --save
安装完成后,可以开始编写代码了。首先,在根目录下创建一个名为index.js的文件,并添加以下代码:
const express = require('express');
const passport = require('passport');
const SamlStrategy = require('passport-saml').Strategy;
const session = require('express-session');
const app = express();
// 设置SAML配置信息
const samlConfig = {
entryPoint: 'https://sts.secsso.net', // SSO服务提供商的登录地址
issuer: 'http://localhost:3000', // 本系统的标识
callbackUrl: 'http://localhost:3000/login/callback', // 登录成功后的回调URL
};
// 配置SAML策略
passport.use(new SamlStrategy(
{
...samlConfig,
// 验证SAML响应中的用户信息
verify: (profile, done) => {
// 在此处验证用户信息,并将用户信息传递给回调函数
done(null, profile);
},
},
));
// 序列化和反序列化用户信息
passport.serializeUser((user, done) => {
done(null, JSON.stringify(user));
});
passport.deserializeUser((user, done) => {
done(null, JSON.parse(user));
});
// 配置Express中间件
app.use(session({ secret: 'secret-key', resave: false, saveUninitialized: true }));
app.use(passport.initialize());
app.use(passport.session());
// 登录页面路由
app.get('/login', passport.authenticate('saml'));
// 登录回调路由
app.post('/login/callback', passport.authenticate('saml', { failureRedirect: '/login' }), (req, res) => {
// 登录成功后的逻辑,将用户信息保存在cookie中
res.cookie('user', JSON.stringify(req.user));
res.redirect('/home');
});
// 主页路由
app.get('/home', (req, res) => {
// 在这里获取用户信息
const user = JSON.parse(req.cookies.user);
res.send(`Welcome, ${user.displayName}!`);
});
// 退出登录路由
app.get('/logout', (req, res) => {
// 清除cookie中的用户信息
res.clearCookie('user');
res.redirect('/login');
});
// 启动服务
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
在项目根目录下创建一个名为login.html的文件,作为登录页面,内容如下:
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
</head>
<body>
<h1>Login Page</h1>
<form method="post" action="/login">
<button type="submit">Login</button>
</form>
</body>
</html>
现在运行项目,打开浏览器访问http://localhost:3000,将会自动跳转到https://sts.secsso.net进行登录。登录成功后,将会跳转回本地服务器,并显示欢迎信息。
要退出登录,可以访问http://localhost:3000/logout,将会清除cookie中的用户信息,并重定向到登录页面。
////////////////////////////////////////////////////////////////////////////////////////
mkdir sso-example
cd sso-example
npm init -y
npm install express passport passport-saml express-session
const express = require('express');
const session = require('express-session');
const passport = require('passport');
const SAMLStrategy = require('passport-saml').Strategy;
const app = express();
app.use(session({
secret: 'your-secret-key',
resave: false,
saveUninitialized: true
}));
const samlConfig = {
entryPoint: 'YOUR_ADFS_ENTRY_POINT',
issuer: 'YOUR_ISSUER_NAME',
cert: 'YOUR_CERT_CONTENTS'
};
passport.use(new SAMLStrategy(samlConfig, (profile, done) => {
// 在这里验证用户信息并进行相关操作
return done(null, profile);
}));
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser((user, done) => {
done(null, user);
});
app.use(passport.initialize());
app.use(passport.session());
app.get('/', (req, res) => {
if (req.isAuthenticated()) {
res.send('Authenticated User: ' + req.user.email);
} else {
res.redirect('/login');
}
});
app.get('/login', passport.authenticate('saml', { failureRedirect: '/', failureFlash: true }));
app.post('/login/callback',
passport.authenticate('saml', { failureRedirect: '/', failureFlash: true }),
(req, res) => {
res.redirect('/');
}
);
app.get('/logout', (req, res) => {
req.logout();
res.redirect('/');
});
app.listen(3000, () => {
console.log('Server started on http://localhost:3000');
});
<!DOCTYPE html>
<html>
<head>
<title>Login Page</title>
</head>
<body>
<h1>Login Page</h1>
<!-- Add your login form here -->
</body>
</html>
在上述代码中,同样需要替换 YOUR_ADFS_ENTRY_POINT、YOUR_ISSUER_NAME 和 YOUR_CERT_CONTENTS。
这个示例中使用了 express-session 来管理用户会话,而不是直接将用户信息保存在 cookie 中。当用户通过 ADFS 认证成功后,passport-saml 模块会将用户信息存储在会话中。如果用户已经通过认证,则直接展示用户信息;否则,重定向到 /login 路由进行认证。
最后,在命令行中执行 node app.js 启动应用程序。当访问 http://localhost:3000 时,如果未进行认证,将会自动跳转到 ADFS 登录页面进行认证。认证成功后,用户信息将存储在会话中,可以通过访问 http://localhost:3000 查看认证用户信息。