現在オフラインです。再接続するためにインターネットの接続を待っています

[ACC2003] Access プロジェクトおよび SQL Server 2000 Desktop Edition でアプリケーション ロールを使用する方法

Office 2003 のサポートは終了しました

マイクロソフトでは、2014 年 4 月 8 日に Office 2003 のサポートを終了しました。この変更は、ソフトウェアの更新プログラムおよびセキュリティ オプションに影響しています。 この変更の意味および保護された状態を維持する方法について説明します。

上級者向け : 高度なコーディング能力、相互運用性、およびマルチユーザー環境の経験が必要です。

この資料は Microsoft Access プロジェクト (.adp) についてのみ記述したものです。

概要
この資料では、Microsoft Access プロジェクト (ADP) で Microsoft SQL Server のアプリケーション ロールを使用する場合の機能、制限事項、および問題の回避方法について説明します。
詳細
SQL Server では、データベース ロールを作成することにより、データベース内の権限をより容易に管理することができます。各ユーザーに権限を個別に付与するのではなく、同じ権限が必要なユーザーを同じ通常のデータベース ロールのメンバに追加し、そのデータベース ロール自体に権限を割り当てることにより、それらのユーザーをグループ化することができます。特定の権限が明示的に拒否されていない限り、メンバ ユーザーにはそのデータベース ロールに付与された権限が与えられます。

通常のデータベース ロールは、ユーザーがデータベースに対してアドホック クエリや更新を実行できるようにする場合には非常に有効ですが、どのような場合にも適切な方法であるとは限りません。場合によっては、ユーザーが特定のアプリケーションを使用する場合にのみ一定の権限を付与し、そのアプリケーションを使用する場合以外はデータの表示や修正ができないようにする必要があります。

このような問題の回避策としてよく使用される方法の 1 つに、1 つの SQL Server ユーザー アカウントに必要な権限だけを付与する方法があります。この場合、実際のユーザーにはデータベースに接続する権限のみが与えられ、データを表示または変更する権限はありません。ユーザーが各自のアカウントを使用してデータベースに接続した後で、ADP でプログラムから、権限を持つユーザー アカウントの資格情報を使用して再接続します。この方法が有効な場合もありますが、データベース内でのユーザーの識別や、特定のアクションを実行したユーザーの確認はできません。

アプリケーション ロールは、このような制限を回避できるように設計されています。通常のデータベース ロールとは異なり、アプリケーション ロールにはメンバがありません。ユーザーは各自の資格情報を使用して SQL Server にログオンし、データベースに接続します。この時点で、sp_setapprole ストアド プロシージャを使用することにより、プログラムから、既存の接続にアプリケーション ロールのセキュリティ コンテキストを適用できます。SQL Server では個々のユーザーが識別されますが、特定の接続で使用可能な権限はアプリケーション ロールの権限に制限されます。個々のユーザーの権限がアプリケーション ロールの権限より大きいか小さいかにかかわらず、個々のユーザーの権限は考慮されません。

アプリケーション ロールの作成

