IIS 7 での読み取り専用サンプル XML メンバーシップおよび役割プロバイダーの使用方法

公開日: 2009 年 1 月 3 日 (作業者: robmcm (英語))

更新日: 2009 年 7 月 23 日 (作業者: robmcm (英語))

はじめに

ASP.NET 2.0 がリリースされたときに、Microsoft Developer Network (MSDN) Web サイトで ASP.NET メンバーシップおよび役割用のサンプル プロバイダーが 2 つ提供されました。これらのプロバイダーは、ユーザーおよび役割のリストに XML ファイルを使用した読み取り専用プロバイダーであり、以下の URL から入手できました。

これらのサンプルは、IIS 7 での Web サイトの実践やテスト用として優れたものですが、IIS 7 のセキュリティの設計方法が原因で、その記述のとおりには IIS 7 で動作しません。元の説明では、これらのメンバーシップおよび役割プロバイダーのサンプルを Web サイトの App_Code フォルダーに展開できますが、IIS 7 でプロバイダーを展開するには、その前にプロバイダーをグローバル アセンブリ キャッシュ (GAC) に登録する必要があります。この点を考慮し、以下のステップに従うことで、読み取り専用 XML プロバイダーをコンパイルして開発システムに展開できます。

必要条件

この記事の手順を完了するには、以下の項目が必須です。

  1. Windows Vista または Windows Server 2008 コンピューターに IIS 7 がインストールされている必要があります。
  2. IIS 7 に ASP.NET がインストールされている必要があります。
  3. IIS 7 のインターネット インフォメーション サービス マネージャーがインストールされている必要があります。
  4. IIS 7 コンピューターに Gacutil.exe があることを確認してください。Gacutil.exe は、アセンブリをグローバル アセンブリ キャッシュ (GAC) に追加するのに必要なツールです。

ステップ 1: XML プロバイダー プロジェクトのセットアップ

