none
Windows認証だと接続できるが、SQL認証だと接続できない RRS feed

  • 質問

  • SQL Server 2008 R2を利用しています。

    C#で簡単なプログラムを作成し、接続しようとしていますが、Windows認証だと接続できて、SQL認証だと接続できません。
    最終的には…
      1) CodeFirstで作成したEntityFrameworkのプログラムにて
      2) ユーザーID/パスワードを指定して接続したいと思っています。
    なので、SQL認証で接続したいと考えています。
    (Windows認証だとユーザーID/パスワードを指定できませんよね?)


    以下のような簡単なサンプルプログラムですが、接続できないので恐らくSQL側に設定をする必要があるのではと思っています。
    よろしければ、教えてください。

    //接続に失敗するケース

    static void Main(string[] args)
    {
        SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
        builder.UserID = "ドメイン名\\ユーザー名";
        builder.Password = "パスワード"; builder.IntegratedSecurity = false; builder.InitialCatalog = "データベース名"; using (SqlConnection cSqlConnection = (new SqlConnection(builder.ConnectionString))) { cSqlConnection.Open(); } }

    //接続に成功するケース
    static void Main(string[] args)
    {
        SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
        builder.DataSource = "サーバー名";
        builder.IntegratedSecurity = true;
        builder.InitialCatalog = "データベース名";
    
        using (SqlConnection cSqlConnection = (new System.Data.SqlClient.SqlConnection(builder.ConnectionString)))
        {
            cSqlConnection.Open();
        }
    }

    例外
    System.Data.SqlClient.SqlException はハンドルされませんでした。
      HResult=-2146232060
      Message=ユーザー 'ドメイン\ユーザー' はログインできませんでした。
      Source=.Net SqlClient Data Provider
      ErrorCode=-2146232060
      Class=14
      LineNumber=65536
      Number=18456
      Procedure=""
      Server=2k8sql001
      State=1
      StackTrace:
           場所 System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
           場所 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
           場所 System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
           場所 System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
           場所 System.Data.SqlClient.SqlInternalConnectionTds.CompleteLogin(Boolean enlistOK)
           場所 System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean ignoreSniOpenTimeout, TimeoutTimer timeout, Boolean withFailover)
           場所 System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString connectionOptions, SqlCredential credential, TimeoutTimer timeout)
           場所 System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(TimeoutTimer timeout, SqlConnectionString connectionOptions, SqlCredential credential, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance)
           場所 System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions)
           場所 System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
           場所 System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool pool, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions)
           場所 System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnectionOptions userOptions)
           場所 System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnectionOptions userOptions)
           場所 System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
           場所 System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
           場所 System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
           場所 System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
           場所 System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
           場所 System.Data.SqlClient.SqlConnection.Open()
           場所 GenerateFromDatabasePractice001.Program.Main(String[] args) 場所 C:\TFS\Alpha\EntityFrameworkPractice\GenerateFromDatabasePractice001\Program.cs:行 25
           場所 System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
           場所 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
           場所 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
           場所 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           場所 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
           場所 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
           場所 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           場所 System.Threading.ThreadHelper.ThreadStart()
      InnerException:


    2013年1月8日 11:48

回答

  • Message=ユーザー 'ドメイン\ユーザー' はログインできませんでした。

    の通りです。

    接続先のインスタンスに対して「ログイン」を作成し、データベースに対して「ユーザー」を作成する必要があります。

    • 回答の候補に設定 佐祐理 2013年1月10日 2:59
    • 回答としてマーク 佐伯玲 2013年1月11日 1:06
    2013年1月9日 4:42

