Appearance
对接微软AD域同步组织架构和成员
概述
在企业内部通常会使用微软AD域
进行组织架构管理、用户管理、 下面是同步组织架构和成员到织信的步骤。
实现代码
javascript
const syncOrg = () => {
let connection = null;
try {
connection = informat.ldap.connect({
providerURL: 'LDAP://1.13.173.190:389',
securityPrincipal: 'userName',
securityCredentials: 'password',
});
// 查询ou=Group,dc=informat,dc=cn目录所有部门
const result = connect.search('ou=Group,dc=informat,dc=cn', 'objectClass=group', {
searchScope: 'SUBTREE', // 搜索的限定范围,默认为 SUBTREE。SUBTREE 返回所有满足条件的条目,ONELEVEL 返回同级的条目,OBJECT 只返回满足条件的对象
});
// 输出所有条目的名称及其属性
result.forEach(r => {
let id = null
let name = null
let description = null
let parentId = null
r.attributes.forEach(ra => {
if (ra.id === 'cn') {
id = ra.values[0]
}
if (ra.id === 'name') {
name = ra.values[0]
}
if (ra.id === 'description') {
description = ra.values[0]
}
if (ra.id === 'memberOf') {
const cnMatch = ra.values[0].match(/CN=([^,]+)/);
parentId = cnMatch ? cnMatch[1] : null;
}
});
let dept = {
id: id,
name: name,
description: description,
parentId: parentId
}
addDept(dept)
});
} catch (e) {
//连接ldap服务器或者认证失败
console.error('ldap login failure')
} finally {
if (connection != null) {
connection.close();
}
}
}
/**
* 添加部门
* @param dept
*/
const addDept = (dept) => {
let deptExist = informat.dept.getDept(dept.id);
if (deptExist) {
return;
}
informat.dept.addDept({
id:dept.id,
name:dept.name,
shortName:dept.name,
parentId: dept.parentId ? dept.parentId : 'root',
ownerList:['zhangsan'], // 部门属主,根据实际情况修改
remark: dept.description
});
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
javascript
const syncAccount = () => {
let connection = null;
try {
connection = informat.ldap.connect({
providerURL: 'LDAP://1.13.173.190:389',
securityPrincipal: 'userName',
securityCredentials: 'password',
});
// 查询cn=Users,dc=informat,dc=cn目录所有用户
const result = connect.search('cn=Users,dc=informat,dc=cn', 'objectClass=user', {
searchScope: 'SUBTREE', // 搜索的限定范围,默认为 SUBTREE。SUBTREE 返回所有满足条件的条目,ONELEVEL 返回同级的条目,OBJECT 只返回满足条件的对象
});
// 输出所有条目的名称及其属性
result.forEach(r => {
let userName = null
let name = null
let userAccountControl = null
let deptList = []
r.attributes.forEach(ra => {
if (ra.id === 'userPrincipalName') {
userName = ra.values[0]
}
if (ra.id === 'name') {
name = ra.values[0]
}
if (ra.id === 'userAccountControl') {
userAccountControl = ra.values[0]
}
if (ra.id === 'memberOf') {
deptList = ra.values.filter(group => group.includes('OU='))
.map(group => {
// 提取 CN
const cnMatch = group.match(/CN=([^,]+)/);
return cnMatch ? cnMatch[1] : null;
}).filter(cn => cn !== null);
}
});
// 生成织信账号对象
let account = {
userName: userName,
name: name,
password: 'informat1234', // 默认密码
deptList: deptList
}
if (isDisableAccount(userAccountControl)) {
// 该AD域账户如果为禁用状态则禁用织信账号
disableAccount(account)
}
addAccount(account)
});
} catch (e) {
//连接ldap服务器或者认证失败
console.error('ldap login failure');
} finally {
if (connection != null) {
connection.close();
}
}
}
const addAccount = (account) => {
// 创建系统账号
let accountList = informat.system.queryAccountList({
pageSize:-1,
filter: {
conditionList: [
{
fieldId: 'userName',
opt: 'eq',
value: account.userName
}
]
}
})
if (accountList.length !== 0) {
let existAccount = accountList[0];
if (!existAccount.isValid) {
informat.system.setAccountValid(existAccount.id, true);
}
return
}
let accountId = informat.system.addAccount({
name: account.name,
avatar: 'pic1.png',
userName: account.userName,
password: account.password
});
// 给账号添加部门和系统角色
informat.company.addCompanyMember(accountId, account.deptList, ['normal'])
}
/**
* 禁用账户
* @param account
*/
const disableAccount = (account) => {
// 查询已存在账户
let accountList = informat.system.queryAccountList({
pageSize:-1,
filter: {
conditionList: [
{
fieldId: 'userName',
opt: 'eq',
value: account.userName
}
]
}
})
if (accountList.length !== 0) {
let existAccount = accountList[0];
if (existAccount.isValid) {
informat.system.setAccountValid(existAccount.id, false);
}
}
}
/**
* 是否禁用
* @param userAccContr
* @returns {boolean}
*/
const isDisableAccount = (userAccContr) => {
// TRUSTED_TO_AUTH_FOR_DELEGATION - 允许该帐户进行委派
if (userAccContr >= 16777216) {
userAccContr = userAccContr - 16777216;
}
// PASSWORD_EXPIRED - (Windows 2000/Windows Server 2003) 用户的密码已过期
if (userAccContr >= 8388608) {
userAccContr = userAccContr - 8388608;
}
//DONT_REQ_PREAUTH
if (userAccContr >= 4194304) {
userAccContr = userAccContr - 4194304;
}
// USE_DES_KEY_ONLY - (Windows 2000/Windows Server 2003) 将此用户限制为仅使用数据加密标准 (DES) 加密类型的密钥
if (userAccContr >= 2097152) {
userAccContr = userAccContr - 2097152;
}
// NOT_DELEGATED - 设置此标志后,即使将服务帐户设置为信任其进行 Kerberos 委派,也不会将用户的安全上下文委派给该服务
if (userAccContr >= 1048576) {
userAccContr = userAccContr - 1048576;
}
// TRUSTED_FOR_DELEGATION - 设置此标志后,将信任运行服务的服务帐户(用户或计算机帐户)进行 Kerberos 委派。任何此类服务都可模拟请求该服务的客户端。若要允许服务进行 Kerberos 委派,必须在服务帐户的 userAccountControl 属性上设置此标志
if (userAccContr >= 524288) {
userAccContr = userAccContr - 524288;
}
// SMARTCARD_REQUIRED - 设置此标志后,将强制用户使用智能卡登录
if (userAccContr >= 262144) {
userAccContr = userAccContr - 262144;
}
// MNS_LOGON_ACCOUNT - 这是 MNS 登录帐户
if (userAccContr >= 131072) {
userAccContr = userAccContr - 131072;
}
// DONT_EXPIRE_PASSWORD-密码永不过期
if (userAccContr >= 65536) {
userAccContr = userAccContr - 65536;
}
// MNS_LOGON_ACCOUNT - 这是 MNS 登录帐户
if (userAccContr >= 2097152) {
userAccContr = userAccContr - 2097152;
}
// SERVER_TRUST_ACCOUNT - 这是属于该域的域控制器的计算机帐户
if (userAccContr >= 8192) {
userAccContr = userAccContr - 8192;
}
// WORKSTATION_TRUST_ACCOUNT - 这是运行 Microsoft Windows NT 4.0 Workstation、Microsoft Windows NT 4.0 Server、Microsoft Windows 2000 Professional 或 Windows 2000 Server 并且属于该域的计算机的计算机帐户
if (userAccContr >= 4096) {
userAccContr = userAccContr - 4096;
}
// INTERDOMAIN_TRUST_ACCOUNT - 对于信任其他域的系统域,此属性允许信任该系统域的帐户
if (userAccContr >= 2048) {
userAccContr = userAccContr - 2048;
}
//NORMAL_ACCOUNT - 这是表示典型用户的默认帐户类型
if (userAccContr >= 512) {
userAccContr = userAccContr - 512;
}
// TEMP_DUPLICATE_ACCOUNT - 此帐户属于其主帐户位于另一个域中的用户。此帐户为用户提供访问该域的权限,但不提供访问信任该域的任何域的权限。有时将这种帐户称为“本地用户帐户”
if (userAccContr >= 256) {
userAccContr = userAccContr - 256;
}
//ENCRYPTED_TEXT_PASSWORD_ALLOWED - 用户可以发送加密的密码
if (userAccContr >= 128) {
userAccContr = userAccContr - 128;
}
//PASSWD_CANT_CHANGE - 用户不能更改密码。可以读取此标志,但不能直接设置它
if (userAccContr >= 64) {
userAccContr = userAccContr - 64;
}
// PASSWD_NOTREQD - 不需要密码
if (userAccContr >= 32)
{
userAccContr = userAccContr - 32;
}
// LOCKOUT
if (userAccContr >= 16) {
userAccContr = userAccContr - 16;
}
// HOMEDIR_REQUIRED - 需要主文件夹
if (userAccContr >= 8) {
userAccContr = userAccContr - 8;
}
return userAccContr >= 2;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208