0

asp.netmvc3プロジェクトのデータベースに接続します。また、ソリューションにWindowsサービスプロジェクトがあり、イベントによってはこのデータベースにデータが書き込まれます。

難しいのは、Windowsサービスプロジェクトのコードをデータベースに接続する必要がある場合、次のようになりますSqlException

ログインで要求されたデータベース「WebStore」を開くことができません。ログインに失敗しました。ユーザー'NTAUTHORITY\SYSTEM'のログインに失敗しました。

Windowsサービスのコードは次のとおりです。

    public static string GetConnectionString()
    {
        return @"Data Source=(LocalDB)\v11.0; DataBase=WebStore; 
                AttachDbFilename=myDbFullPath;
                Integrated Security=True;Connect Timeout=30";
    }

そして、データベースに書き込むイベントハンドラーでは、次のようになります。

using (var conn = new SqlConnection(GetConnectionString()))
{
    conn.Open();
    var productId = Convert.ToInt32(Regex.Match(e.Name, @"\d+").Value);
    const string cmd1 = "UPDATE Products SET ImageModifiedDate=@date WHERE ProductId=@productId";

    using (var command = new SqlCommand(cmd1, conn))
    {
        command.Parameters.AddWithValue("@productId", productId);
        command.Parameters.AddWithValue("@date", DateTime.Now);
        command.ExecuteNonQuery();
    }
 }

例外はconn.Open();インラインで発生します。この行にコメントすると、次の場所で新しい例外が発生しcommand.ExecuteNonQuery();ます。

InvalidOperationException:ExecuteNonQueryには、開いて使用可能な接続が必要です。接続が閉じられます。

質問:別のプロジェクトに既に接続されているSQL Serverデータベースへの接続を開くにはどうすればよいですか?

編集1:次のコードを使用して、DBに新しいログインと新しいユーザーを作成します。

CREATE LOGIN user1
WITH PASSWORD = 'password1';
GO
CREATE USER user1 FOR LOGIN user1;
GO

サーバーエクスプローラーでDBを接続しようとしているよりも、[SQL Server認証を使用する]を選択し、ユーザー名:user1、パスワード:password1を入力します。

そして私は得る:

データベースへの接続の試行が次の情報で失敗しました:
ユーザー'user1'のログインに失敗しました。

編集2:このプロパティを設定します:

processInstaller.Username = "user1";
processInstaller.Password = "password1";

そしてcmdで実行するより:

installutil /name=user1 /password=password1 MyService.exe

そして私は得るSystem.ComponentModel.Win32.Exception:
the comparison between user names and security identifiers haven't been executed.

私は何を間違えますか?

編集3: ユーザー名とパスワードをservices.mscに設定し、processInstallerの「アカウント」プロパティを「ローカルシステム」に残しました。実行されますが、イメージ(およびデータベースにアクセスしようとしているイベントハンドラー)を変更すると、次のようになります。

Cannot attach file 'C:\Users\Aleksey\repos\working-copy\WebStore\WebStore\App_Data\WebStore.mdf' as database 'WebStore' because this file is already in use for database 'C:\USERS\ALEKSEY\REPOS\WORKING-COPY\WEBSTORE\WEBSTORE\APP_DATA\WEBSTORE.MDF',

接続文字列に、データベースに作成したユーザーの資格情報を追加しました。

User Id=user1;PASSWORD=password1;

また、サーバーエクスプローラーで接続を追加して使用しようとするSql Server Authenticationと、入力するuser1password1Edit1からメッセージが表示されます

サーバーエクスプローラー*Windows Authentication*とWindowsサービスで接続文字列を使用する必要がありますUser Id=user1;PASSWORD=password1;か?

4

1 に答える 1

1
Cannot open database "WebStore" requested by the login. The login failed. Login failed for user 'NT AUTHORITY\SYSTEM'.

これは、サービスがLocalSystemアカウントで実行されており、統合セキュリティを使用してSQLサーバーに接続しているため、SYSTEMがそこにアクセスできないために発生します。したがって、3つの選択肢:

  1. SQLServer認証に切り替えます。これには、データベースへのログインの作成と接続文字列の変更が含まれます
  2. 本当に必要な特権のみを持つ特定のユーザーでサービスを実行し(これは実際には良い考えです)、統合されたセキュリティで接続できるように、そのユーザーにデータベースへのアクセスを許可します。コードを変更する必要がないため、これが最も簡単です。
  3. 本当にSYSTEMとして実行する必要がある場合は、偽装を使用して、LogonUserを使用して別のユーザー(オプション2のユーザーなど)に切り替えることができます。そうすれば、データベースアクセスのためだけにオプション2になり、残りのサービスコードに対してSYSTEM特権を保持することになります。

2番目のエラー

InvalidOperationException: Opened and available connection is needed for ExecuteNonQuery. Connection is closed.

最初のエラーが原因で、接続を開かないとこれが発生します。接続が開いていないと何も実行できません。ADO.Netがそれを確認します。

したがって、重要なのは最初のエラーだけです。

セキュリティ慣行の観点から最善のオプション2を選択することをお勧めします。統合セキュリティで実行しているため、パスワードを保存する必要はありません。これは、アプリケーションが異なる複数の環境にある場合にプラスになります。データベース、ユーザー、パスワード、そしてあなたが持っているもの。環境、権限ごとのユーザーだけで、設定が完了します。

于 2013-02-27T13:18:09.163 に答える