views:

238

answers:

1

I have a WCF application that is using Windows Authentication. So a Windows Principal object is what I will find in the System.Threading.Thread.CurrentPrincipal() property. That's is all fine. However, I also have a custom principal object that is used for finer grained authorizations and auditing. This is a domain user, not a windows user. I really need both and am looking for a place to store the custom user on the service side so that all the code that runs on the service, down through Business and Data layers, can access this user.

The communication between client and server is handled by a custom behavior and message inspector. When calling the service from the client (ASP.NET Web Application), this gets the current user from session and serializes it to a custom header on the service call. On the service side it then strips the principal out of the header and puts the custom principal here:

OperationContext.Current.ServiceSecurityContext.AuthorizationContext.Properties("CurrentDomainUser")

So, questions to validate this approach:

  1. Is this a valid approach to storage of a custom principal on the service. Keeping in mind I want to Windows Authentication to stay in place.
  2. Is this "best practice"? Or is there a better way?
  3. Any traps or pitfalls to watch for with this approach?

Thanks for the input.

+1  A: 

I can't specifically answer if this is the best practice or not, but you can pass custom data in the outgoing message headers.

Here is an example calling a WCF service from the client

MyAccountService.MyAccountServiceClient client = new MyAccountServiceClient();
using (OperationContextScope scope = new OperationContextScope(client.InnerChannel))
{
    MessageHeader customHeader = MessageHeader.CreateHeader("customData", "ns", "My custom data");
    OperationContext.Current.OutgoingMessageHeaders.Add(customHeader);

    List<Bill> list = client.BillHistory("12345", DateTime.Now.AddMonths(-1), DateTime.Now);
}

On the service side, you can inspect the incoming message headers.

public IList<Bill> BillHistory(string accountID, DateTime datefrom, DateTime dateTo)
{
    string customData = OperationContext.Current.IncomingMessageHeaders.GetHeader<string>("customData", "ns");
...etc...
}
Pete Nelson
Pete: thanks for the input. We are using custom message headers to send our custom principal over the wire. The sticky part is: where to store the custom principal on the service side?
TheZenker
Once you get the principal on the service side, what do you need to do with it?
Pete Nelson