Custom Principal problem with EntLib DAAB

Custom Principal problem with EntLib DAAB

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


PaulB posted on Thursday, December 07, 2006

When I call myPrincipal.Logout, then myPrincipal.Login(...) I get
System.Runtime.Serialization.SerializationException: Type is not resolved for member 'myPrincipal,myAssem, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

If I don't call Logout first, it works fine.

I am using the EntLib Data Access Block to access my database to get the custom roles. The connection string contains the User and Password. When the the DatabaseFactory.CreateDatabase(...) call is made, I get the exception.

I believe this has to do with the custom principal and the DAAB trying to login with Integrated Security, but am not sure.

Does anyone have any suggestions as to how to resolve this, or know if it is a problem if I don't call Logout first?

Thanks,
Paul


RockfordLhotka replied on Thursday, December 07, 2006

Something in your code is causing the thread to marshal from one AppDomain to another - or something along that line - and the other AppDomain doesn't have access to the directory containing your assemblies.

This happens all the time with nunit, and with Cassini - the ASP.NET Web Development server.

I'll venture to guess that you are using Cassini for debugging, and are getting bit by the fact that it doesn't work the same as IIS - and really doesn't work with referenced assemblies worth a darn...

PaulB replied on Thursday, December 07, 2006

I read a lot of posts about Cassini and Nunit, but still couldn't get it to work.
I am not doing any remoting yet, just running local. I am trying to run in VS using Nunit and ReSharper to execute the tests.

When this goes to production it will be multi-tier with a WinForms app and an application server, so there will be remoting, most likely hosting in IIS. I am concerned that when it is in that environment that it will be a problem.

The goal is to have a version that will have several authentication fall back scenarios.
First I would like to use Windows authentication so I can just pick up the users windows identity and have it authenticate. It sounds like the way to do that is to setup IIS to use windows authentication. The problem we have right now is our domains/ active directory is not built out correctly so the user may not be in the valid when they hit the IIS server.
Fallback scenarios: Ask the user for credentials, Call Principal Login which will then try AD authentication on the application server, if that fails it the falls back to authenticating against SQL Server with SQL login.

If authentication is successful then always get role from the application database using a  application SQL login.

It appears that the DAAB is causing one more complication by trying to use windows (trusted) authentication when connecting to the database the first time.

If you think that the inital problem is with ReSharper/Nunit and have a workaround please let me know.
If you have any feedback on the whole fall back authentication scheme, I would love to hear that too.

Thanks,
Paul

RockfordLhotka replied on Thursday, December 07, 2006

You need to understand the nature of the issue you are seeing.
 
You are getting a serializion exception - which is really a DEserialization exception. During deserialization of your principal object, the .NET runtime is unable to locate your assembly.
 
The reason this happens is because your thread of execution has been transferred from one AppDomain to another. The first AppDomain is running on top of your "bin" directory where all your assemblies are located, so .NET can find your assemblies. The second AppDomain is running on top of some OTHER directory, which does not include your assemblies. Due to this, the .NET runtime can't locate your assemblies - and thus can't create an instance of your custom principal object to deserialize the object.
 
I very much doubt the DAAB is creating AppDomain objects and transferring control from one AppDomain to another - that just doesn't make sense.
 
However, both nunit and Cassini do exactly that. Other runtime environments might do that as well.
 
The only solution I'm aware of is to ensure that the System.Threading.Thread.CurrentPrincipal is null/Nothing (or a GenericPrincpal or a WindowsPrincipal) BEFORE that AppDomain switch occurs.
 
In the case of nunit testing this means that you MUST reset this value before returning from a test method - because that's the point at which the thread of execution leaves the test AppDomain and returns to the host nunit AppDomain (which is, of course, running from the nunit directory, not your test directory).
 
Rocky
 

Copyright (c) Marimer LLC