使用@node-saml/node-saml开发SAML SP失败,求修复及Azure配置指引
问题描述
我基于@node-saml/node-saml库开发SAML服务提供商(SP),但认证功能无法正常工作,希望得到修复方法或可靠参考方向。同时对Azure Entra ID中的SAML应用配置存在疑问,不清楚Assertion Consumer Service(ACS)URL和实体ID的正确设置方式,目前误将应用基础URL设为ACS URL。
代码片段
vc.ts
export const SAML = async () => { const express = require("express"); const bodyParser = require("body-parser"); const { SAML } = require("@node-saml/node-saml"); const app = express(); const port = 3001; app.use(bodyParser.urlencoded({ extended: true })); const spOptions = { issuer: "saml_XXX", cert: "MII...XXX", assert_endpoint: "https://5XXX", audience: "https://5XXX", }; const sp = new SAML(spOptions); // SAMLrequest app.get("/login", (req: any, res: { redirect: (arg0: any) => void }) => { const request = sp.createLoginRequest(); res.redirect(request); }); // SAML Assertion app.post( "/assert", ( req: { body: { SAMLResponse: any } }, res: { status: (arg0: number) => { (): any; new (): any; send: { (arg0: any): any; new (): any }; }; redirect: (arg0: string) => any; send: (arg0: string) => void; } ) => { const response = req.body.SAMLResponse; sp.parseLoginResponse( response, (err: any, profile: any, loggedOut: any) => { if (err) { console.log("err:", err); return res.status(500).send(err); } console.log(profile); if (loggedOut) { return res.redirect("/"); } res.send("Login successful!"); return "OK!"; } ); } ); return app; };
saml-request.ts
import { error } from "console"; import { SAML } from "../../../lib/vc"; const createSamlRequest = async (req: any, res: any) => { const app = await SAML(); app(req, res); try { console.log("success"); } catch { console.log("failed", error); } }; export default createSamlRequest;
修复建议与配置说明
代码层面修复点
- 补充SP配置关键参数:
spOptions缺少IDP核心配置,@node-saml/node-saml需要IDP的地址和证书才能生成有效请求并验证响应。补充以下参数:const spOptions = { issuer: "saml_XXX", // SP实体ID,需和Azure配置完全一致 cert: "MII...XXX", // SP签名证书(可选,若启用SP请求签名) assert_endpoint: "https://你的公网域名/assert", // ACS URL,和Azure配置一致 audience: "saml_XXX", // 应为SP实体ID,而非ACS URL entryPoint: "https://login.microsoftonline.com/你的租户ID/saml2", // Azure提供的SSO URL idpCert: "MII...", // Azure的签名证书,用于验证IDP响应 }; - 修正登录请求生成逻辑:
createLoginRequest需通过回调获取正确的跳转URL,直接调用无法生成有效地址:app.get("/login", (req: any, res: any) => { sp.createLoginRequestUrl(req, (err: any, url: any) => { if (err) return res.status(500).send(err); res.redirect(url); }); }); - 修正响应解析参数:
parseLoginResponse需传入完整请求对象req,库会自动解析请求体中的SAML响应:sp.parseLoginResponse(req, (err: any, profile: any, loggedOut: any) => { // 原有逻辑 }); - 避免重复创建Express实例:
SAML函数每次调用都会生成新的Express实例,建议将Express初始化与路由定义分离,防止重复注册路由导致的冲突。
Azure Entra ID配置说明
- 实体ID(Entity ID):对应SP配置的
issuer参数,是SP的唯一标识,可自定义字符串(如saml_XXX)或URL格式(如https://你的域名/saml/metadata),必须和spOptions.issuer完全一致。 - ACS URL:是IDP发送SAML响应的专属端点,对应代码中
assert_endpoint的值,需为公网可访问的https地址(如https://你的域名/assert),不能与应用基础URL混淆。 - 基础URL设置:仅作为应用的根地址标识,无需与ACS URL一致,根据实际应用部署地址填写即可。
- 证书配置:在Azure中上传SP的公钥证书(对应
spOptions.cert),用于IDP验证SP请求的签名;同时复制Azure提供的签名证书到spOptions.idpCert,用于SP验证IDP的响应合法性。
内容的提问来源于stack exchange,提问作者Jamil
相关产品推荐
相关产品推荐

