0

IPrincipal(ASP.NET MVC 3)を実装しようとして問題が発生した場合:カスタムIPrincipal:

  interface IDealsPrincipal: IPrincipal
    {
        int UserId { get; set; }
        string Firstname { get; set; }
        string Lastname { get; set; }
    }


public class DealsPrincipal : IDealsPrincipal
    {

        public IIdentity Identity { get; private set; }
        public bool IsInRole(string role) { return false; }

        public DealsPrincipal(string email)
        {
            this.Identity = new GenericIdentity(email);
        }

        public int UserId { get; set; }
        public string Firstname { get; set; }
        public string Lastname { get; set; }

    }

シリアル化/逆シリアル化するには、次のクラスを使用します。

public class DealsPrincipalSerializeModel
    {
        public int UserId { get; set; }
        public string Firstname { get; set; }
        public string Lastname { get; set; }
    }

アプリケーション認証イベントは次のとおりです(正常に動作します!)

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
        {
            HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
            if (authCookie != null)
            {
                //get the forms ticket
                FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
                //instantiate a new Deserializer
                JavaScriptSerializer serializer = new JavaScriptSerializer();
                //deserialize the model
                DealsPrincipalSerializeModel serializeModel = serializer.Deserialize<DealsPrincipalSerializeModel>(authTicket.UserData);
                //put the values of the deserialized model into the HttpContext
                DealsPrincipal newUser = new DealsPrincipal(authTicket.Name); //this implements IPrincipal
                newUser.UserId = serializeModel.UserId;
                newUser.Firstname = serializeModel.Firstname;
                newUser.Lastname = serializeModel.Lastname;

                HttpContext.Current.User = newUser;                
            }
        }

最後のステートメントでわかるように、HttpContextにはこの新しいDealsPrincipalが割り当てられます(これは正常に機能します)。

問題は、Controller(Action)でこのユーザーにアクセスしたい場合、常に基本クラスオブジェクトを取得することです。次のようにユーザーをキャストした場合:

User as DealsPrincipal 

たとえば、UserIdを取得します(サンプル:

( User as DealsPrincipal).UserId 

これは常にnullです!!! なんで?私は何が欠けていますか?

4

1 に答える 1

0

正しい答えを得るには、さらに調査する必要がありますが、コードのこの部分を見てください。役立つ場合があります (WindowsAuthenticationModule.cs のソースの一部)。

void OnAuthenticate(WindowsAuthenticationEventArgs e) {
        //////////////////////////////////////////////////////////// 
        // If there are event handlers, invoke the handlers 
        if (_eventHandler != null)
             _eventHandler(this, e); 

        if (e.Context.User == null)
        {
            if (e.User != null) 
                e.Context.User = e.User;
            else  if (e.Identity == _anonymousIdentity) 
                e.Context.SetPrincipalNoDemand(_anonymousPrincipal, false /*needToSetNativePrincipal*/); 
            else
                e.Context.SetPrincipalNoDemand(new WindowsPrincipal(e.Identity), false /*needToSetNativePrincipal*/); 
        }
    }

このコードから、カスタム IPrincipal 実装のインスタンスを割り当てる前に、ユーザーが匿名かどうかを確認することをお勧めします。また、このメソッドが「protected void Application_AuthenticateRequest」の前または後に実行されるかどうかもわかりません。これについては、さらに時間をかけて調査します。

また、次の記事もご覧ください。

http://msdn.microsoft.com/en-us/library/ff649210.aspx

于 2012-05-12T21:21:39.770 に答える