この最初のステップでは、Visual Studio でプロジェクトを 2 つ含むソリューションを作成します。プロジェクトの 1 つは XML に基づくメンバーシップ プロバイダーで、もう 1 つは XML に基づく役割プロバイダーです。

  1. Microsoft Visual Studio 2008 を開きます。
  2. [ファイル] メニューの [新規作成] をクリックし、[プロジェクト] をクリックします。
  3. [新しいプロジェクト] ダイアログで以下の操作を行います。
    • プロジェクトの種類として [Visual C#] を選択します。
    • テンプレートとして [クラス ライブラリ] を選択します。
    • プロジェクト名として「ReadOnlyXmlMembershipProvider」と入力します。
    • ソリューション名として「ReadOnlyXmlProviders」と入力します。
    • [OK] をクリックします。
  4. ReadOnlyXmlMembershipProvider プロジェクトから Class1.cs を削除します。
    • ソリューション エクスプローラーで、[ReadOnlyXmlMembershipProvider] 内の [Class1.cs] ファイルを右クリックし、[削除] をクリックします。
    • プロンプトが表示されたら [OK] をクリックして、このクラスを完全に削除します。
  5. System.Configuration ライブラリへの参照パスを追加します。
    • ソリューション エクスプローラーで、[ReadOnlyXmlMembershipProvider] プロジェクトを右クリックし、[参照の追加] をクリックします。
    • [.NET] タブをクリックします。
    • アセンブリの一覧の [System.Configuration] をクリックします。
    • [OK] をクリックします。
  6. System.Web ライブラリへの参照パスを追加します。
    • ソリューション エクスプローラーで、[ReadOnlyXmlMembershipProvider] プロジェクトを右クリックし、[参照の追加] をクリックします。
    • [.NET] タブをクリックします。
    • アセンブリの一覧の [System.Web] をクリックします。
    • [OK] をクリックします。
  7. 厳密な名前のキーをプロジェクトに追加します。
    • ソリューション エクスプローラーで、[ReadOnlyXmlRoleProvider] プロジェクトを右クリックし、[プロパティ] をクリックします。
    • [署名] タブをクリックします。
    • [アセンブリの署名] チェック ボックスをオンにします。
    • 厳密なキー名を選択するドロップダウン ボックスから [<新規作成>] を選択します。
    • キー ファイルの名前として「ReadOnlyXmlMembershipProviderKey」と入力します。
    • 必要な場合、キー ファイル用のパスワードを入力します。不要な場合は、[キー ファイルをパスワードで保護する] チェック ボックスをオフにします。
    • [OK] をクリックします。
  8. (オプション) DLL を GAC に自動的に登録するためのカスタム ビルド イベントを追加します。
    • ソリューション エクスプローラーで、[ReadOnlyXmlRoleProvider] プロジェクトを右クリックし、[プロパティ] をクリックします。
    • [ビルド イベント] タブをクリックします。
    • [ビルド後に実行するコマンド ライン] ボックスに、次を入力します。
      call "%VS90COMNTOOLS%\vsvars32.bat">nul
      gacutil.exe /if "$(TargetPath)"
  9. 2 つ目のプロジェクトをソリューションに追加します。
    • [ファイル] メニューの [追加] をクリックし、[新しいプロジェクト] をクリックします。
    • プロジェクトの種類として [Visual C#] を選択します。
    • テンプレートとして [クラス ライブラリ] を選択します。
    • プロジェクト名として「ReadOnlyXmlRoleProvider」と入力します。
    • [OK] をクリックします。
  10. ReadOnlyXmlRoleProvider プロジェクトから Class1.cs を削除します。
    • ソリューション エクスプローラーで、[ReadOnlyXmlRoleProvider] 内の [Class1.cs] ファイルを右クリックし、[削除] をクリックします。
    • プロンプトが表示されたら [OK] をクリックして、このクラスを完全に削除します。
  11. System.Configuration ライブラリへの参照パスを追加します。
    • ソリューション エクスプローラーで、[ReadOnlyXmlRoleProvider] プロジェクトを右クリックし、[参照の追加] をクリックします。
    • [.NET] タブをクリックします。
    • アセンブリの一覧の [System.Configuration] をクリックします。
    • [OK] をクリックします。
  12. System.Web ライブラリへの参照パスを追加します。
    • ソリューション エクスプローラーで、[ReadOnlyXmlRoleProvider] プロジェクトを右クリックし、[参照の追加] をクリックします。
    • [.NET] タブをクリックします。
    • アセンブリの一覧の [System.Web] をクリックします。
    • [OK] をクリックします。
  13. 厳密な名前のキーをプロジェクトに追加します。
    • ソリューション エクスプローラーで、[ReadOnlyXmlRoleProvider] プロジェクトを右クリックし、[プロパティ] をクリックします。
    • [署名] タブをクリックします。
    • [アセンブリの署名] チェック ボックスをオンにします。
    • 厳密なキー名を選択するドロップダウン ボックスから [<新規作成>] を選択します。
    • キー ファイルの名前として「ReadOnlyXmlRoleProvider」と入力します。
    • 必要な場合、キー ファイル用のパスワードを入力します。不要な場合は、[キー ファイルをパスワードで保護する] チェック ボックスをオフにします。
    • [OK] をクリックします。
  14. (オプション) DLL を GAC に自動的に登録するためのカスタム ビルド イベントを追加します。
    • ソリューション エクスプローラーで、[ReadOnlyXmlRoleProvider] プロジェクトを右クリックし、[プロパティ] をクリックします。
    • [ビルド イベント] タブをクリックします。
    • [ビルド後に実行するコマンド ライン] ボックスに、次を入力します。
      call "%VS90COMNTOOLS%\vsvars32.bat">nul
      gacutil.exe /if "$(TargetPath)"
  15. ソリューションを保存します。

ステップ 2: プロジェクトへのプロバイダー クラスの追加

この 2 番目のステップでは、XML に基づくメンバーシップおよび役割プロバイダー用にクラスを作成します。これらのクラスのコードは、MSDN の「メンバーシップ プロバイダー (英語)」および「役割プロバイダー (英語)」からコピーします。

  1. ReadOnlyXmlMembershipProvider プロジェクトに新しいクラスを追加します。
    • ソリューション エクスプローラーで、[ReadOnlyXmlMembershipProvider] プロジェクトを右クリックし、[追加] をクリックしてから [クラス] をクリックします。

    • クラスに「ReadOnlyXmlMembershipProvider.cs」と名前を付けます。

    • [追加] をクリックします。

    • 既存のコードを削除します。

    • メンバーシップ プロバイダー (英語)」トピックからの以下のサンプル コードを、エディターに貼り付けます。

      using System;
      using System.Xml;
      using System.Collections.Generic;
      using System.Collections.Specialized;
      using System.Configuration.Provider;
      using System.Web.Security;
      using System.Web.Hosting;
      using System.Web.Management;
      using System.Security.Permissions;
      using System.Web;
      public class ReadOnlyXmlMembershipProvider : MembershipProvider
      {
      private Dictionary<string, MembershipUser> _Users;
      private string _XmlFileName;
      // MembershipProvider プロパティ
      public override string ApplicationName
      {
      get { throw new NotSupportedException(); }
      set { throw new NotSupportedException(); }
      }
      public override bool EnablePasswordRetrieval
      {
      get { return false; }
      }
      public override bool EnablePasswordReset
      {
      get { return false; }
      }
      public override int MaxInvalidPasswordAttempts
      {
      get { throw new NotSupportedException(); }
      }
      public override int MinRequiredNonAlphanumericCharacters
      {
      get { throw new NotSupportedException(); }
      }
      public override int MinRequiredPasswordLength
      {
      get { throw new NotSupportedException(); }
      }
      public override int PasswordAttemptWindow
      {
      get { throw new NotSupportedException(); }
      }
      public override MembershipPasswordFormat PasswordFormat
      {
      get { throw new NotSupportedException(); }
      }
      public override string PasswordStrengthRegularExpression
      {
      get { throw new NotSupportedException(); }
      }
      public override bool RequiresQuestionAndAnswer
      {
      get { throw new NotSupportedException(); }
      }
      public override bool RequiresUniqueEmail
      {
      get { throw new NotSupportedException(); }
      }
      // MembershipProvider メソッド
      public override void Initialize(string name,
      NameValueCollection config)
      {
      // config が null でないことを検証します
      if (config == null)
      throw new ArgumentNullException("config");
      // プロバイダーに名前が付いていない場合に既定の名前を割り当てます
      if (String.IsNullOrEmpty(name))
      name = "ReadOnlyXmlMembershipProvider";
      // "description" 属性が存在しないまたは空の場合に、config に既定の
      // "description" 属性を割り当てます
      if (string.IsNullOrEmpty(config["description"]))
      {
      config.Remove("description");
      config.Add("description",
      "Read-only XML membership provider");
      }
      // base クラスの Initialize メソッドを呼び出します
      base.Initialize(name, config);
      // XmlFileName を初期化し、そのパスがアプリケーションに対する
      // 相対的パスであることを確認します
      string path = config["xmlFileName"];
      if (String.IsNullOrEmpty(path))
      path = "~/App_Data/Users.xml";
      if (!VirtualPathUtility.IsAppRelative(path))
      throw new ArgumentException
      ("xmlFileName must be app-relative");
      string fullyQualifiedPath = VirtualPathUtility.Combine
      (VirtualPathUtility.AppendTrailingSlash
      (HttpRuntime.AppDomainAppVirtualPath), path);
      _XmlFileName = HostingEnvironment.MapPath(fullyQualifiedPath);
      config.Remove("xmlFileName");
      // XML データ ソースを読み取るためのアクセス許可があることを確認し、
      // ない場合は例外をスローします
      FileIOPermission permission =
      new FileIOPermission(FileIOPermissionAccess.Read,
      _XmlFileName);
      permission.Demand();
      // 認識されない属性が残っている場合は例外をスローします
      if (config.Count > 0)
      {
      string attr = config.GetKey(0);
      if (!String.IsNullOrEmpty(attr))
      throw new ProviderException
      ("Unrecognized attribute: " + attr);
      }
      }
      public override bool ValidateUser(string username, string password)
      {
      // 入力パラメーターを検証します
      if (String.IsNullOrEmpty(username) ||
      String.IsNullOrEmpty(password))
      return false;
      try
      {
      // データ ソースが読み込まれたことを確認します
      ReadMembershipDataStore();
      // ユーザー名とパスワードを検証します
      MembershipUser user;
      if (_Users.TryGetValue(username, out user))
      {
      if (user.Comment == password) // Case-sensitive
      {
      // メモ: メンバーシップ プロバイダーの読み取りまたは書き込みによって
      // ユーザーの LastLoginDate がここで更新されます。
      // 完全に実装されたプロバイダーであれば、
      // AuditMembershipAuthenticationSuccess Web イベントも
      // 生成します。
      return true;
      }
      }
      // メモ: 完全に実装されたメンバーシップ プロバイダーであれば、
      // AuditMembershipAuthenticationFailure Web イベントも
      // ここで生成します。
      return false;
      }
      catch (Exception)
      {
      return false;
      }
      }
      public override MembershipUser GetUser(string username,
      bool userIsOnline)
      {
      // メモ: この実装では userIsOnline は無視されます
      // 入力パラメーターを検証します
      if (String.IsNullOrEmpty(username))
      return null;
      // データ ソースが読み込まれたことを確認します
      ReadMembershipDataStore();
      // データ ソースからユーザーを取得します。
      MembershipUser user;
      if (_Users.TryGetValue(username, out user))
      return user;
      return null;
      }
      public override MembershipUserCollection GetAllUsers(int pageIndex,
      int pageSize, out int totalRecords)
      {
      // メモ: この実装では pageIndex および pageSize は無視され、
      // 返される MembershipUser オブジェクトは並べ替えられません
      // データ ソースが読み込まれたことを確認します
      ReadMembershipDataStore();
      MembershipUserCollection users =
      new MembershipUserCollection();
      foreach (KeyValuePair<string, MembershipUser> pair in _Users)
      users.Add(pair.Value);
      totalRecords = users.Count;
      return users;
      }
      public override int GetNumberOfUsersOnline()
      {
      throw new NotSupportedException();
      }
      public override bool ChangePassword(string username,
      string oldPassword, string newPassword)
      {
      throw new NotSupportedException();
      }
      public override bool
      ChangePasswordQuestionAndAnswer(string username,
      string password, string newPasswordQuestion,
      string newPasswordAnswer)
      {
      throw new NotSupportedException();
      }
      public override MembershipUser CreateUser(string username,
      string password, string email, string passwordQuestion,
      string passwordAnswer, bool isApproved, object providerUserKey,
      out MembershipCreateStatus status)
      {
      throw new NotSupportedException();
      }
      public override bool DeleteUser(string username,
      bool deleteAllRelatedData)
      {
      throw new NotSupportedException();
      }
      public override MembershipUserCollection
      FindUsersByEmail(string emailToMatch, int pageIndex,
      int pageSize, out int totalRecords)
      {
      throw new NotSupportedException();
      }
      public override MembershipUserCollection
      FindUsersByName(string usernameToMatch, int pageIndex,
      int pageSize, out int totalRecords)
      {
      throw new NotSupportedException();
      }
      public override string GetPassword(string username, string answer)
      {
      throw new NotSupportedException();
      }
      public override MembershipUser GetUser(object providerUserKey,
      bool userIsOnline)
      {
      throw new NotSupportedException();
      }
      public override string GetUserNameByEmail(string email)
      {
      throw new NotSupportedException();
      }
      public override string ResetPassword(string username,
      string answer)
      {
      throw new NotSupportedException();
      }
      public override bool UnlockUser(string userName)
      {
      throw new NotSupportedException();
      }
      public override void UpdateUser(MembershipUser user)
      {
      throw new NotSupportedException();
      }
      // ヘルパー メソッド
      private void ReadMembershipDataStore()
      {
      lock (this)
      {
      if (_Users == null)
      {
      _Users = new Dictionary<string, MembershipUser>
      (16, StringComparer.InvariantCultureIgnoreCase);
      XmlDocument doc = new XmlDocument();
      doc.Load(_XmlFileName);
      XmlNodeList nodes = doc.GetElementsByTagName("User");
      foreach (XmlNode node in nodes)
      {
      MembershipUser user = new MembershipUser(
      Name,                       // プロバイダー名
      node["UserName"].InnerText, // Username
      null,                       // providerUserKey
      node["EMail"].InnerText,    // Email
      String.Empty,               // passwordQuestion
      node["Password"].InnerText, // Comment
      true,                       // isApproved
      false,                      // isLockedOut
      DateTime.Now,               // creationDate
      DateTime.Now,               // lastLoginDate
      DateTime.Now,               // lastActivityDate
      DateTime.Now,               // lastPasswordChangedDate
      new DateTime(1980, 1, 1)    // lastLockoutDate
      );
      _Users.Add(user.UserName, user);
      }
      }
      }
      }
      }
      
  2. ReadOnlyXmlRoleProvider プロジェクトに新しいクラスを追加します。
    • ソリューション エクスプローラーで、[ReadOnlyXmlRoleProvider] プロジェクトを右クリックし、[追加] をクリックしてから [クラス] をクリックします。

    • クラスに「ReadOnlyXmlRoleProvider.cs」と名前を付けます。

    • [追加] をクリックします。

    • 既存のコードを削除します。

    • 役割プロバイダー (英語)」の以下のサンプル コードをエディターに貼り付けます。

      using System;
      using System.Web.Security;
      using System.Collections.Generic;
      using System.Collections.Specialized;
      using System.Configuration.Provider;
      using System.Web.Hosting;
      using System.Xml;
      using System.Security.Permissions;
      using System.Web;
      public class ReadOnlyXmlRoleProvider : RoleProvider
      {
      private Dictionary<string, string[]> _UsersAndRoles =
      new Dictionary<string, string[]>(16,
      StringComparer.InvariantCultureIgnoreCase);
      private Dictionary<string, string[]> _RolesAndUsers =
      new Dictionary<string, string[]>(16,
      StringComparer.InvariantCultureIgnoreCase);
      private string _XmlFileName;
      // RoleProvider プロパティ
      public override string ApplicationName
      {
      get { throw new NotSupportedException(); }
      set { throw new NotSupportedException(); }
      }
      // RoleProvider メソッド
      public override void Initialize(string name,
      NameValueCollection config)
      {
      // config が null でないことを検証します
      if (config == null)
      throw new ArgumentNullException("config");
      // プロバイダーに名前が付いていない場合に既定の名前を割り当てます
      if (String.IsNullOrEmpty(name))
      name = "ReadOnlyXmlRoleProvider";
      // "description" 属性が存在しないまたは空の場合に、config に既定の
      // "description" 属性を割り当てます
      if (string.IsNullOrEmpty(config["description"]))
      {
      config.Remove("description");
      config.Add("description", "Read-only XML role provider");
      }
      // base クラスの Initialize メソッドを呼び出します
      base.Initialize(name, config);
      // XmlFileName を初期化し、そのパスがアプリケーションに対する
      // 相対的パスであることを確認します
      string path = config["xmlFileName"];
      if (String.IsNullOrEmpty(path))
      path = "~/App_Data/Users.xml";
      if (!VirtualPathUtility.IsAppRelative(path))
      throw new ArgumentException
      ("xmlFileName must be app-relative");
      string fullyQualifiedPath = VirtualPathUtility.Combine
      (VirtualPathUtility.AppendTrailingSlash
      (HttpRuntime.AppDomainAppVirtualPath), path);
      _XmlFileName = HostingEnvironment.MapPath(fullyQualifiedPath);
      config.Remove("xmlFileName");
      // XML データ ソースを読み取るためのアクセス許可があることを確認し、
      // ない場合は例外をスローします
      FileIOPermission permission =
      new FileIOPermission(FileIOPermissionAccess.Read,
      _XmlFileName);
      permission.Demand();
      // 認識されない属性が残っている場合は例外をスローします
      if (config.Count > 0)
      {
      string attr = config.GetKey(0);
      if (!String.IsNullOrEmpty(attr))
      throw new ProviderException
      ("Unrecognized attribute: " + attr);
      }
      // 役割データ ソースを読み取ります。メモ: 
      // ReadOnlyXmlMembershipProvider とは異なり、このプロバイダーは
      // この時点でデータ ソースを読み取ることができます。これは
      // ReadRoleDataStore が役割マネージャーを呼び出さないからです
      ReadRoleDataStore();
      }
      public override bool IsUserInRole(string username, string roleName)
      {
      // 入力パラメーターを検証します
      if (username == null || roleName == null)
      throw new ArgumentNullException();
      if (username == String.Empty || roleName == string.Empty)
      throw new ArgumentException();
      // ユーザー名と役割名が有効であることを確認します
      if (!_UsersAndRoles.ContainsKey(username))
      throw new ProviderException("Invalid user name");
      if (!_RolesAndUsers.ContainsKey(roleName))
      throw new ProviderException("Invalid role name");
      // 指定された役割にユーザーが含まれているかどうかを判断します 
      string[] roles = _UsersAndRoles[username];
      foreach (string role in roles)
      {
      if (String.Compare(role, roleName, true) == 0)
      return true;
      }
      return false;
      }
      public override string[] GetRolesForUser(string username)
      {
      // 入力パラメーターを検証します
      if (username == null)
      throw new ArgumentNullException();
      if (username == string.Empty)
      throw new ArgumentException();
      // ユーザー名が有効であることを確認します
      string[] roles;
      if (!_UsersAndRoles.TryGetValue(username, out roles))
      throw new ProviderException("Invalid user name");
      // 役割名を返します
      return roles;
      }
      public override string[] GetUsersInRole(string roleName)
      {
      // 入力パラメーターを検証します
      if (roleName == null)
      throw new ArgumentNullException();
      if (roleName == string.Empty)
      throw new ArgumentException();
      // 役割名が有効であることを確認します
      string[] users;
      if (!_RolesAndUsers.TryGetValue(roleName, out users))
      throw new ProviderException("Invalid role name");
      // ユーザー名を返します
      return users;
      }
      public override string[] GetAllRoles()
      {
      int i = 0;
      string[] roles = new string[_RolesAndUsers.Count];
      foreach (KeyValuePair<string, string[]> pair in _RolesAndUsers)
      roles[i++] = pair.Key;
      return roles;
      }
      public override bool RoleExists(string roleName)
      {
      // 入力パラメーターを検証します
      if (roleName == null)
      throw new ArgumentNullException();
      if (roleName == string.Empty)
      throw new ArgumentException();
      // 役割が存在するかどうかを判断します
      return _RolesAndUsers.ContainsKey(roleName);
      }
      public override void CreateRole(string roleName)
      {
      throw new NotSupportedException();
      }
      public override bool DeleteRole(string roleName,
      bool throwOnPopulatedRole)
      {
      throw new NotSupportedException();
      }
      public override void AddUsersToRoles(string[] usernames,
      string[] roleNames)
      {
      throw new NotSupportedException();
      }
      public override string[] FindUsersInRole(string roleName,
      string usernameToMatch)
      {
      throw new NotSupportedException();
      }
      public override void RemoveUsersFromRoles(string[] usernames,
      string[] roleNames)
      {
      throw new NotSupportedException();
      }
      // ヘルパー メソッド
      private void ReadRoleDataStore()
      {
      XmlDocument doc = new XmlDocument();
      doc.Load(_XmlFileName);
      XmlNodeList nodes = doc.GetElementsByTagName("User");
      foreach (XmlNode node in nodes)
      {
      if (node["UserName"] == null)
      throw new ProviderException
      ("Missing UserName element");
      string user = node["UserName"].InnerText;
      if (String.IsNullOrEmpty(user))
      throw new ProviderException("Empty UserName element");
      if (node["Roles"] == null ||
      String.IsNullOrEmpty(node["Roles"].InnerText))
      _UsersAndRoles.Add(user, new string[0]);
      else
      {
      string[] roles = node["Roles"].InnerText.Split(',');
      // 役割名を _UsersAndRoles に追加し、それらを
      // ユーザー名で照合します
      _UsersAndRoles.Add(user, roles);
      foreach (string role in roles)
      {
      // ユーザー名を _RolesAndUsers に追加し、それらを
      // 役割名で照合します
      string[] users1;
      if (_RolesAndUsers.TryGetValue(role, out users1))
      {
      string[] users2 =
      new string[users1.Length + 1];
      users1.CopyTo(users2, 0);
      users2[users1.Length] = user;
      _RolesAndUsers.Remove(role);
      _RolesAndUsers.Add(role, users2);
      }
      else
      _RolesAndUsers.Add(role,
      new string[] { user });
      }
      }
      }
      }
      }
      
  3. 両方のプロジェクトを保存してコンパイルします。

メモ: GAC にアセンブリを登録するオプションのステップを使用しなかった場合は、アセンブリを IIS 7 コンピューターに手動でコピーし、Gacutil.exe ツールを使用して GAC にアセンブリを追加する必要があります。詳細については、マイクロソフトの MSDN Web サイトの次のトピックを参照してください。

グローバル アセンブリ キャッシュ ツール (Gacutil.exe)

ステップ 3: IIS へのプロバイダーの追加

この 3 番目のステップでは、メンバーシップおよび役割プロバイダーのアセンブリ情報を判断し、その情報を IIS の信頼済みプロバイダーの一覧に追加します。

  1. 両プロバイダーのアセンブリ情報を判断します。
    • Windows Explorer で、パス C:\Windows\assembly を開きます。ここで、C: はオペレーティング システム ドライブです。
    • ReadOnlyXmlMembershipProvider および ReadOnlyXmlRoleProvider アセンブリを探します。
    • 各アセンブリを右クリックし、[プロパティ] をクリックします。
    • [カルチャ] の値 ([Neutral] など) をコピーします。
    • [バージョン] 番号 ([1.0.0.0] など) をコピーします。
    • [公開キー トークン] の値 ([426f62526f636b73] など) をコピーします。
    • [キャンセル] をクリックします。
  2. XML プロバイダーを IIS の信頼済みプロバイダーの一覧に追加します。
    • Administration.config file を編集するために開きます。(メモ: このファイルは、%WinDir%\System32\Inetsrv\Config フォルダーにあります。

    • 前のステップで得たアセンブリ プロパティを持つプロバイダーを、次の構文を使用して <trustedProviders> セクションに追加します。

      <add type="ReadOnlyXmlMembershipProvider, ReadOnlyXmlMembershipProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=426f62526f636b73" />
      
      
      
      
      <add type="ReadOnlyXmlRoleProvider, ReadOnlyXmlRoleProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=426f62526f636b73" />
      
    • Administration.config ファイルを保存して閉じます。

ステップ 4: XML プロバイダーを使用したフォーム認証用サイトの構成

この 4 番目のステップでは、XML に基づくメンバーシップおよび役割プロバイダーによるフォーム認証を使用する Web サイトを構成します。この構成のために、Web サイトの Web.config ファイルを手動で作成し、ユーザーのリストを含む XML ファイルを Web サイトの App_Data フォルダーに追加して、フォーム認証要求を処理する Login.aspx ページを Web サイトに追加します。

  1. メンバーシップ ユーザーおよび役割用に XML ファイルを作成します。
    • テキスト エディターに次のコードを貼り付けます。

      <Users>
      <User>
      <UserName>Bob</UserName>
      <Password>contoso!</Password>
      <EMail>bob@contoso.com</EMail>
      <Roles>Members</Roles>
      </User>
      <User>
      <UserName>Alice</UserName>
      <Password>contoso!</Password>
      <EMail>alice@contoso.com</EMail>
      <Roles>Members,Administrators</Roles>
      </User>
      </Users>
      
    • このコードを Users.xml として Web サイトの App_Data フォルダーに保存します。

  2. Web サイト用の Login.aspx ファイルを作成します。
    • テキスト エディターに次のコードを貼り付けます。

      <%@ Page Language="C#" %>
      <%@ Import Namespace="System.ComponentModel" %>
      <html>
      <head runat="server">
      <title>Login Page</title>
      </head>
      <body>
      <form id="form1" runat="server">
      <asp:Login id="Login1" runat="server"
      BorderStyle="Solid"
      BackColor="#ffffcc"
      BorderWidth="1px"
      BorderColor="#cccc99"
      Font-Size="10pt"
      Font-Names="Verdana">
      <TitleTextStyle Font-Bold="True"
      ForeColor="#ffffff"
      BackColor="#666666"/>
      </asp:Login>
      </form>
      </body>
      </html>
      
    • このコードを Login.aspx として Web サイトのルートに保存します。

  3. Web サイト用の Web.config ファイルを作成します。
    • テキスト エディターに次のコードを貼り付けます。

      <configuration>
         <system.web>
            <!-- 読み取り専用 XML メンバーシップ プロバイダーを追加し、既定に設定します。-->
            <membership defaultProvider="AspNetReadOnlyXmlMembershipProvider">
               <providers>
                  <add name="AspNetReadOnlyXmlMembershipProvider"
                     type="ReadOnlyXmlMembershipProvider, ReadOnlyXmlMembershipProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=91454274822e8111"
                     description="Read-only XML membership provider"
                     xmlFileName="~/App_Data/Users.xml" />
               </providers>
            </membership>
            <!-- 読み取り専用 XML 役割プロバイダーを追加し、既定に設定します。-->
            <roleManager enabled="true" defaultProvider="AspNetReadOnlyXmlRoleProvider">
               <providers>
                  <add name="AspNetReadOnlyXmlRoleProvider"
                     type="ReadOnlyXmlRoleProvider, ReadOnlyXmlRoleProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a9c0f8ad39898a3c"
                     description="Read-only XML role provider"
                     xmlFileName="~/App_Data/Users.xml" />
               </providers>
            </roleManager>
            <!-- 認証モードをフォーム認証に設定します。-->
            <authentication mode="Forms" />
         </system.web>
         <system.webServer>
            <!-- すべてのコンテンツに対する認証および役割モジュールを構成します。-->
            <modules>
               <remove name="RoleManager" />
               <remove name="DefaultAuthentication" />
               <remove name="FormsAuthentication" />
               <add name="FormsAuthentication"
                  type="System.Web.Security.FormsAuthenticationModule"
                  preCondition="" />
               <add name="DefaultAuthentication"
                  type="System.Web.Security.DefaultAuthenticationModule"
                  preCondition="" />
               <add name="RoleManager"
                  type="System.Web.Security.RoleManagerModule"
                  preCondition="" />
            </modules>
            <!-- メンバーシップ役割用の承認規則を追加します。-->
            <security>
               <authorization>
                  <clear />
                  <add accessType="Allow" roles="Administrators" />
                  <add accessType="Allow" roles="Members" />
               </authorization>
            </security>
         </system.webServer>
      </configuration>
      

      メモ: web.config の <providers> セクションの PublicKeyToken の値は、Administration.config ファイルの <trustedProviders> セクションの PublicKeyToken の値と一致している必要があります。

    • このコードを Web.config として Web サイトのルートに保存します。

まとめ

このチュートリアルでは、以下を行いました。

  • 読み取り専用 XML メンバーシップおよび役割プロバイダー用に、Visual Studio 2008 でクラス プロジェクトを 2 つ作成しました。
  • これらのプロジェクトをコンパイルし、グローバル アセンブリ キャッシュに追加しました。
  • XML メンバーシップおよび役割プロバイダーを、信頼済みプロバイダーとして IIS に追加しました。
  • XML プロバイダーを使用して、フォーム認証用サイトを構成しました。