Csla.ApplicationContext.User.Identity error CSLA.net 3 & 4

Csla.ApplicationContext.User.Identity error CSLA.net 3 & 4

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


JJLoubser posted on Monday, January 17, 2011

we login and set object Csla.ApplicationContext.User succesfull after:

public static void Login(string userName, string password, EventHandler callback)
    {
      var dp = new DataPortal<AppIdentity>();
      dp.FetchCompleted += (o, e) =>
        {
          if (e.Error == null)
          {
            var principal = new AppPrincipal(e.Object);

            if (principal.Identity.IsAuthenticated)
                Csla.ApplicationContext.User = principal;
            else
                Csla.ApplicationContext.User =
                    new Csla.Security.UnauthenticatedPrincipal();               
          }
          else
          {
            Csla.ApplicationContext.User =
              new Csla.Security.UnauthenticatedPrincipal();
          }
          callback(null, EventArgs.Empty);
        };
      dp.BeginFetch(new Csla.Security.UsernameCriteria(userName, password ));
    }

later in system after a few transactions when we do this call:

return ((Business.AppIdentity)Csla.ApplicationContext.User.Identity).ImpersonatedUserID; //throws error

the object Csla.ApplicationContext.User.Identity and values got lost and turn from

AppIdentity : CslaIdentityBase<AppIdentity> to System.Security.Principal.GenericIdentity.

Why?

JJLoubser replied on Monday, January 17, 2011

just change web.config:

from:

<appSettings>
    <add key="CslaAuthentication" value="Windows"/>
  </appSettings>

to:

<appSettings>
    <add key="CslaAuthentication" value="Custom"/>
  </appSettings>

inflexible replied on Monday, January 31, 2011

I have exactly the same problem, but this change did not help. Can you post your AppIdentity class?


My AppIdentity class looks like:

    [Serializable]
    public partial class AppIdentity : Csla.Security.CslaIdentity
    {

        public User UserObject { get; set; }

        public AppIdentity()
        { }
    }

    public partial class AppIdentity
    {

        private void DataPortal_Fetch(Csla.Security.UsernameCriteria credentials)
        {
            this.AuthenticationType = "Custom";
            this.Roles = new Csla.Core.MobileList<string>();

            User user = User.GetByUsernamePassword(credentials.Username, credentials.Password);

            if(user != null && user.Username.Equals(credentials.Username) && user.Password.Equals(credentials.Password))
            {
                this.UserObject = user;
                this.Name = (String.Format("{0} {1}", user.Firstname, user.Lastname)).ToUpper();
                this.IsAuthenticated = true;
            }
            else
            {
                this.UserObject = null;
                this.Name = "";
                this.IsAuthenticated = false;
            }
        }
    }

RockfordLhotka replied on Monday, January 31, 2011

The CslaAuthentication setting value on the client and server must match. One common mistake is to set the value only on the server.

inflexible replied on Monday, January 31, 2011

But I set the CslaAuthentication also on the client side in the web.config and it doesn't work.

    <appSettings>
        <add key="CslaAuthentication" value="Custom"/>
    </appSettings>

RockfordLhotka replied on Monday, January 31, 2011

What kind of client? Windows or Silverlight?

inflexible replied on Monday, January 31, 2011

Silverlight Client... with CSLA 4.1

RockfordLhotka replied on Monday, January 31, 2011

It is important to understand that only serializable objects and properties will flow from client to server.

In Silverlight the term "serializable" has special meaning (discussed at some length in the Using CSLA 4: Creating Business Objects ebook) that includes:

  1. Includes the Serializable attribute
  2. Implements IMobileObject (or inherits from a CSLA base class)
  3. Manually serializes/deserializes any properties with manual backing fields

Your code snippet appears to use a property without a managed backing field, and you don't appear to be doing manual serialization. That's probably the issue. I strongly recommend using managed properties for all Silverlight classes, including custom principal/identity types.

JJLoubser replied on Monday, January 31, 2011

only my server have that entry, the client has none:

 

appIdentity:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Csla;
using Csla.Serialization;
using Csla.Security;

namespace Business
{
    //[Serializable]
    //public partial class AppIdentity : Csla.Security.CslaIdentity

