今まで、ここらへん放置してたから、ざっくりと作ってみました。
とりあえず、ログインするユーザーの管理は、別で作ってあることが多いので、ログイン出来て、現在ログインしているユーザの情報が取れればいい!というスタンスです。
MyMembershipProvider
public class MyMembershipProvider : MembershipProvider
{
public override string ApplicationName { get; set; }
// このメソッドを実装してれば、Membership.GetUser()が動くみたい
public override MembershipUser GetUser(string username, bool userIsOnline)
{
// sessionにあれば、それを返す。
var session = HttpContext.Current.Session;
if (session != null)
{
var user = session["User"] as MembershipUser;
if (user != null)
{
return user;
}
}
// DBにアクセスするなりしてログインユーザ情報をとってくる
var user = new MembershipUser(...(略)...);
if (session != null)
{
session["User"] = user;
}
return user;
}
// こいつを実装してればLoginコントロールとかと連携してノンコーディングでログインできるみたい
public override bool ValidateUser(string username, string password)
{
// DBにアクセスするなりして認証する
}
// その他のメソッド、プロパティはNotSupportedExceptionでも投げておく
}
GetUserメソッドは、毎度毎度DBにいくのもなんなので、セッションに避難させるようなつくりにしてみた。
この方法の嫌なところは、Login画面なんかできっちり一旦セッションをクリアしてあげないと他人のユーザ情報がとれてしまうといった非常に危険なことになってしまうので要注意。
毎回ユーザ情報とりにいくくらいのDBアクセスは、発生してもたいしたことないんかなぁ。
次にRoleProviderの実装です。
MyRoleProvider
public class MyRoleProvider : RoleProvider
{
// とりあえず、こいつを実装しておけばIsInRoleとか使えるみたい
public override string[] GetRolesForUser(string username)
{
var session = HttpContext.Current.Session;
if (session != null)
{
var roles = session["Roles"] as string[];
if (roles != null)
{
return roles;
}
}
// DBにアクセスするなりしてユーザのロール情報をとってくる
var roles = new string[] { ...(略)... };
if (session != null)
{
session["Roles"] = roles;
}
return roles;
}
// 他のメソッドやプロパティはNotSupportExceptionでも投げておく
}
後は、このProviderをWeb.configに登録する。
<system.web>
<!-- MembershipProviderの登録 -->
<membership defaultProvider="MyProvider">
<providers>
<clear/>
<add name="MyProvider" type="MyMembershipProvider"/>
</providers>
</membership>
<!-- RoleProviderの登録。enabledをtrueにするのを忘れずに -->
<roleManager defaultProvider="MyProvider" enabled="true">
<providers>
<clear />
<add name="MyProvider" type="MyRoleProvider"/>
</providers>
</roleManager>
</system.web>
これで、ログインページは、Loginコントロールを置くだけで作れるようになります。
LoginViewコントロールでRoleGroupsを使ってロールに応じた表示の切り替えや、Membership.GetUser()によるユーザ情報の取得や、User.IsInRole(“ロール名”)がばっちり動くようになります。
後は、必要に応じてProviderの各メソッドを足していけばいいのかな?
ここまで動くようにするのに、えらい時間がかかってしまった・・・。ASP.NETの本を真面目に読もうかなぁ・・・。