QA@IT

ASP.NET LDAP認証でエラー

11111 PV

よろしくお願いいたします。
ASP.NET 2012(VB)にて、LDAP認証をしたいのですが、エラーが出てしまいます。

Imports System
Imports System.Text
Imports System.DirectoryServices

Public Class LdapAuthentication

    Public Function IsAuthenticated() As Boolean

        Dim path As String = "LDAP://111.111.111.111:389/ou=people,dc=mycompany,dc=co,dc=jp"
        Dim username As String = "yamada"
        Dim pwd As String = "password"

        Dim entry As DirectoryEntry = New DirectoryEntry(path, username, pwd)

        Try
            Dim search As DirectorySearcher = New DirectorySearcher(entry)
            Dim result As SearchResult = search.FindOne

            If (result Is Nothing) Then
                Return False
            End If

        Catch ex As Exception
            System.Diagnostics.Debug.Print("LDAP認証エラー:" & ex.Message)
            Return False
        Finally
            entry.Close()
        End Try

        Return True

    End Function

End Class

エラー内容:無効な構文が指定されました。

申し訳ございませんが、原因等ご存知の方がいらっしゃいましたら教えていただけ
ませんでしょうか。
よろしくお願いいたします。

情報に不足がございましたら、ご指摘ください。


ご指摘ありがとうございます。追記させていただきます。

自分の開発環境を書きましょう。

VisualStudio2012 .NET Framework4.5 です。
使用言語はVB.NETです。
自分が開発している環境はWindows7ですが、システムを実行して、現在エラーが
出ているWebサーバはWindows2008Serverです。

LDAP認証サーバは、どのような環境かは不明です。(客先が用意しているLDAP
サーバのため。)
ただ、同じLDAPサーバで認証できているシステムが他にあるようなので、認証
サーバ自体の問題ではないそうです。(・・・と言われました。)

Windows2008 Server の IIS にて ASP.NET Web Forms アプリケーションを
動かして、同じイントラネット内にあるLDAP認証サーバに接続し、名前とパスワード
で認証OKかNGかをチェックしようとしている、という状況です。

出展を書きましょう。

あちこちのサイトを参考にして変更していったので、元のそのままではないの
ですが、ベースになっているのは下記です。

フォーム認証と Visual Basic .NET を使用して Active Directory に対する認証を行う方法
https://support.microsoft.com/ja-jp/kb/326340/ja

どの行でエラーが出るのか書きましょう。

Dim search As DirectorySearcher = New DirectorySearcher(entry)

の部分です。

エラーメッセージは略さないでそのままコピペしましょう。

いえ、略していません。
「無効な構文が指定されました。」だけです。

よろしくお願いいたします。

  • 自分の開発環境を書きましょう。MSDN ライブラリなどのコードを参考にしていると思いますが、そうであれば出展を書きましょう。どの行でエラーが出るのか書きましょう。エラーメッセージは略さないでそのままコピペしましょう。 -

回答

ldapはあまり得意ではないですが。

ERROR_DS_INVALID_DN_SYNTAX (0x00002032) エラーじゃないかと思います。

FormatMessageしてみたら同じ文字列になったので。

__________052915_125626_AM.jpg

多分COMExceptionでしょう。

このエラーだった場合はDN名の構文の間違いとなりますので、
dnの指定、LDAPのパスの部分やユーザー名の部分ですね。
このあたりの見直しが必要になるんじゃないかと思います。

LDAPサーバーにもよりますが、認証タイプの相違などでも出ることがあるようです。
相手のLDAPサーバーがなにかをハッキリさせる事が先決じゃないでしょうかね。
大きなところではActiveDirectoryかそうでないか、Windowsかそうでないかを確認した方がいいでしょう。

ちなみに Windows 7からは接続できているんでしょうか?
また自分で建てたldapサーバーとは通信できていますか?(違うエラーになるのか、成功してエラーが再現しないのか)

もう少しローレベルアクセスな LdapConnectionというクラスもあるので試してみるのも良いかもしれません。

How To: Connect to an LDAP Server (msdn.microsoft.com)

編集 履歴 (0)

皆様、ご回答ありがとうございました。
申し訳ございません、結局、先方のLDAPサーバの問題だったようです・・・。
(このシステムからの利用許可設定がされていなかった。)
お付き合いをいただき、本当にありがとうございました。

blunder3さま、ご回答ありがとうございます。

LDAP認証ならAuthenticationType.None(基本認証)を指定したほうがよいのではないかと。
あとAuthenticationType.SecureSocketsLayerもつけた方がいいのかどうか気になります。