すべての返信

  • まず確認することは、そのSQL ServerがSQL Server認証を許可しているかどうかです。

    (参考)
    サーバーの認証モードの変更
    http://msdn.microsoft.com/ja-jp/library/ms188670.aspx


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    2013年1月8日 13:08
  • ご返信、ありがとうございます。

    SQL Server認証を許可しました。

    これで大丈夫・・・と思ったのですが、状況変わらずです。

    他に確認すべき事はないでしょうか?

    2013年1月9日 2:39
  • 確認ですが、SQL Serverの再起動は行われましたか? 再起動は「SQL Server構成マネージャ」を起動し、「SQL Serverのサービス」より当該のSQL Serverのサービスを見つけ、それを右クリックして「再起動」で行えます。もちろん、SQL Serverが動いているサーバー自体を再起動してもかまいません。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    2013年1月9日 2:48
  • はい。再起動は行いました。
    SQL Serverが動いているサーバー自体を再起動しました。
    2013年1月9日 2:53
  • Message=ユーザー 'ドメイン\ユーザー' はログインできませんでした。

    の通りです。

    接続先のインスタンスに対して「ログイン」を作成し、データベースに対して「ユーザー」を作成する必要があります。

    • 回答の候補に設定 佐祐理 2013年1月10日 2:59
    • 回答としてマーク 佐伯玲 2013年1月11日 1:06
    2013年1月9日 4:42
  • 少し調べてみましたが、ドメインユーザーでSQL Server認証はできないのではないかと思います。例えば以下のページに、次の記述があります。

    認証モードの選択
    http://msdn.microsoft.com/ja-jp/library/ms144284(v=sql.100).aspx

    ------ 引用開始 ---------------------------------------------------------
    SQL Server 認証の欠点
    Windows のログインとパスワードを持っている Windows ドメイン ユーザーの場合、接続するために別の (SQL Server) ログインとパスワードを入力する必要があります。多くのユーザーにとって、複数の名前とパスワードを把握しておくことは困難です。データベースに接続するたびに SQL Server の資格情報を入力する必要があるのは面倒な場合があります。
    ------ 引用終了 ---------------------------------------------------------

    上の引用は今回の問題に関して完全に的を得た引用ではないと思いますが、そもそもSQL Server認証とは、SQL Serverが独自にユーザーを管理し、認証を行うものであり、SQL Server内だけで閉じた世界です。試しに「ドメイン名\ユーザー名」でSQL Server認証のユーザーを作成しようとしましたが、不正な文字が含まれていますと言われ、作成できませんでした。ユーザー名@ドメイン名では作成できましたが、これはドメインユーザーとして認識されているわけではなく、単にSQL Server認証のユーザーの名前が、ユーザー名@ドメイン名というだけのことだと思います。

    SQL Server認証は、SQL Serverがログインユーザーを管理するという仕組みから言っても、ドメインユーザーとは全く関係のない世界ですし、ドメインユーザーと結びつける必要性も無いと思います。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/


    • 編集済み trapemiya 2013年1月9日 4:53 追記
    2013年1月9日 4:44
  • 佐祐理さんの言われるとおり、接続できないのではなくログインできないのだと思いますが、それ以前に、以下のところに大きな考え違いがあるような気がします。

    >  2) ユーザーID/パスワードを指定して接続したいと思っています。
    > なので、SQL認証で接続したいと考えています。
    > (Windows認証だとユーザーID/パスワードを指定できませんよね?)

    「builder.UserID = "ドメイン名\\ユーザー名";」と書いてあったので Active Directory を使ったドメイン環境だと理解しています。

    それなら Windows 認証にすべきです。

    ドメインにログインする際にユーザーID/パスワードでログインしているはずですが、何故再度 SQL Server に同じユーザーID/パスワードでログインする必要があるのですか? そんな必要性はまったくないと思いますが。

    2013年1月9日 13:05
  • 返信が遅れて申し訳ありません。

    > 接続先のインスタンスに対して「ログイン」を作成し、データベースに対して「ユーザー」を作成する必要があります。

    この通り対応しましたらば、問題なく接続が出来ました。

    ありがとうございます。

    2013年1月10日 2:43
  • ありがとうございます。

    SQL認証/Windows認証について理解しました。
    実はインターネット上で公開されたSharePointサーバーが使っているSQL Serverにログインしたいと考えており、
    当該SharePointサーバーのユーザーだけにSQL Serverへのアクセス権を付与したいと思っておりました。

    どうも、無理そうなので、SQL Server認証のログインを利用してアクセスすることとします。

    2013年1月10日 3:03
  • ご回答ありがとうございます。
    ご指摘の通り、理解が足りておりませんでした。

    ちなみに……

    ドメイン環境なのは、SQL Serverがある環境であって、ユーザーがログインする環境ではありません。
    そのため、ユーザーがドメインユーザーIDをもっているとは限らないんです。自宅からアクセスする場合などは、ドメインユーザーIDがありません。

    上述の通り、インターネット上で公開しているSharePointサーバーにアクセスするプログラムを作成しております。
    そのプログラム側で、SharePointのID/Passwordを管理しています。
    (これがドメインのユーザーIDになっています。『ドメイン名\ユーザー名』の形式です。)

    そのため、ここで管理しているID/Passwordをそのまま使ってSQLサーバーにログインできないものかと考えておりました。
    ユーザーに2つ・3つのIDを入力させることはさすがに抵抗がありましたので……

    結論としては、SQLサーバー認証用のIDとパスワードを作成して、それを使ってアクセスすることにします。

    2013年1月10日 3:15
  • SharePoint の知識はないのでハズレかもしれませんが・・・

    > ドメイン環境なのは、SQL Serverがある環境であって、
    > ユーザーがログインする環境ではありません。
    > そのため、ユーザーがドメインユーザーIDをもっている
    > とは限らないんです。自宅からアクセスする場合などは、
    > ドメインユーザーIDがありません。

    ちょっとググって調べた限りですが、SharePoint は、Windows Server + IIS をベースとした ASP.NET Web アプリケーションとのことなので、ASP.NET Web アプリケーション部分のカスタマイズが可能であれば(ここのところは自分はわかりませんが)、プロトコルトランジッションという手法が使えると思います。

    詳しくは、以下のページの図1及びその説明を見てください。

    How To: ASP.NET 2.0 でプロトコル トランジションと制約付き委任を使用する方法
    http://msdn.microsoft.com/ja-jp/library/ms998355

    2013年1月10日 12:39