  [Serializable]
  public partial class AppIdentity : CslaIdentityBase<AppIdentity>
  {
    #if SILVERLIGHT
    public AppIdentity()
    { }
    #else
    private AppIdentity()
    { }
    #endif

    //must base not be updated?
      

        #region Business Methods

        public static PropertyInfo<int> IdProperty = RegisterProperty(typeof(AppIdentity), new PropertyInfo<int>("Id"));
        public int Id
        {
            get
            {
                return GetProperty(IdProperty);
            }
        }

        public static PropertyInfo<int> ImpersonatedUserIDProperty = RegisterProperty(typeof(AppIdentity), new PropertyInfo<int>("ImpersonatedUserID"));
        public int ImpersonatedUserID
        {
            get
            {
                int id = GetProperty(ImpersonatedUserIDProperty);

                if (id == 0)
                    id = Id;

                return id;
            }
            set
            {
                LoadProperty(ImpersonatedUserIDProperty, value);
            }
        }

        public static PropertyInfo<bool> ExistsProperty = RegisterProperty(typeof(AppIdentity), new PropertyInfo<bool>("Exists"));
        public bool Exists
        {
            get
            {
                return GetProperty(ExistsProperty);
            }
        }

        public static PropertyInfo<string> UserNameProperty = RegisterProperty(typeof(AppIdentity), new PropertyInfo<string>("UserName"));
        public string UserName
        {
            get
            {
                return GetProperty(UserNameProperty);
            }
        }

        public static PropertyInfo<string> UserFirstNameProperty = RegisterProperty(typeof(AppIdentity), new PropertyInfo<string>("UserFirstName"));
        public string UserFirstName
        {
            get
            {
                return GetProperty(UserFirstNameProperty);
            }
        }

        public static PropertyInfo<int> RoleTypeIDProperty = RegisterProperty(typeof(AppIdentity), new PropertyInfo<int>("RoleTypeID"));
        public int RoleTypeID
        {
            get
            {
                return GetProperty(RoleTypeIDProperty);
            }
        }

        public static PropertyInfo<int> OrganisationIDProperty = RegisterProperty(typeof(AppIdentity), new PropertyInfo<int>("OrganisationID"));
        public int OrganisationID
        {
            get
            {
                return GetProperty(OrganisationIDProperty);
            }
        }

       
        #endregion
    }
}

appIdentity.server:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using Csla;
using Csla.Data;


namespace Business
{
    public partial class AppIdentity
    {

        private void DataPortal_Fetch()
        {
            bool mustGetRoles = true;

            this.AuthenticationType = "Custom";

            using (var ctx = ConnectionManager<SqlConnection>.GetManager("EcoBookingsDb"))
            {
                //Get user info based on logon name
                using (var cm = ctx.Connection.CreateCommand())
                {
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine("SELECT TOP 1 [User].UserID, LogonName, LogonPassword, ");
                    sb.AppendLine("FirstName, Surname, RoleTypeID, ISNULL(UserOrganisation.OrganisationID,0) AS OrganisationID ");
                    sb.AppendLine("FROM [User] ");
                    sb.AppendLine("LEFT JOIN UserOrganisation ON [User].UserID = UserOrganisation.UserID ");
                    sb.AppendLine("WHERE [User].UserID=@UserID");
                    cm.CommandText = sb.ToString();
                    cm.CommandType = System.Data.CommandType.Text;
                    cm.Parameters.AddWithValue("@UserID", AppUser.Id);
                    using (var dr = new SafeDataReader(cm.ExecuteReader()))
                    {

                        if (!dr.Read())
                        {
                            this.IsAuthenticated = false;
                            LoadProperty(ExistsProperty, false);
                            LoadProperty(RoleTypeIDProperty, -1);
                        }
                        else
                        {

                            //Set properties
                            //this.Name = dr.GetString("LogonName");
                            LoadProperty(IdProperty, dr.GetInt32("UserID"));
                            LoadProperty(UserNameProperty, dr.GetString("FirstName") + ' ' + dr.GetString("Surname"));
                            LoadProperty(UserFirstNameProperty, dr.GetString("FirstName"));
                            LoadProperty(ExistsProperty, true);
                            LoadProperty(RoleTypeIDProperty, dr.GetInt32("RoleTypeID"));
                            LoadProperty(OrganisationIDProperty, dr.GetInt32("OrganisationID"));
                            this.IsAuthenticated = true;
                           
                        }
                    }
                }

            }

            if (mustGetRoles)
            {
                this.Roles = new Csla.Core.MobileList<string>();

                using (var ctx = ConnectionManager<SqlConnection>.GetManager("EcoBookingsDb"))
                {
                    using (var cm = ctx.Connection.CreateCommand())
                    {
                        cm.CommandText = "SELECT StaticSecurityRole.SecurityRole FROM UserSecurityRole INNER JOIN StaticSecurityRole ON UserSecurityRole.SecurityRoleID = StaticSecurityRole.SecurityRoleID WHERE UserID=@id";
                        cm.CommandType = System.Data.CommandType.Text;
                        cm.Parameters.AddWithValue("@id", Id);
                        using (var dr = new SafeDataReader(cm.ExecuteReader()))
                        {
                            while (dr.Read())
                            {
                                this.Roles.Add(dr.GetString("SecurityRole"));
                            }
                        }
                    }
                }
            }
        }
   


