How does Csla.ApplicationContext.User work?

How does Csla.ApplicationContext.User work?

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


SMILEMan posted on Monday, January 06, 2014

I'm testing my application that has a BusinessIdentity based on CslaIdentityBase<BusinessIdentity> using direct database connections (i.e. using connection strings in the config or development testing).

After I do the logon, Csla.ApplicationContext.User.Identity returns a BusinessIdentity, but in my Data Access project (I'm using the Encapsulated Invocation model), Csla.ApplicationContext.User.Identity returns a System.Security.Principal.GenericIdentity and the cast to a BusinessIdentity fails with an InvalidCastException.

I've noticed some discussions that Csla.ApplicationContext has changed during the 4.x development but didn't see a comprehensive discussion on how this works.

Ray.

RockfordLhotka replied on Monday, January 06, 2014

The default behavior of the User property varies depending on the client UI technology you are using (ASP.NET, WPF, etc.)  - which are you using?

SMILEMan replied on Monday, January 06, 2014

I'm using WPF for the client.

Ray Klaassen

JonnyBee replied on Tuesday, January 07, 2014

You must make sure to have Csla.Xaml,dll in your references (and bin folder) of the application anmd Csla.Web must NOT be present..

Csl.ApplicationContext uses a ApplicationContextManager and will use the ApplicationContextManager from Csla.Xaml when present.

public static IPrincipal User
    {
      get { return ContextManager.GetUser(); }
      set { ContextManager.SetUser(value); }
    }

So the Csla.Xaml assembly has its own implementation of ApplicationContextManager:

    private static IPrincipal _principal;
    /// <summary>
    /// Gets the current principal.
    /// </summary>
    /// <returns></returns>
    public IPrincipal GetUser()
    {
      IPrincipal current;
      if (System.Windows.Application.Current != null)
      {
        if (_principal == null)
        {
          if (ApplicationContext.AuthenticationType != "Windows")
            _principal = new Csla.Security.UnauthenticatedPrincipal();
          else
            _principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
        }
        current = _principal;
      }
      else
        current = Thread.CurrentPrincipal;
      return current;
    }

    /// <summary>
    /// Sets the current principal.
    /// </summary>
    /// <param name="principal">Principal object.</param>
    public void SetUser(IPrincipal principal)
    {
      if (System.Windows.Application.Current != null)
        _principal = principal;
      Thread.CurrentPrincipal = principal;
    }

 

SMILEMan replied on Tuesday, January 07, 2014

Thank you.

Does anything need to change if I want to deploy the WPF application with data access using a WCF DataPortal hosted by IIS rather than direct connections?

RockfordLhotka replied on Tuesday, January 07, 2014

Ray, have you read through the "CSLA 4: Data Portal Configuration" book? It covers a lot of these things (I hope) pretty well.

There are client and server configuration settings that control how (and if) the data portal tries to flow the client-side principal to the server, and those do matter as soon as you use a 3-tier deployment model.

Copyright (c) Marimer LLC