WCF Data Portal and Identity Management

WCF Data Portal and Identity Management

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


Diz posted on Thursday, March 06, 2008

I'm working on an intranet app - dual head Win/Web, based on CSLA business objects. 

Using CSLA 3.5 Beta 2, I'm trying to get WCF working for the dataportal.

Client requires WCF be hosted in a Windows Service.  I'm using a console app in place of the Windows Service for dev. 

I've been running into this and that error, am currently getting the "Invalid Token for impersonation - it cannot be duplicated." error.  This confuses me because there's nothing I know of causing impersonation. 
But that's not my main question.  I need access to the user's network username from within the dataportal so that I can use it to mark "who updated this" on rows.

I don't care about an actual identity or principal object, don't care about roles, etc, but if identity or principal comes across, that's fine too as it will give me the username that I need.

I keep reading that by default WCF will pass the windows identity, but no combination of my experimenting has actually allowed this to happen. 

It sounds like nothing in WCF is easy, but is there a known way to get this information to go across the wire?


App.config (WPF Client)
----------------------------------------
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
   
  <appSettings>
      <add key="CslaAuthentication" value="Csla" />
  
    <add key="CslaDataPortalProxy"
         value="Csla.DataPortalClient.WcfProxy, Csla"/>
  </appSettings>
 
  <system.serviceModel>
    <client>
      <endpoint name="WcfDataPortal"
                address="net.tcp://corpdev10knd:9090/WcfDataPortal"
                binding="netTcpBinding" 
                contract="Csla.Server.Hosts.IWcfPortal" />
    </client>
   
  </system.serviceModel>
</configuration>
----------------------------------------

Server app.config (WCF hosted in Windows Console App)
----------------------------------------
<?xml version="1.0" encoding="utf-8" ?>
<configuration>

  <appSettings>
    <add key="CslaAuthentication" value="Csla" />
   </appSettings>
 
  <system.serviceModel>
   
    <services>
      <!-- Before deployment, you should remove the returnFaults behavior configuration to avoid disclosing information in exception messages -->
      <service name="Csla.Server.Hosts.WcfPortal" behaviorConfiguration="returnFaults">
        <endpoint address="net.tcp://localhost:9090/WcfDataPortal"
                  contract="Csla.Server.Hosts.IWcfPortal"
                  binding="netTcpBinding"/>
      </service>
    </services>

    <behaviors>
      <serviceBehaviors>
        <behavior name="returnFaults">
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    
    </behaviors>
  </system.serviceModel>
 
</configuration>
----------------------------------------

Any advice would be appreciated.  Thanks!

liruiyt replied on Sunday, March 09, 2008

In the PT, there are two class about security, which are Principal.cs and Identity.cs.

And to deal with your problem, you just need to call the Login or Logout method of Principal class.

public static bool Login(string username, string password)

{}

public static void Logout()

{}

RockfordLhotka replied on Monday, March 10, 2008

Diz:

I keep reading that by default WCF will pass the windows identity, but no combination of my experimenting has actually allowed this to happen. 

That is true (sort of), but only when you host in IIS or WAS. If you host in your own custom process then you assume responsibility for things like impersonation and identity management - at least that's my understanding.

If you are using a custom CSLA principal, then the data portal will take care of the principal for you - but you'll still need to make sure your WCF host accepts requests without trying to do Windows impersonation - which probably requires some extra WCF configuration.

In my experience even hosting in IIS or WAS typically requires extra WCF configuration too. Rarely can you get away with the default WCF settings in a real app.

And you are right, nothing with WCF comes easy...

DazedAndConfused replied on Monday, May 19, 2008

We are using a framework wrapping CSLA in my company. Until recently, in most projects the server was hosted in IIS. I have built a new solution and am hosting this in a windows service. In order to provide logging by the server, I need to obtain the windows login of the user and use in the database fetch method.

We were using the ApplicationContext to return the user ID, this now has the account info for the IIS account, not the actual user.

We are using basicHttpBinding and I have the credentials set up and working in a test project. This involves using [(ServiceBehaviour(InstanceContextMode = InstanceContectMode.PerCall)] and [OperationBehaviour(Impersonation = ImpersonationOption.Required)] around the methods.

What I need to be able to do, it get this working with CSLA, but am unsure how to do this.

 

 

RockfordLhotka replied on Monday, May 19, 2008

ApplicationContext.User returns the current .NET principal. That’s all it does.

 

So if you are using Windows security (and it sounds like you are) then it is up to the server host (typically IIS) to impersonate the caller. If you are running in a custom Windows service then you will have to make your service do the impersonation – unless you can get WCF to do it for you, but I don’t know if that is possible.

 

This sounds like a pretty advanced scenario – with luck you can get some information from MSDN or either Juval or Michelle’s books in terms of how to implement impersonation with WCF in a custom Windows service.

 

Rocky

DazedAndConfused replied on Monday, May 19, 2008

Thanks for the reply. I can get WCF to do it, can send you code if you want?

It easy for me to do it if I have full control over the operations contracts, but the way we are using the CSLA / IWcfPortal means that I haven't got control of the operations contracts. These are in the IWcfPortal.cs. I am wondering if I just wrap these methods with the impersonation operation contract specifics, it may just work. This will be nicer solution than me having to change the code to have to pass the user name.

RockfordLhotka replied on Monday, May 19, 2008

The data portal is flexible, specifically to accommodate scenarios where people have needs beyond the basic ones provided by the standard data portal channels provided with CSLA.

 

In other words, you can create your own client-side proxy and server-side host classes and plug them into the data portal. This is not hard to do. Look at Chapter 5 in the Expert 2005 Business Objects book, or better at the CSLA .NET Version 2.1 Handbook to see how a proxy/host is created. You can take the existing WCF proxy/host classes and copy them into your own project, modify them and tell CSLA to use them.

 

Rocky

 

 

From: DazedAndConfused [mailto:cslanet@lhotka.net]
Sent: Monday, May 19, 2008 10:39 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: WCF Data Portal and Identity Management

 

Thanks for the reply. I can get WCF to do it, can send you code if you want?

It easy for me to do it if I have full control over the operations contracts, but the way we are using the CSLA / IWcfPortal means that I haven't got control of the operations contracts. These are in the IWcfPortal.cs. I am wondering if I just wrap these methods with the impersonation operation contract specifics, it may just work. This will be nicer solution than me having to change the code to have to pass the user name.



Copyright (c) Marimer LLC