Access 2002 または Access 2000 プロジェクトには、アプリケーション ロールなどの SQL Server セキュリティ オブジェクトを作成するためのビジュアル デザイン ツールはありません。アプリケーション ロールを作成して権限を割り当てる場合、製品版の SQL Server または Microsoft Office XP Developer に含まれているクライアント ツールを使用することをお勧めします。ただし、ADP から Transact-SQL (T-SQL) を使用することにより、プログラムによってアプリケーション ロールを作成し、必要な権限を付与することも可能です。この資料では SQL Server のセキュリティ機能の詳細については説明していません。詳細については、SQL Server Books Online または以下のマイクロソフト MSDN Web サイトを参照してください。プログラムによってアプリケーション ロールを作成し、そのロールにテーブルに対する SELECT 権限を付与するには、以下の手順を実行します。
  1. Access を起動します。
  2. [ヘルプ] メニューの [サンプル データベース] をポイントし、[ノースウィンド サンプル Access プロジェクト] をクリックします。
  3. データベース ウィンドウで、[オブジェクト] の下の [モジュール] をクリックし、[新規作成] をクリックして、Visual Basic Environment で新しいモジュールを開きます。
  4. 新しいモジュールに次のコードを入力するか、貼り付けます。
    Public Function AddNewAppRole(RoleName As String, PW As String) As BooleanOn Error GoTo EH:If CurrentProject.IsConnected ThenDim sTSQL As String    'Create the commandsTSQL = "EXEC sp_addapprole '" & RoleName & "','" & PW & "'"    'Send the commandApplication.CurrentProject.Connection.Execute sTSQLAddNewAppRole = TrueElseAddNewAppRole = FalseEnd IfExit FunctionEH:MsgBox Err.Number & ": " & Err.Description, vbCriticalAddNewAppRole = FalseEnd Function					
  5. モジュールを保存してから、Visual Basic Environment を終了します。
  6. [得意先] テーブルのコピーを作成し、tNewTable として保存します。
    1. データベース ウィンドウで、[得意先] テーブルを右クリックし、ショートカット メニューの [名前を付けて保存] をクリックします。
    2. [名前を付けて保存] ダイアログ ボックスで、['得意先' テーブルの保存先] ボックスに「tNewTable」と入力し、[OK] をクリックして新しいテーブルを完成させます。
  7. データベース ウィンドウで、[オブジェクト] の下の [フォーム] をクリックし、[新規作成] をクリックします。[OK] をクリックし、デザイン ビューで新しいフォームを開きます。
  8. 新しいフォームを作成し、コマンド ボタンを追加します。
  9. 新しいコマンド ボタンの [クリック時] プロパティに以下のイベント プロシージャを設定します。
    On Error GoTo EH:'Code only works if ADP is connected.If CurrentProject.IsConnected Then    Dim bNewAppRole As Boolean, strTSQL As String    Dim strRoleName As String, strPW As String    strRoleName = "AppRoleName"    strPW = "Password"    'Call function to create app role.    bNewAppRole = AddNewAppRole(strRoleName, strPW)    'Test to see if it failed.    If bNewAppRole = False ThenExit SubEnd If    MsgBox "New Application role '" & strRoleName & "' created", vbInformation    'Create command to grant permissions.    strTSQL = "Grant Select on tNewTable to " & strRoleName    'Send the command.    Application.CurrentProject.Connection.Execute strTSQL    MsgBox "Select permissions granted on tNewTable for " & strRoleNameElseMsgBox "ADP must be connected to SQL Server"End IfExit SubEH:MsgBox Err.Number & ": " & Err.Description, vbCritical					
  10. Visual Basic Environment を閉じてフォームに戻ります。
  11. フォームを保存してからフォーム ビューに切り替えます。
  12. コマンド ボタンをクリックして内部のコードを実行します。実行の成功を示す 2 つのメッセージ ボックスが表示されます。アプリケーション ロールが作成された後に最初のメッセージ ボックスが、tNewTable に新しいロールの権限が付与された後に 2 つ目のメッセージ ボックスが表示されます。

アプリケーション ロールの実装

Access プロジェクトでアプリケーション ロールを使用する場合の主な問題は、Access ではさまざまなタスクを処理するために SQL Server に対して 3 種類の接続が使用されることによるものです。理想としては、プロジェクト全体にアプリケーション ロールを適用するには、3 種類の接続すべてのコンテキストで sp_setapprole を実行する必要があります。各接続で処理されるオブジェクトは以下のとおりです。

  1. データベース ウィンドウに表示されるオブジェクトの決定、およびその他のデータベース管理タスクの実行に使用されます。

    テーブル、ビュー、ストアド プロシージャ、関数、およびフォームとサブレポート (ただしメイン レポート自体は除く) のレコード ソースを開くために使用されます。

    コンボ ボックス、リスト ボックス、およびレポートのレコード ソースを取得するために使用されます。
  2. テーブル、ビュー、ストアド プロシージャ、関数、およびフォームとサブレポート (ただしメイン レポート自体は除く) のレコード ソースを開くために使用されます。

    コンボ ボックス、リスト ボックス、およびレポートのレコード ソースを取得するために使用されます。
  3. コンボ ボックス、リスト ボックス、およびレポートのレコード ソースを取得するために使用されます。

