久しぶりのラーカー初めてのポスター..
MVC の単純なカスタム ロールとメンバーシップ プロバイダーを実装しようとしています。
ロールとメンバーシップ プロバイダー クラスを実装し、web.config にフックしました。カスタムデータベースに対してユーザーを検証するコードを追加しましたが、正常に動作します。
ただし、ロールプロバイダーがリクエストごとにデータベースにヒットする方法が気に入らないため、次のように認証チケットからこれを読み取ろうとするコードを追加しました。
カスタム ロール プロバイダー:
public override string[] GetRolesForUser(string username)
{
if (HttpContext.Current.User != null)
{
return ((UserPrincipal)HttpContext.Current.User).Roles.ToArray();
}
else
{
UserPrincipal user = orchestrator.GetUserByLoginID(username);
return user.Roles.ToArray();
}
}
次に、次のコードを global.asax に追加して、カスタム ユーザー プリンシパル オブジェクトを使用して、役割やその他の有用なユーザー情報を Cookie に保持します。
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
JavaScriptSerializer serializer = new JavaScriptSerializer();
UserPrincipalModel userFromTicket = serializer.Deserialize<UserPrincipalModel>(authTicket.UserData);
UserPrincipal newUser = new UserPrincipal();
newUser.UserId = userFromTicket.UserId;
newUser.FullName = userFromTicket.Fullname;
newUser.Email = userFromTicket.Email;
newUser.Roles = userFromTicket.Roles;
newUser.Identity = new GenericIdentity(userFromTicket.Username);
HttpContext.Current.User = newUser;
}
}
私のユーザープリンシパルクラス:
public class UserPrincipal : IPrincipal
{
public UserPrincipal() { }
public UserPrincipal(int userId, string userName, string fullName, string password)
{
UserId = userId;
UserName = userName;
FullName = fullName;
Password = password;
}
public virtual int UserId { get; set; }
public virtual string UserName { get; set; }
public virtual string FullName { get; set; }
public virtual string Email { get; set; }
public virtual string Password { get; set; }
public virtual IEnumerable<string> Roles { get; set; }
public virtual IIdentity Identity { get; set; }
public virtual bool IsInRole(string role)
{
if (Roles.Contains(role))
{
return true;
}
else
{
return false;
}
}
//public string[] GetRolesForUser()
//{
// return Roles;
//}
}
ただし、これを実行すると、ロール プロバイダーが Cookie のカスタム UserPrincipal オブジェクトにアクセスしようとすると、次のエラーが発生します。
「タイプ 'System.Web.Security.RolePrincipal' のオブジェクトをタイプ 'MyApp.Domain.UserPrincipal' にキャストできません」
カスタム ロール プロバイダーが、チケットに格納されているカスタム ユーザー プリンシパルを独自のロール固有のプリンシパルで上書きしているようなものです。
私がやろうとしていることに欠陥があるのか 、それとももっと簡単な方法があるのか 疑問に思っています。車輪を再発明したくありません。
ロールのリクエストごとにデータベースにアクセスしないカスタム ロール プロバイダーの例を知っている人はいますか?