ありがとうございます。
LDAPサーバが利用できるようになって、それでもダメなようでしたら試して
みたいと思います。
「SecureSocketsLayer」については、説明を読んでみた限りでは必要かどうか
判断がつかなかったので、勉強してみます。

LDAP認証ならユーザ名はDNなので、"cn=yamada,ou=people,dc=mycompany,dc=co,dc=jp"とか
そんな感じじゃないでしょうか。

自宅のLDAPサーバでは特にドメイン等つけなくても問題なかったので、これで
良いのかと思い込んでいたのですが、普通はそうなのですね。
(ご指摘のとおり、参考元サイトはActiveDirectoryなので、書き方が違うん
だなぁ、と勝手に思っていました。)
ありがとうございます。

編集 履歴 (0)
  • コメントが行き違いになってしまいました。DirectorySearcher のコンストラクタで例外がスローされるというのに間違いないとすると、そこでは LDAP サーバーには接続に行かない(その後の FindOne で接続に行く)はずなので 、「先方のLDAPサーバの問題」と言うことはなさそうに思えますが、いかがですか? -
  • 先に「try - catch を外して、例外がスローされたらブラウザに詳細情報が表示されるようにし、それを見てください。」と書きましたが結果はどうなったでしょうか? -
  • コメントをありがとうございます。先方が対応してくれまして、無事接続できるようになりました。エラーが出なくなってしまったので、ブラウザに表示されるエラーの内容を確認できなくなりました・・・。(実機サーバで作業するためには事前申請等必要なため、すぐには確認できず、そのまま・・・。)また自分でもLDAPについて改めて勉強してみます。今回はありがとうございました。 -

時間がなくて斜め読みなんですけど、とりあえず気になった点。

まずDirectoryEntryコンストラクタを呼ぶとき、AuthenticationTypeを指定してないのが気になりました。認証方法にも色々あると思うので。LDAP認証ならAuthenticationType.None(基本認証)を指定したほうがよいのではないかと。あとAuthenticationType.SecureSocketsLayerもつけた方がいいのかどうか気になります。

DirectoryEntry コンストラクターのマニュアル
AuthenticationTypesのマニュアル

次にユーザ名ですが、"yamada"は気になりました。出典のサイトには"domain\yamada"のようになっているようだったので。でもこれはActiveDirectory前提ですよね?LDAP認証ならユーザ名はDNなので、"cn=yamada,ou=people,dc=mycompany,dc=co,dc=jp"とかそんな感じじゃないでしょうか。

とりあえずその二点が気になりました。

編集 履歴 (0)
  • 質問者さんによると DirectorySearcher のコンストラクタで例外がスローされるそうなので、それが間違いないとすると blunder3 さんが指摘されていることは影響なさそうですが、いかがでしょう? (そこでは LDAP サーバーには接続に行かないので)
    -
  • はい。たしかにそうですね。ご指摘ありがとうございます。DirectorySearcher のコンストラクタで例外がスローされる理由は僕にも分からないです。
    -

flied_onionさま、ありがとうございます。

このエラーだった場合はDN名の構文の間違いとなりますので、
dnの指定、LDAPのパスの部分やユーザー名の部分ですね。
このあたりの見直しが必要になるんじゃないかと思います。

そうなんですか・・・。
なるほど、ネット上で「無効な構文」で検索しても全然引っかからなかった
のですが、元は「ERROR_DS_INVALID_DN_SYNTAX」だったんですね。
ありがとうございます。

LDAPサーバーにもよりますが、認証タイプの相違などでも出ることがあるようです。
相手のLDAPサーバーがなにかをハッキリさせる事が先決じゃないでしょうかね。
大きなところではActiveDirectoryかそうでないか、Windowsかそうでないかを確認した方がいいでしょう。

分かりました。改めて確認してみます。

ちなみに Windows 7からは接続できているんでしょうか?

自分のWindows7からは客先環境のLDAPサーバには接続できないため、確認が
できない状態です。

また自分で建てたldapサーバーとは通信できていますか?(違うエラーになるのか、
成功してエラーが再現しないのか)

はい、自分のLDAPサーバとは問題なく認証成功し、エラーが再現しません。

もう少しローレベルアクセスな LdapConnectionというクラスもあるので試してみるのも良いかもしれません。

ありがとうございます。
ご指摘いただいた部分を再確認して、それでもうまくいかないようでしたら、
試してみたいと思います。

編集 履歴 (0)
  • 先に「try - catch を外して、例外がスローされたらブラウザに詳細情報が表示されるようにし、それを見てください。」と書きましたが結果はどうなったでしょうか? エラーメッセージから探るという方法もアリかもしれませんが、やはりブラウザに表示されたエラー詳細を見るのが確かだと思いますので。 -