接続 2 と 3 には容易にアクセスできますが、接続 1 のコンテキストでストアド プロシージャを実行する方法はありません。さいわい、この接続は 3 つの接続の中で最も重要性が低いので、組み込みのデータベース ウィンドウを使用する代わりに、データベース オブジェクトを処理するための独自のユーザー インターフェイス (メニュー型のフォームなど) を作成することによって容易に問題を回避できます。

以下の手順では、サンプル プロジェクト NorthwindCS を例にとって、接続 2 と 3 にアプリケーション ロールを適用する方法を示します。

  1. データベース ウィンドウで、[オブジェクト] の下の [フォーム] をクリックし、[新規作成] をクリックします。[OK] をクリックし、デザイン ビューで新しいフォームを開きます。
  2. 新しく作成したフォームにリスト ボックスを追加し、そのリスト ボックスの [名前] プロパティに「lst_AppRole」と設定します。
  3. フォームにコマンド ボタンを追加します。
  4. 新しいコマンド ボタンの [クリック時] プロパティに以下のイベント プロシージャを設定します。
    On Error GoTo EH    'This avoids a message that no records were returned.DoCmd.SetWarnings FalseDim TSQLTSQL = "EXEC sp_setapprole 'AppRoleName', {Encrypt N 'Password'}, 'odbc'"    'This sets the app role on Connection #2.Application.CurrentProject.Connection.Execute TSQL    'This sets the app role on Connection #3.lst_approle.RowSource = TSQLlst_approle.RequeryDoCmd.SetWarnings TrueMsgBox "The application Role is now in effect.", vbInformationExit SubEH:MsgBox Err.Number & ": " & Err.Description, vbCritical					
  5. Visual Basic Environment を閉じてフォームに戻ります。
  6. フォームを保存してからフォーム ビューに切り替えます。
  7. コマンド ボタンをクリックして内部のコードを実行します。実行の成功を示すメッセージ ボックスが表示されます。
  8. データベース ウィンドウで、[オブジェクト] の下の [テーブル] をクリックし、tNewTable テーブルを開きます。
  9. レコードを変更してから保存します。
変更をコミットするときに、必要な権限がないことを示すエラー メッセージが表示されます。新しいアプリケーション ロールには、tNewTable テーブルに対する Select 権限は付与されていますが、Update 権限は付与されていないため、このエラーが発生します。

Access の仕様では、ユーザーが少なくとも Select 権限または Execute 権限を持っているオブジェクトだけがデータベース ウィンドウに表示されます。Access では、ユーザーが権限を持っているオブジェクトの確認に接続 1 が使用されます。接続 2 と 3 にアプリケーション ロールを適用後、表示されていたすべてのオブジェクトに対する権限がユーザーに付与されなくなった場合や、現在表示されているよりも多くのオブジェクトに対する権限が付与された場合でも、データベース ウィンドウには適用前と同じオブジェクトが表示されます。これにより、データベース ウィンドウの使用時に予期しない動作が発生する可能性があります。

たとえば、tNewTable テーブルを開くと、ユーザーにレコードの編集と挿入を行う権限があるように見えます。テーブル下部の新規レコード挿入アイコンが有効になっているので、ユーザーは編集モードでレコードを挿入することができます。編集内容または挿入結果をコミットするまで、権限がないことを示すものは表示されず、コミットするときになってエラー メッセージが表示されます。これは、ユーザーが実際には権限を持っていない場合でも、権限を持っていると Access で認識されているためです。

この問題の最も効率の良い回避方法は、データベース ウィンドウのインターフェイスを使用せず、ユーザーにカスタム インターフェイスを提供することです。メニュー型のユーザー インターフェイスを使用することにより、ユーザーがアクセスできるオブジェクトを厳密に制御できます。