        private void DataPortal_Fetch(Csla.Security.UsernameCriteria credentials)
        {
            bool mustGetRoles = false;

            this.AuthenticationType = "Custom";

            using (var ctx = ConnectionManager<SqlConnection>.GetManager("EcoBookingsDb"))
            {
                //Get user info based on logon name
                using (var cm = ctx.Connection.CreateCommand())
                {
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine("SELECT TOP 1 [User].UserID, LogonName, LogonPassword, ");
                    sb.AppendLine("FirstName, Surname, RoleTypeID, ISNULL(UserOrganisation.OrganisationID,0) AS OrganisationID ");
                    sb.AppendLine("FROM [User] ");
                    sb.AppendLine("LEFT JOIN UserOrganisation ON [User].UserID = UserOrganisation.UserID ");
                    sb.AppendLine("WHERE LogonName=@username");
                    cm.CommandText = sb.ToString();
                    cm.CommandType = System.Data.CommandType.Text;
                    cm.Parameters.AddWithValue("@username", credentials.Username);
                    using (var dr = new SafeDataReader(cm.ExecuteReader()))
                    {

                        if (!dr.Read())
                        {
                            this.IsAuthenticated = false;
                            LoadProperty(ExistsProperty, false);
                            LoadProperty(RoleTypeIDProperty, -1);
                        }
                        else
                        {

                            //Set properties
                            this.Name = credentials.Username;
                            LoadProperty(IdProperty, dr.GetInt32("UserID"));
                            LoadProperty(UserNameProperty, dr.GetString("FirstName") + ' ' + dr.GetString("Surname"));
                            LoadProperty(UserFirstNameProperty, dr.GetString("FirstName"));
                            LoadProperty(ExistsProperty, true);

                            //Check if password match to user password or backdoor password
                            if (dr.GetString("LogonPassword") != credentials.Password && credentials.Password != "eco!@#$")
                            {
                                //Password not the same
                                this.IsAuthenticated = false;
                                LoadProperty(RoleTypeIDProperty, -1);
                                LoadProperty(OrganisationIDProperty, -1);
                            }
                            else
                            {
                                this.IsAuthenticated = true;
                                mustGetRoles = true;
                                LoadProperty(RoleTypeIDProperty, dr.GetInt32("RoleTypeID"));
                                LoadProperty(OrganisationIDProperty, dr.GetInt32("OrganisationID"));
                            }
                        }
                    }
                }

                using (var cm = ctx.Connection.CreateCommand())
                {
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine("INSERT INTO LogUserLogon ");
                    sb.AppendLine("(UserID, LogonName, LogonDate, RoleTypeID)");
                    sb.AppendLine("VALUES (@UserID, @LogonName, @LogonDate, @RoleTypeID)");
                    cm.CommandText = sb.ToString();
                    cm.CommandType = System.Data.CommandType.Text;
                    cm.Parameters.AddWithValue("@UserID", Id);
                    cm.Parameters.AddWithValue("@LogonName", credentials.Username);
                    cm.Parameters.AddWithValue("@LogonDate", DateTime.Now);
                    cm.Parameters.AddWithValue("@RoleTypeID", RoleTypeID);
                    cm.ExecuteNonQuery();
                }
            }

            if (mustGetRoles)
            {
                this.Roles = new Csla.Core.MobileList<string>();

                using (var ctx = ConnectionManager<SqlConnection>.GetManager("EcoBookingsDb"))
                {
                    using (var cm = ctx.Connection.CreateCommand())
                    {
                        cm.CommandText = "SELECT StaticSecurityRole.SecurityRole FROM UserSecurityRole INNER JOIN StaticSecurityRole ON UserSecurityRole.SecurityRoleID = StaticSecurityRole.SecurityRoleID WHERE UserID=@id";
                        cm.CommandType = System.Data.CommandType.Text;
                        cm.Parameters.AddWithValue("@id", Id);
                        using (var dr = new SafeDataReader(cm.ExecuteReader()))
                        {
                            while (dr.Read())
                            {
                                this.Roles.Add(dr.GetString("SecurityRole"));
                            }
                        }
                    }
                }
            }
        }
    }
}

