失敗の原因判別がつかないのでござる
- 普通にパスワード間違えた場合
- パスワードの期限が切れた場合
- アカウントがロックされた場合
これらの場合はすべて
Invalid Credential(49)
... (´゚д゚`)ポカーン
有識者に聞いてみたら、一応OpenLDAPの作り的には
それで良くて、細かいメッセージは必須ではないそう
そもそもldapsearchコマンドでも判別がつかない
上記のケースで、ターミナルでldapsearchを叩いても
Invalid Credential(49)
しか出てこない
一方、ldapサーバーにリモートアクセスし、中でコマンド叩くとしっかりメッセージが細かく分かれている
ldapjsのメッセージラッピングがイけてない説を疑っていた自分を悔いつつ、
それじゃあどうしようもないわなと。。。
回避策
要は気合を入れてハンドリングすればいいと。
フローして:
*前処理*
ユーザーが認証失敗した時、
サーバーで一度管理者でbindし、そのユーザー情報をldapjsのsearch関数取得する
if searchで取れるアカウントのパスワードと実際にユーザーが入力したパスワードが一致する {
if pwdAccountLockedTimeという属性値を取得できたら {
ユーザーアカウントはロックされているので、その処理を行う
}
else {
ユーザーパスワードは期限切れなので、その処理を行う
}
} else {
入力ミスの処理を行う
}
// 先にロック判定などしたほうがいい気もするが、今回はこの分岐にした
sinippet
promiseしてない、サーセン
// client は ldapjsのインスタンス
// ssha は ssha モジュールのインスタンス
let opt = { attributes: ['pwdAccountLockedTime', 'userPassword'] };
client.search(`ユーザー識別子`, opt, (er, response) => {
response.on('searchEntry', (entry) => {
// 一応sshaモジュールのverify関数を使う(ツッコミどころ)
if(pwd === entry.object.userPassword || ssha.verify(pwd, entry.object.userPassword)) {
if(entry.object.hasOwnProperty('pwdAccountLockedTime')) {
console.log('Account locked');
} else {
console.log('Password expired');
}
} else {
console.log('Invalid Password');
}
return;
});
response.on('searchReference', function(referral) {
// ...
});
response.on('error', function(err) {
// ...
});
response.on('end', function(result) {
// ...
});
});