その他の制限事項とセキュリティ上の注意点

サブフォームの機能に関する問題

他のデータベース オブジェクトとは異なり、Access では常に同じ接続を使用してサブフォームのデータ ソースが取得されるとは限りません。Access ではしばしば (ただし常にではありません)、サブフォーム レコードセットを処理するため、またはサブフォームをメイン フォームに接続するリンク フィールド データを取得するためだけに、SQL Server への新しい接続が作成されます。この新しい接続にはアプリケーション ロールが適用されないため、データベース オブジェクトに対する明示的な権限がユーザーにない場合は、権限エラーが発生する可能性があります。このことは、アプリケーション ロールを適用している場合、リンクするサブフォームを使用するための確実な方法がないことを意味します。唯一の有効な回避方法は、完全にリンクされていないサブフォームを使用し、プログラムでデータ処理を行う方法です。この制限が、Access でアプリケーション ロールを使用する際の最も大きな制限です。

レポートの機能に関する問題

レポートまたはサブレポートのレコード ソースとして一覧に表示されたテーブル名やビュー名などのオブジェクトがある場合、Access では SQL Server からデータを取得する前に、データベース ウィンドウの一覧にオブジェクトが表示されているかどうかがチェックされます。データベース ウィンドウではアプリケーション ロールが適用されていない接続が使用されるため、基になるデータ ソースに対する明示的な権限がない場合はエラーが生成されます。

この問題を回避するには、フォームやレポートのレコード ソースには必ず Transact-SQL ステートメントを使用します。たとえば、単に "ViewName" ではなく "Select * from ViewName" を、"StoredProcedureName" ではなく "Exec StoredProcedureName" を使用します。これにより、Access から Transact-SQL ステートメントが直接 SQL Server に渡され、アプリケーション ロールの権限に基づいてデータが取得されます。

パブリック データベース ロール

アプリケーション ロールは、パブリック データベース ロールの権限を取得します。NorthwindCS のデフォルトでは、大部分のオブジェクトに対するすべての権限がパブリック ロールに割り当てられています。このため、アプリケーション ロールを使用してもほとんど効果はありません。この資料の「アプリケーション ロールの作成」に記載されている手順で tNewTable テーブルを作成した場合、パブリック ロールにはそのテーブルに対する権限が付与されていないため、そのテーブルではアプリケーション ロールのセキュリティ コンテキストの効果を確認できます。ただし、その他のテーブルでは、パブリック ロールにそれらのオブジェクトに対する権限があるため、アプリケーション ロールを使用しても結果が異なることはありません。

VBA セキュリティ

アプリケーション ロールのパスワードは呼び出されるアプリケーションに埋め込まれているため、専門知識のあるユーザーがソース コードからアプリケーション ロール名とパスワードを読み取り、その情報を使用して別のアプリケーションから SQL Server にアクセスすることができます。このため、ソース コードを表示できないように、ADP を ADE ファイルにコンパイルすることをお勧めします。少なくとも、VBA プロジェクトではパスワードを使用するようにします。
ACC2002 reviewdocid
関連情報
この資料のトピックの Microsoft Access 2000 での関連情報については、以下の「サポート技術情報」 (Microsoft Knowledge Base) をクリックしてください。
318816 ACC2000: How to Use Application Roles with Access Projects and SQL Server 2000 Desktop Engine (MSDE 2000)
関連情報
この資料は米国 Microsoft Corporation から提供されている Knowledge Base の Article ID 308312 (最終更新日 2003-10-13) を基に作成したものです。

この資料に含まれているサンプル コード/プログラムは英語版を前提に書かれたものをありのままに記述しており、日本語環境での動作は確認されておりません。
プロパティ

文書番号:308312 - 最終更新日: 11/06/2003 18:04:06 - リビジョン: 5.1

Microsoft Office Access 2003, Microsoft Access 2002 Standard Edition

  • kbhowto KB308312
フィードバック