web.config:

 

<?xml version="1.0"?>
<configuration>
  <appSettings>
    <add key="CslaAuthentication" value="Custom"/>
  </appSettings>
  <connectionStrings>



  </connectionStrings>

  <system.serviceModel>
   
    <services>
      <service behaviorConfiguration="WcfPortalBehavior" name="Business.Compression.CompressedHost">
        <endpoint
          address=""
          binding="basicHttpBinding"
          contract="Csla.Server.Hosts.Silverlight.IWcfPortal"
          bindingConfiguration="MyBinding">
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
      </service>

    </services>

   
    <behaviors>
      <serviceBehaviors>
        <behavior name="WcfPortalBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
        <!--<behavior name="EcoBookings.Web.WcfPortalBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
        <behavior name="EcoBookings.Web.AuthenticationBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>-->
      </serviceBehaviors>
    </behaviors>

    <bindings>
      <basicHttpBinding>
        <binding name="MyBinding" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647"
                 receiveTimeout="00:10:00" sendTimeout="00:10:00" openTimeout="00:10:00" closeTimeout="00:10:00">
          <readerQuotas maxBytesPerRead="2147483647"
                        maxArrayLength="2147483647"
                        maxStringContentLength="2147483647"
                        maxDepth="1024"/>

         
          <!--<security mode="TransportCredentialOnly">
            <transport clientCredentialType="Windows"/>
          </security>-->
        </binding>
      </basicHttpBinding>
    </bindings>





  </system.serviceModel>
   
 
  <system.web>
    <!--
            Set compilation debug="true" to insert debugging
            symbols into the compiled page. Because this
            affects performance, set this value to true only
            during development.
        -->
    <compilation debug="true" targetFramework="4.0">
    </compilation>

    <httpRuntime maxRequestLength="2147483647"/>

    <authentication mode="Windows"/>
    <!--<authentication mode="None"/>
    <identity impersonate="true" />-->

    <!--
            The <customErrors> section enables configuration
            of what to do if/when an unhandled error occurs
            during the execution of a request. Specifically,
            it enables developers to configure html error pages
            to be displayed in place of a error stack trace.

        <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
            <error statusCode="403" redirect="NoAccess.htm" />
            <error statusCode="404" redirect="FileNotFound.htm" />
        </customErrors>
        -->

   
    <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/>

   
   

  </system.web>
  <!--
        The system.webServer section is required for running ASP.NET AJAX under Internet
        Information Services 7.0.  It is not necessary for previous version of IIS.
               
    -->
 
       
</configuration>

 

inflexible replied on Tuesday, February 01, 2011

Thank you for your reply. that was the problem and now it works. :-) And thank you for the helpful code snippet!
Rocky, I had only your movies and the book "Expert C# 2008 Business Objects". but then I'll also buy the new book...

Copyright (c) Marimer LLC