@darioackermann/saml2-js (英语)
@darioackermann/saml2-js 是一个节点模块,它将 SAML 协议的复杂性归纳在一个易于使用的界面后。 它通过帮助您执行 SAML 协议的服务提供商来实现这一点. 它目前没有实施作为身份提供者的特征.
分叉通知
这是叉子 聪明/ saml2-js 我会确保 依赖定期更新。 扩展现有功能的PR是受欢迎的.
使用量
安装方式 无。 。 。 .
npm install @darioackermann/saml2-js --save
包含 SAML 库 .
var saml2 = require('@darioackermann/saml2-js');
文档
这个库输出出两个构造器.
ServiceProvider- 代表依赖信任的服务提供者IdentityProvider用于SAML流中的认证和授权.IdentityProvider- 代表一个认证SAML流量用户的在线服务.
说明: 可以在 战略计划, (中文(简体) ), 报告,和/或按方法。 对于在多处设置的选项,它们按以下顺序被推翻: 方法基础 覆盖 报告 哪个 覆盖 战略计划。 。 。 .
服务提供者( 选项)
代表依赖信任的服务提供商 IdentityProvider 用于SAML流中的认证和授权.
选项
一个可以包含以下选项的对象。 所有选项都是字符串, 除非另有说明 。 见 说明 需要更多关于选项的信息.
entity_id- 说吧 需求 - 服务提供者的独特标识符,经常是元数据文件的URL.private_key- 说吧 需求 - (PEM格式字符串) - 服务提供商的私人密钥.certificate- 说吧 需求 - (PEM格式字符串) - 服务商的证书.assert_endpoint- 说吧 需求 - 服务提供者的URL申明终点.alt_private_keys– (Array of PEM格式字符串) - 试图解密响应时需要使用的额外私钥. 用于为旧证书在翻转后添加后相容性 .alt_certs- (Array of PEM格式字符串) - 在 SAML 元数据中曝光的额外证书. 用于为翻转提供新证书 .audience- (String或RegExp) - 如果设定,至少其中一种<Audience>数值<AudienceRestriction>sAML 认证响应的条件必须匹配。 默认为entity_id。 。 。 .notbefore_skew– (数量) – 计算 IdP 和 SP 之间的时钟 skew , 请先于当前时间( 根据我们的时钟) 接受条件不早的反应 。 默认为 1 。 设定为0,以达到最佳安全,但不能容忍时钟摇晃.force_authn- (Boolean) - 如果真实, 强制重新认证用户, 即使用户与 SSO 会话 报告。也可以在 报告 或按方法进行.auth_context- 指定AuthnContextClassRef。也可以按方法配置.nameid_format- 名称标识格式。 这也可以按每方法配置.sign_get_request如果是真的,请在请求上签名 此选项也可以配置在 报告 或按方法进行.allow_unencrypted_assertion如果是真的,允许不加密的断言。 此选项也可以配置在 报告 或按方法进行.
返回以下函数
create_login_request_url(IdP, options, cb)- 获得一个URL启动登录.redirect_assert(IdP, options, cb)- 如果登录尝试有效,则获得一个 SAML 响应对象,用于重定向绑定.post_assert(IdP, options, cb)- 如果登录尝试有效, 则获取一个 SAML 响应对象, 用于邮局绑定 .create_logout_request_url(IdP, options, cb)- 创建 SAML 请求 URL 启动用户登录.create_logout_response_url(IdP, options, cb)- 创建 SAML 响应 URL 确认成功 报告 启动登录 .create_metadata()- 返回初始 SAML 配置中使用的 XML 元数据 .
示例
var sp_options = {
entity_id: "https://sp.example.com/metadata.xml",
private_key: fs.readFileSync("key-file.pem").toString(),
certificate: fs.readFileSync("cert-file.crt").toString(),
assert_endpoint: "https://sp.example.com/assert",
force_authn: true,
auth_context: { comparison: "exact", class_refs: ["urn:oasis:names:tc:SAML:1.0:am:password"] },
nameid_format: "urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
sign_get_request: false,
allow_unencrypted_assertion: true
}
// Call service provider constructor with options
var sp = new saml2.ServiceProvider(sp_options);
// Example use of service provider.
// Call metadata to get XML metatadata used in configuration.
var metadata = sp.create_metadata();
服务提供者函数定义
创建 login request url( IdP, 选项, cb)
获取一个 URL 启动登录 .
提出下列论点:
重定向 sassert( IdP, 选项, cb)
如果登录尝试有效, 则获得一个 SAML 响应对象, 用于重定向绑定 .
提出下列论点:
SAML 声明回复的例子 :{ response_header:
{ id: '_abc-1',
destination: 'https://sp.example.com/assert',
in_response_to: '_abc-2' },
type: 'authn_response',
user:
{ name_id: 'nameid',
session_index: '_abc-3',
assertion_id: '_123',
attributes:
{ 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname': [ 'Test' ] } } }
后塞( IdP, 选项, cb)
如果登录尝试有效, 获取 SAML 响应对象, 用于邮局绑定 .
提出下列论点:
IdP- 说吧 报告options- 一个可以包含以下选项的对象。 所有选项都是字符串, 除非另有说明 。 见 说明 需要更多关于选项的信息.request_body- (Object) - 包含解析的查询字符串参数的对象. 此对象应包含其中任一对象的值SAMLResponse或者说SAMLRequest。 。 。 .allow_unencrypted_assertion如果是真的,允许不加密的断言。 此选项也可以配置在 报告 或者说 战略计划。 。 。 .require_session_index- (Boolean) - 如果虚假,允许断言有效,而不包含SessionIndex属性AuthnStatement节点.audience- (String或RegExp) - 如果设定,至少其中一种<Audience>数值<AudienceRestriction>sAML 认证响应的条件必须匹配。 默认为entity_id。 。 。 .notbefore_skew– (数量) – 计算 IdP 和 SP 之间的时钟 skew , 请先于当前时间( 根据我们的时钟) 接受条件不早的反应 。 默认为 1 。 设定为0,以达到最佳安全,但不能容忍时钟摇晃.
cb(error, response)- 回电了 请求答复。 。 。 .
创建 logout request url( IdP, 选项, cb)
创建 SAML 请求 URL 启动用户登录 .
提出下列论点:
创建 logout reswer url( IdP, 选项, cb)
创建 SAML 响应 URL 确认成功 报告 启动登录 .
提出下列论点:
创建数据( m)
返回初始 SAML 配置中使用的 XML 元数据 .
身份提供者( 选项)
代表一个认证SAML流中用户的在线服务.
返回时没有函数,只有函数可以传递给 战略计划 函数.
选项
一个可以包含以下选项的对象。 所有选项都是字符串, 除非另有说明 。 见 说明 需要更多关于选项的信息.
sso_login_url- 说吧 需求 - 在登录请求中使用的登录 URL.sso_logout_url- 说吧 需求 - 登录url在登录请求中使用.certificates- 说吧 需求 -(PEM格式字符串或PEM格式字符串的数组) - 身份提供者的证书或证书(证书数量).force_authn- (Boolean) - 如果真实, 强制重新认证用户, 即使用户与 SSO 会话 报告。也可以在 战略计划 或按方法进行.sign_get_request如果是真的,请在请求上签名 也可以在 [战略计划 或按方法进行.allow_unencrypted_assertion如果是真的,允许不加密的断言。 此选项也可以配置在 战略计划 或按方法进行.
示例
// Initialize options object
var idp_options = {
sso_login_url: "https://idp.example.com/login",
sso_logout_url: "https://idp.example.com/logout",
certificates: [fs.readFileSync("cert-file1.crt").toString(), fs.readFileSync("cert-file2.crt").toString()],
force_authn: true,
sign_get_request: false,
allow_unencrypted_assertion: false
};
// Call identity provider constructor with options
var idp = new saml2.IdentityProvider(idp_options);
// Example usage of identity provider.
// Pass identity provider into a service provider function with options and a callback.
sp.post_assert(idp, {}, callback);
示例: 快速执行
库用户需要执行一组 URL 端点,这里就是一个例子 表达式 结束点.
var saml2 = require('saml2-js');
var fs = require('fs');
var express = require('express');
var app = express();
// If you're using express <4.0:
// var bodyParser = require('body-parser');
// app.use(bodyParser.urlencoded({
// extended: true
// }));
app.use(express.urlencoded());
// Create service provider
var sp_options = {
entity_id: "https://sp.example.com/metadata.xml",
private_key: fs.readFileSync("key-file.pem").toString(),
certificate: fs.readFileSync("cert-file.crt").toString(),
assert_endpoint: "https://sp.example.com/assert"
};
var sp = new saml2.ServiceProvider(sp_options);
// Create identity provider
var idp_options = {
sso_login_url: "https://idp.example.com/login",
sso_logout_url: "https://idp.example.com/logout",
certificates: [fs.readFileSync("cert-file1.crt").toString(), fs.readFileSync("cert-file2.crt").toString()]
};
var idp = new saml2.IdentityProvider(idp_options);
// ------ Define express endpoints ------
// Endpoint to retrieve metadata
app.get("/metadata.xml", function(req, res) {
res.type('application/xml');
res.send(sp.create_metadata());
});
// Starting point for login
app.get("/login", function(req, res) {
sp.create_login_request_url(idp, {}, function(err, login_url, request_id) {
if (err != null)
return res.send(500);
res.redirect(login_url);
});
});
// Variables used in login/logout process
var name_id, session_index;
// Assert endpoint for when login completes
app.post("/assert", function(req, res) {
var options = {request_body: req.body};
sp.post_assert(idp, options, function(err, saml_response) {
if (err != null)
return res.send(500);
// Save name_id and session_index for logout
// Note: In practice these should be saved in the user session, not globally.
name_id = saml_response.user.name_id;
session_index = saml_response.user.session_index;
res.send("Hello #{name_id}! session_index: #{session_index}.");
});
});
// Starting point for logout
app.get("/logout", function(req, res) {
var options = {
name_id: name_id,
session_index: session_index
};
sp.create_logout_request_url(idp, options, function(err, logout_url) {
if (err != null)
return res.send(500);
res.redirect(logout_url);
});
});
app.listen(3000);