Vibrant discussion about CSLA .NET and using the framework to build great business applications.
Wondering if someone can help me with an issue I'm having with accessing the data portal.
We are using CSLA version 3.6.2. with CSLA Authentication for the DataPortal.
We have developed a Windows Service that is responsible for generation of data sets that are shared amongst a number of clients. The service also hosts a WCF Services that exposes an endpoint that is consumed by a Pub/Sub implementation.
When the service starts up, it successfully connects to the data portal (via WCF) and builds the available datasets in the system. No problem.
When a new dataset definition is created by a client, the Windows Service receives the published event via the pub/sub and attempts to build the dataset from the newly created definition which was saved in the database. It at this point that the attempt to access the database fails with an error:
"Invalid token for impersonation - it cannot be duplicated."
During the initial call (when the service starts up) the DataPortalContext has no identity. When the callback method is invoked by the pub sub, the DataPortalContext has the identity of the host for the PubSub service. I know this because when I hosted the Pub/Sub service is IIS (via WAS), it tried to access the data portal with the identity IIS APPPOOL.
My initial solution was to add the following to the callback method
[OperationBehavior(Impersonation = ImpersonationOption.NotAllowed)]
This actually worked, at least initially. Now it doesn't and I am not sure why or how to get around the issue of the impersonation token duplication. I've read some previous posts that talk about double hops but I am not sure how to resolve that either.
Your assistance would be appreciated.
Have found an issue to the problem. We have a custom class that inherits from BusinessPrincipalBase and resets the ApplicationContext for the DataPortal to a new unauthenticated identity/principal. This then replaces the security context of the service call and resolves the impersination issue. Hope this helps some else in future.
This sounds like the classic double hop issue. Using Windows authentication, you can have Windows present a user token for validation to one machine. Typically you encounter the issue in this scenario:
Client computer (Web browser) -> Web server (Asp.net using Windows Authentication) -> Data server (Sql Server).
Each of these is a seperate physical machine. Windows Auth will have the token passed from client to web server. The web server will accept it (provided the DC says its a valid token). But that token CANNOT be handed to the data base server. That's be design, Windows domains won't allow a duplicated token to be used.
I suspect you're hitting something similar here. It sounds like your windows service allows clients to connect via Windows Auth, and the service then turns around and tries to contact the database server, also with Windows auth, which won't be allowed.
One option is to move the service to run on the database server. Another might be to prompt of the Windows username / password, then use it to create the principal on the app server using that username password to create a new token, although I don't know if that will work. If it does, you'll of course have to be careful, because now you're passing Windows logon information around your network..
Thanks for the suggestions Andy. The Windows Service is running on the same physical machine as the Data Portal. The WCF Service being hosted by the windows service is implementing a callback method which executes logic within it so it can't be moved.
What I need is a way to stop the credentials from being transferred from the WCF Service host process to the data portal. I thought by implementing the operation behaviour it would do that but for some reason its still coming through.
I'll take your suggestions on board and see if i can alter the security on the context before calling the data portal.
Ok, so it was the double hop issue then?