Difficulties using WcfPortal in Beta 1

Difficulties using WcfPortal in Beta 1

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


dlutz52 posted on Tuesday, May 22, 2007

Good day to all!

   I am using Beta 1 (and the previous test version) of CSLA 3.0 to grok the WcfPortal. I got Project Tracker working with the WcfPortal without any trouble. Great!

   When I went to use this same CSLA functionality with my own business objects, I ran into a problem I have not been able to resolve. I added a reference to my business objects to the WcfPortal project and had my client access this portal via app.config. These business objects work fine when using the SimpleDataPortal.

    When I call the Save(false) method on my ERO, I get an exception stating: "The underlying connection was closed: The connection was closed unexpectedly."

    These business objects work fine when using the SimpleDataPortal within the same test app that I am using here.

    When I turn logging on for the WcfPortal, I find the following in the log file after running my test:

"<ExceptionString>System.ServiceModel.CommunicationException: There was an error while trying to serialize parameter http://ws.lhotka.net/WcfDataPortal:UpdateResult. The InnerException message was 'Enum value '0' is invalid for type 'System.Security.Permissions.SecurityAction' and cannot be serialized. Ensure that the necessary enum values are present and are marked with EnumMemberAttribute attribute if the type has DataContractAttribute attribute.'.  Please see InnerException for more details. System.Runtime.Serialization.SerializationException: Enum value '0' is invalid for type 'System.Security.Permissions.SecurityAction' and cannot be serialized. Ensure that the necessary enum values are present and are marked with EnumMemberAttribute attribute if the type has DataContractAttribute attribute."

     I have looked at everything that I can think of to see any difference between my business objects (which are generated with a code generator) and the ProjectTracker business objects. I have yet to find anything that lead to a solution to this problem. Since the ProjectTracker objects work fine with WcfPortal, it must be something with the business object code that I am using, but what...? So any help here would be much appreciated.

     I have tried to be brief here. If you need more info, just ask...

    BTW, are there any specific instructions somewhere for setting up a WCF project in VS2005 for use as a WcfPortal for CSLA objects? I would imagine that it would be pretty much the same as the instructions for remoting on pg. 611 of the VB 2005 Business Objects book. I have also checked out http://www.lhotka.net/files/csla20/BuildCsla.pdf but it appears to be just CSLA 2.0. But I wonder if there is just something that I am missing here.

Best regards--
David Lutz

RockfordLhotka replied on Tuesday, May 22, 2007

I recommend trying one of the 2.0 channels (remoting, web services, etc) to see what happens. If you problem continues to exist with that channel then we eliminate WCF. If your code works with that channel then that indicates the problem almost certainly must be with the WCF channel.

dlutz52 replied on Wednesday, May 23, 2007

I can confirm that the BOs work fine with remoting. After adding a reference to my BOs in your remoting server, making the necessary config changes and working out the security principal, I was able to get my test app to create and save the business objects to the database using the remoting server.

One other thing I discovered after writing the first post: once a reference these business objects were added to your WcfHost project, not even ProjectTracker would work. A similarly worded error happened when trying to retrieve a project. Once the references were removed, ProjectTracker worked fine.

Best regards --
David Lutz

dlutz52 replied on Wednesday, May 23, 2007

I can now add some additional info to this thread:

Once the BusinessPrincipal was implemented in my test app, the remoting test worked. However, I had to hack the class implementing the IIdentity interface to get around and error that returned: "Principal must be of type BusinessPrincipal, not System.Security.Principal.GenericPrincipal" when calling the GetIdentity method which called DataPortal.Fetch. ProjectTracker does not have this problem and calls the remoting server even though a BusinessPrincipal has not been created. I would someday like to understand this better, but for now I just hacked my way around this problem.

My hack was to create a constructor that took a name and set IsAuthenicated to True. So now I call this constructor and use the result to set the Csla.ApplicationContext.User. Once this is done the saving of these objects via the remoting server works. The same applies to the WCF Host.

I hope this provides some clarification to this ongoing situation.

Best regards --
David Lutz

RockfordLhotka replied on Wednesday, May 23, 2007

dlutz52:

My hack was to create a constructor that took a name and set IsAuthenicated to True. So now I call this constructor and use the result to set the Csla.ApplicationContext.User. Once this is done the saving of these objects via the remoting server works. The same applies to the WCF Host.