.NET のバージョンが不明です。

失礼しました。.NET Framework4.5 です。

それよりに何より大事な情報として、全体的にどういう構成になっているかが分からないのですが・・・
Windows7 の IIS(ASP.NET 開発サーバーとか IIS Express ではなくて)で ASP.NET Web Forms
アプリを動かして、それから同じイントラネット内にある Windows Server 2008 の Active Directory
ドメインサービスに接続し、名前とパスワードでドメインユーザー情報を取得しているという理解で
いいですか?

いえ、自分が開発している環境はWindows7ですが、システムを実行して、現在
エラーが出ているWebサーバはWindows2008Serverです、という意味でした。
(この場合は実際にエラーが出ているWebサーバの環境だけ書けば良いのかとも
思いましたが、「自分の開発環境を書きましょう」というご指摘でしたので、
前記のような書き方をしました。分かりにくくなってしまって申し訳ありません。)

LDAP認証サーバは、どのような環境かは不明です。(客先が用意しているLDAP
サーバのため。)
ただ、同じLDAPサーバで認証できているシステムが他にあるようなので、認証
サーバ自体の問題ではないそうです。(・・・と言われました。)

Windows2008 Server の IIS にて ASP.NET Web Forms アプリケーションを動か
して、同じイントラネット内にあるLDAP認証サーバに接続し、名前とパスワード
で認証OKかNGかをチェックしようとしている、という状況です。

DirectorySearcher のコンストラクタで「無効な構文が指定されました。」というエラーメッセージが
出るというのはどうやっても再現できませんでした。

自分で構築したテスト用のLDAPサーバでいろいろやってみても再現できず、また、
ネットで検索してみたりしたのですが同じ現象もなく、手詰まりとなって質問
させていただきました・・・。

try - catch を外して、例外がスローされたらブラウザに詳細情報が表示されるようにし、
それを見てください。
どの行で例外がスローされたか、例外の種類、スタックトレースが表示されるはずです。
その情報を書いてください。

今はサーバにアクセスできない状況のため、後ほど追記させていただきます。
よろしくお願いいたします。

(初めての利用なので使い方のルールをよく理解していないのですが、コメント
では文字数が足りないため、「回答」に記載させていただきました。)

編集 履歴 (0)
  • そういうことは一番最初に書きましょう。接続先の LDAP サーバーが質問者さんも不明ということですと、ここに書いてあること以外は何も知りえない私のような第三者に回答を期待するのが無理だと思うのですが。 -
  • どのくらいまで詳細に書いてよいか勝手が分からず、最初のような書き方にしてしまいました。
    失礼いたしました。
    どなたか、同じエラーに遭遇したことのある方にご回答をいただければ・・・と思い、質問させていただきました。
    -

VisualStudio2012 です。使用言語はVBです。
開発環境のOSはWindows7ですが、サーバはWindows2008Serverです。

.NET のバージョンが不明です。それより何より大事な情報として、全体的にどういう構成になっているかが分からないのですが・・・

Windows7 の IIS(ASP.NET 開発サーバーとか IIS Express ではなくて)で ASP.NET Web Forms アプリを動かして、それから同じイントラネット内にある Windows Server 2008 の Active Directory ドメインサービスに接続し、名前とパスワードでドメインユーザー情報を取得しているという理解でいいですか?

自分の環境(Web サーバーは Vista SP2 32-bit の IIS7 で統合パイプラインモード。ASP.NET 3.5, Visual Studio 2010 Professional, IE9, Windows Server 2008 の AD DS)で試してみましたが、DirectorySearcher のコンストラクタで「無効な構文が指定されました。」というエラーメッセージが出るというのはどうやっても再現できませんでした。

Vista の IIS7 の Web アプリから、正しいパス(自分の環境では "LDAP://192.168.1.2:389/OU=本社,DC=bglb,DC=jp")、ユーザー名、パスワードで期待通り Windows Server 2008 の AD DS に設定したドメインユーザー情報を取得できることを確認したうえで、パスをいろいろ変えて(わざと間違えて)試してみましたが、自分が試した限りでは、例外がスローされるのは search.FindOne メソッドで、エラーメッセージも異なります。

いえ、略していません。
「無効な構文が指定されました。」だけです。

try - catch を外して、例外がスローされたらブラウザに詳細情報が表示されるようにし、それを見てください。

どの行で例外がスローされたか、例外の種類、スタックトレースが表示されるはずです。その情報を書いてください。

編集 履歴 (1)
ウォッチ

この質問への回答やコメントをメールでお知らせします。