ユーザー型の作成
次に、ユーザー情報を保持するユーザー型を、IUser<out TKey>インターフェースを実装して作成します(リスト1)。今回はカスタマイズのわかりやすさを考慮し、最小限の情報を持つユーザー型ApplicationUserを作成します。
/// <summary>
/// ユーザー情報を管理します
/// </summary>
public class ApplicationUser : IUser<string>
{
/// <summary>
/// ユーザーを識別するためのキーです。
/// </summary>
public string Id { get; private set; }
/// <summary>
/// ユーザーの名前です。
/// </summary>
public string UserName { get; set; }
/// <summary>
/// ユーザーのパスワードのハッシュ値です。
/// </summary>
public string PasswordHash { get; set; }
/// <summary>
/// Id を使用して ApplicationUser クラスの新しいインスタンスを生成します。
/// </summary>
/// <param name="id"></param>
public ApplicationUser(string id)
{
this.Id = id;
}
}
今回のサンプルではIUserインターフェースの型引数にstring型を指定することで、ユーザーのIDの型を文字列型にしています。
ユーザー管理用クラスの作成
今度はユーザー情報を扱うための処理を行うクラス群を作成していきます。
ユーザー情報の出し入れを行うApplicationUserStore型
データストアを使いユーザー情報の出し入れを行うための型であるApplicationUserStore型を、IUserStore<TUser>、IUserPasswordStore<TUser>インターフェースを実装して作成します(リスト2)。
/// <summary>
/// ユーザーの管理用APIを提供します。
/// </summary>
public class ApplicationUserStore :
IUserStore<ApplicationUser>, // (1)
IUserPasswordStore<ApplicationUser> // (2)
{
...
/// <summary>
/// ユーザー名を使いユーザーを検索します。
/// </summary>
/// <param name="userName">ユーザー名。</param>
/// <returns>見つかったユーザー情報。見つからない場合はnullを返す。</returns>
public Task<ApplicationUser> FindByNameAsync(string userName) // (3)
{
// ここで外部サービス等からユーザー情報を取得する
var hasher = new PasswordHasher();
var user = new ApplicationUser(Guid.NewGuid().ToString())
{
UserName = userName,
PasswordHash = hasher.HashPassword("123456")
};
return Task.FromResult(user);
}
...
public void Dispose() // (4)
{
}
...
/// <summary>
/// ユーザーのハッシュ処理されたパスワードを取得します。
/// </summary>
/// <param name="user">ユーザー情報。</param>
/// <returns>ユーザーのハッシュ処理されたパスワード。</returns>
public Task<string> GetPasswordHashAsync(ApplicationUser user) // (5)
{
return Task.FromResult(user.PasswordHash);
}
...
}
(1)IUserStore<ApllicationUser>インターフェースの実装
ApplicationUser型のユーザー情報を扱うメソッド群(API)を提供するIUserStoreインターフェースを実装します。
(2)IUserPasswordStore<ApplicationUser>インターフェースの実装
ユーザーのパスワードを扱うAPIを提供するIUserPasswordStoreインターフェースを実装します。
(3)ユーザー情報取得メソッド実装
ユーザー名からユーザー情報を取得するためのIUserStore<TUser>.FindByNameAsync非同期メソッドを実装します。今回は認証処理の流れが分かればよいので、新たなユーザー情報をパスワード"123456"として作成して返します。なお、非同期メソッドなので、戻り値がTask<T>型であることに注意します。
(4)Disposeメソッド実装
ApplicationUserStore型は外部のデータストアとやり取りすることが前提なので、必要ならDisposeメソッドを実装してアンマネージオブジェクトの破棄を行います。今回は空のままとしています。
(5)パスワードハッシュ値取得メソッド実装
ユーザー情報のパスワードのハッシュ値を取得するためのIUserPasswordStore.GetPasswordHashAsyncm非同期メソッドを実装します。今回は簡単にするため、引数のApplicationUserオブジェクトより、PasswordHashプロパティを非同期に返します。
IUserStore<TUser>、IUserPasswordStore<TUser>インターフェースには上記以外にも多くのメソッドが用意されていますが、今回の範囲では使用しないので、次のようにNotImplementedExceptionをスローするようにしておきます(リスト3)。
public Task CreateAsync(ApplicationUser user)
{
throw new NotImplementedException();
}
ユーザー管理処理を指示するApplicationUserManagerクラス
ApplicationUserStoreクラスを使い、実際にユーザー管理処理の指示を行うApplicationUserManagerクラスを作成します(リスト4)。
/// <summary>
/// UserStoreを使ったユーザー情報管理を自動化したAPIを提供します。
/// </summary>
public class ApplicationUserManager : UserManager<ApplicationUser> // (1)
{
/// <summary>
/// UserStoreを使用して ApplicationUserManager クラスの新しいインスタンスを生成します。
/// </summary>
/// <param name="store"></param>
public ApplicationUserManager(IUserStore<ApplicationUser> store)
: base(store)
{
}
/// <summary>
/// ApplicationUserManager クラスのインスタンスを作成します。
/// </summary>
/// <param name="options"></param>
/// <param name="context"></param>
/// <returns></returns>
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var manager = new ApplicationUserManager(new ApplicationUserStore()); // (2)
return manager;
}
}
(1)UserManager<TUser>クラスを継承する
UserStoreクラスを使った各種処理を行うため、UserManager<TUser>クラスを継承して定義します。
(2)UserManagerクラスのインスタンスを作成する
引数にApplicatonUserStoreオブジェクトを渡して、新しいApplicationUserManagerクラスのインスタンスを作成します。