This is close to what you should do, but not quite. You need to implement a static/Shared Logout() method on your principal, that sets the current principal to an unauthenticated instance of your custom principal.

This is discussed in the book, and you'll notice that all three interfaces in ProjectTracker make sure to do a Logout() before any attempt at calling the data portal.

RockfordLhotka replied on Wednesday, May 23, 2007

But in any case, this is a valuable clue to what's going on with the WcfProxy. I think that at least one server-side exception class (probably a WCF one) isn't serializable. I'll have to dig into that a bit - because what I think is happening is that an exception occurs on the server, and my code tries to pack up the server-side stack trace to return it to the client. That requires serializing the exception stack, and that appears to be what's failing.

dlutz52 replied on Wednesday, May 23, 2007

Rocky/Andres --

Calling the Logout() method fixed everything - for both remoting and WCF. Lesson learned. Funny how you can read something in a book and not grok the full significance of what one has read, later yet remember it when you need it.

I thank you both for the help. I hope that this exercise has been helpful in spite of the fact that it arises out of the actions of a fumbling newbie - a fact that will change with time.

Best regards --
David

xal replied on Wednesday, May 23, 2007

Whenever you're using Remoting, you're supposed to have an appropriate principal, not necessarily logged in (IsAuthenticated = True).
If you look at the project tracker, it calls Logout() somewhere before even attempting to login. Calling logout sets an unauthenticated principal as the current principal and that lets you communicate with the remoting portal.

I don't know if this is related in any way to wcf, but for remoting, that's the solution to your problem.

Andrés

RockfordLhotka replied on Friday, June 01, 2007

dlutz52:

"<ExceptionString>System.ServiceModel.CommunicationException: There was an error while trying to serialize parameter http://ws.lhotka.net/WcfDataPortal:UpdateResult. The InnerException message was 'Enum value '0' is invalid for type 'System.Security.Permissions.SecurityAction' and cannot be serialized. Ensure that the necessary enum values are present and are marked with EnumMemberAttribute attribute if the type has DataContractAttribute attribute.'.  Please see InnerException for more details. System.Runtime.Serialization.SerializationException: Enum value '0' is invalid for type 'System.Security.Permissions.SecurityAction' and cannot be serialized. Ensure that the necessary enum values are present and are marked with EnumMemberAttribute attribute if the type has DataContractAttribute attribute."

OK, I have isolated this issue. It appears to be a bug in the NetDataContractSerializer (the WCF replacement for the BinaryFormatter). As such, it is not at all clear to me that there's a fix or workaround short of Microsoft addressing the problem.

http://www.lhotka.net/weblog/WCFNetDataContractSerializerAndSecurityException.aspx

I haven't quite given up on a workaround yet, but it is hard to see any good solution I can provide...

dlabar replied on Sunday, July 27, 2008

Rocky, have you found any solution to this issue?  I'm having the same problem, but only with certain BO, and only in our production environment, and only if trying to remote from a non-development machine.  Any ideas?

 

http://forums.lhotka.net/forums/24987/ShowThread.aspx#24987

 

 

RockfordLhotka replied on Sunday, July 27, 2008

Yes, this was fixed in some point release (3.0.x) - it turns out that extra initialization of the SecurityException is required for it to serialize safely through the NDCS. So the issue should be resolved, unless one of the following is true:

  1. You throw your own SecurityException and don't initialize it fully
  2. Some other code throws a SecurityException and doesn't initialize it fully
  3. I missed a spot in CSLA where I throw a SecurityException and don't initialize it fully

 

dlabar replied on Sunday, July 27, 2008

I'm running version 3.0.3, should I try upgrading to 3.5.0?  I guess I could be throwing a security Exception myself (option number 1).  What is required to "fully initialize" it?

RockfordLhotka replied on Sunday, July 27, 2008

