内容


使用 Active Directory 实现 Node.js Bluemix 应用程序中的身份验证和授权

如何使用 Microsoft Active Directory 代替 LDAP

Comments

前一篇教程 “使用 LDAP 实现 Node.js Bluemix 应用程序中的身份验证和授权” 介绍了如何使用内部 LDAP 服务器在 Node.js Bluemix® 应用程序中实现身份验证和授权。但是如果您的组织使用的是 Microsoft™ Active Directory 该怎么办?Active Directory 大体遵守 LDAP 标准,但它有一些重要的区别。

构建您的应用程序需要做的准备工作

运行应用程序获取代码

演示应用程序

演示应用程序需要输入一个用户名、一个域和一个密码。它还有一个字段可输入您的 Active Directory 服务器的主机名或 IP 地址。

提交信息后,应用程序尝试让您登录。如果尝试成功,该应用程序显示您所属的组的列表。

该屏幕截图显示了用户所属的组的列表
该屏幕截图显示了用户所属的组的列表

Active Directory 与 LDAP 对比

Microsoft Active Directory 有一个 LDAP 接口。但是,像其他许多领域中一样,Microsoft 对该标准具有不同的解释。下面是与让用户登录和检查它们的组成员关系相关的区别:

LDAP Microsoft Active Directory
用户标识符 uidsAMAccountName(仅包含用户标识符)或 userPrincipalName (<user identifier>@<domain>)
绑定标识符 区分名 如果您知道区分名,那么可以使用它,但也可以使用 userPrincipalName
后缀 许多选项 域名始终为 dc(域组件)属性。例如,对于 ibm.com,后缀将为 dc=ibm,dc=com
组成员关系 编码为组对象中的 member 属性 被编码为用户对象中的 memberOf 属性

与 LDAP 一样,如果您的 Active Directory 服务器无法从互联网访问(正常情况下是这样),可以使用 Bluemix Secure Gateway 服务

登录流

您不需要用户的区分名,所以一个 LDAP 连接就足够了。只需使用正确的 LDAP URL 创建一个客户端,并尝试与用户的 userPrincipalName 绑定,这通常是一个有效的电子邮件地址和密码。如果信息是错的,绑定通常会失败。但有一个例外。如果密码是空的,那么任何绑定尝试都会成功。可以在处理登录表单的代码中轻松地处理这种情况:

// Process the login form for Active Directory
app.post("/adlogin", function(req, res) {
	var url = "ldap://" + req.body.ad;
	var userPrincipalName = req.body.uid + "@" + req.body.domain;
	var passwd = req.body.passwd;

	if (passwd === "") {
		res.send("The empty password trick does not work here.");
		return ;
	}

	// Bind as the user
	var adClient = ldap.createClient({ url: url });
	adClient.bind(userPrincipalName, passwd, function(err) {

		if (err != null) {
			if (err.name === "InvalidCredentialsError")
				res.send("Credential error");
			else
				res.send("Unknown error: " + JSON.stringify(err));
		} else
			res.send("Hello " + req.body.uid);
	});
});

登录后,可以像 LDAP 登录一样管理会话。

使用组进行授权

组成员关系是用户对象的一部分,所以获取它的最简单方法就是读取该对象:

  1. 获取将用作搜索基础的后缀。Active Directory 中的后缀由域组成,将每个以点分隔的值放在一个域组件中。例如,域 austin.ibm.com 会得到后缀 dc=austin,dc=ibm,dc=com
    	var suffix = "dc=" + req.body.domain.replace(/\./g, ",dc=");
  2. 搜索使用 userPrincipalName 属性的用户,该属性与用于登录到 LDAP 的值相同。
    	adClient.search(suffix,
    		{
    			scope: "sub",
    			filter: "(userPrincipalName=" + userPrincipalName + ")"
    		},
  3. 此时会得到一个结果,因为您已经使用该用户进行登录。但是,结果中的 memberOf 属性可能是以下三个值之一:
    • Undefined:没有该属性,因为用户不是任何组的成员。
    • 一个字符串:用户仅是一个组的成员,该字符串包含该组的区分名 (DN)。
    • 一个数组:用户是两个或更多组的成员。该数组中的每个成员是一个包含一个组的 DN 的字符串。

    以下代码处理所有三种可能性:

    // When we get a result, that is the user data	
    ldapResult.on('searchEntry', function(entry) {
    		var groups = entry.object.memberOf;
    		
    		// We want to handle a string (single value) as an array
    		if (typeof groups === "string")
    			groups = [groups];
    						
    		var html = "";
    		html += "<h2>Hello " + entry.object.cn + "</h2>";
    		if (groups != undefined) {
    			html += "<h4>Groups:</h4><ol>";
    			for (var i=0; i<groups.length; i++)
    				html += "<li>" + groups[i]  + "</li>";
    				html += "</ol>";
    		} else
    			html += "No group membership detected.";
    
    						
    		res.send(html);
    	});

结束语

您现在应能够使用 Microsoft Active Directory 作为您的 Bluemix Node.js 应用程序的用户存储库。


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Open source
ArticleID=1025649
ArticleTitle=使用 Active Directory 实现 Node.js Bluemix 应用程序中的身份验证和授权
publish-date=01182016