Csla.Web.IdentityFactory weakness?

Csla.Web.IdentityFactory weakness?

Old forum URL: forums.lhotka.net/forums/t/9857.aspx


swegele posted on Saturday, December 11, 2010

Csla.Web.IdentityFactory has the following:

 

    public void LoadIdentity(MembershipIdentity.Criteria criteria, MembershipIdentity identity)

    {

      LoadProperty(identity, MembershipIdentity.AuthenticationTypeProperty, "Membership");

      if (Membership.ValidateUser(criteria.Name, criteria.Password))

      {

...

       identity.LoadCustomData();

 

 

I was so thankful to find I could override "LoadCustomData()"...this is similar to having an OnAfterValidateUser right?  What I need is a virtual "OnBeforeValidateUser" which allows me to call the Membership.GetUser(username) BEFORE the login attempt so that I can grab the lastlogindatetime property.  That property value will show the last time they logged in BEFORE this attempt which is what I want.  Otherwise the value only shows that I just logged in which is useless to me!

As a hack, I wrote a command object to do this and called it in the Principal.Login method.  This works but consider the following problem in silverlight or async implementation:

 

public static void Login(string userName, string password, EventHandler<DataPortalResult<IRBIdentity>> handler)

        {

            IRBPrincipal.SignalLogin = handler;

 

            //first do prelogin stuff

            DataPortal<PreloginCheckAndInfoCommand> dp = new DataPortal<PreloginCheckAndInfoCommand>();

            PreloginCheckAndInfoCommand cmd = new PreloginCheckAndInfoCommand();

            cmd.Username = userName;

 

            dp.ExecuteCompleted += (o, e) =>

            {

                if (e.Object != null && e.Error == null)

                {

                    Csla.ApplicationContext.LocalContext.Add("PreviousLoginDateTime", cmd.PreviousLoginDateTime);

                    MembershipIdentity.GetMembershipIdentity<IRBIdentity>(HandleLogin, userName, password, true);

                }

                else

                {

                    Csla.ApplicationContext.User = new UnauthenticatedPrincipal();

 

                    if (SignalLogin != null)

                        SignalLogin.Invoke(o, new DataPortalResult<IRBIdentity>(null, e.Error, e.UserState));

                }

            };

 

            dp.BeginExecute(cmd);

        }

 

 

Not only do we have two async calls which is 2 trips across the wire...but we have the clunky implementation of having to new up a DataPortalResult<IIdentity> if the first one fails so the original caller gets notified in the way they expect.  YUCK.

Sean

 

 

 

 

RockfordLhotka replied on Saturday, December 11, 2010

That is good feedback and I'll add it to the wish list.

In the meantime, the workaround is probably to just copy the code and create your own factory object. Nothing forces you to use the one provided by CSLA - it is primarily there as a convenience.

Copyright (c) Marimer LLC