I honestly don’t remember – it was months ago I researched this :(

 

Some extra property needs to be set manually on the object if I remember right.

 

I just looked at the CSLA code – it is the Action property that must be explicitly set after the SecurityException object has been created.

 

Rocky

 

From: dlabar [mailto:cslanet@lhotka.net]
Sent: Sunday, July 27, 2008 1:35 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Difficulties using WcfPortal in Beta 1

 

I'm running version 3.0.3, should I try upgrading to 3.5.0?  I guess I could be throwing a security Exception myself (option number 1).  What is required to "fully initialize" it?

RockfordLhotka replied on Sunday, July 27, 2008

I honestly don’t remember – it was months ago I researched this :(

 

Some extra property needs to be set manually on the object if I remember right.

 

I just looked at the CSLA code – it is the Action property that must be explicitly set after the SecurityException object has been created.

 

Rocky

 

From: dlabar [mailto:cslanet@lhotka.net]
Sent: Sunday, July 27, 2008 1:35 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Difficulties using WcfPortal in Beta 1

 

I'm running version 3.0.3, should I try upgrading to 3.5.0?  I guess I could be throwing a security Exception myself (option number 1).  What is required to "fully initialize" it?

dlabar replied on Sunday, July 27, 2008

Does it matter what

System.Security.Permissions.SecurityAction

it is set to?

System.Security.Permissions.SecurityAction

RockfordLhotka replied on Sunday, July 27, 2008

I don’t know for sure…

 

From: dlabar [mailto:cslanet@lhotka.net]
Sent: Sunday, July 27, 2008 1:49 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: Difficulties using WcfPortal in Beta 1

 

Does it matter what

System.Security.Permissions.SecurityAction

it is set to?

System.Security.Permissions.SecurityAction



dlabar replied on Sunday, July 27, 2008

In answer to my own question... I'm going to guess not.  I'm going to guess that the System.Security.SecurityException.Action enum is defaulted to a value of 0, which is not valid.  I'm going to inherit from that class, and give it a default enum value, so that way I don't have to worry about it again.

 

Thanks a ton Rocky!

rfcdejong replied on Tuesday, January 17, 2012

Sorry for all, sorry for replying in such an old thread. But i bumped into this issue as well since i'm doing Windows authentication and my AuthenticationType should be "Windows", but we are using csla objects in windows workflow foundation activity's in the designer of visual studio. During metadata execution there is no config for visual studio so ConfigurationManager.AppSettings["CslaAuthentication"] returns null and the authentication type is set to "Csla".

Too bad the ApplicationContext.AuthenticationType cannot be set in code (without modifying or reflection)

On topic:
Because we are using windows authentication and the authentication type is set to csla, the principal is assigned so there is an security exception raised in the server DataPortal without a Action (it's slashed away)

The exception cannot be serialized so the following exception is visible

There was an error while trying to serialize parameter http://ws.lhotka.net/WcfDataPortal:FetchResult. The InnerException message was 'Enum value '0' is invalid for type 'System.Security.Permissions.SecurityAction' and cannot be serialized. Ensure that the necessary enum values are present and are marked with EnumMemberAttribute attribute if the type has DataContractAttribute attribute.'.  Please see InnerException for more details.

The code responsible:

            if (ApplicationContext.AuthenticationType == "Windows")
            {
                // When using integrated security, Principal must be null
                if (context.Principal != null)
                {
                    System.Security.SecurityException ex =
                      new System.Security.SecurityException(Resources.NoPrincipalAllowedException);
                    //ex.Action = System.Security.Permissions.SecurityAction.Deny;
                    throw ex;
                }
                // Set .NET to use integrated security
                AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
            }
 

RockfordLhotka replied on Tuesday, January 17, 2012

That code hasn't changed since we fixed the original issue a few years ago. I wonder if something changed with .NET since that time...

It appears we may have to entirely abandon the use of SecurityException - a breaking change, but one that may be necessary.

Kyle replied on Friday, October 19, 2012

I've just come across the same problem which caused me to spend a couple days researching. It turns out the problem was simply that I forgot to put 

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

In my WcfPortal web.config file.  But since the SecurityException wouldn't serialize, I had no clue what was going on.

I uncommented out the following line

//ex.Action = System.Security.Permissions.SecurityAction.Deny;

and tried again and the SecurityException was properly serialized and pointed me in the right direction, which is what it is supposed to do.

Presumably, this line was commented out because the enum 'Deny' is deprecated. However, it still works just fine. I recommend putting this line back in with the Deny value or putting it back in with the appropriate non-deprecated value (although I don't claim to know what is appropriate, I don't think it really matters).

 

Copyright (c) Marimer LLC