How to apply audit and/or authorization in a SOA situation

Posts   
 
    
dotprof
User
Posts: 20
Joined: 19-Feb-2010
# Posted on: 05-Apr-2010 14:43:38   

In the provided samples of LLBLGen for auditing the auditinfo (mostly a userinfo object) is retrieved using the thread principal in a windows forms environment or a variable in the session state for a Web application.

When crossing boundary's this approach is more difficult.

What approach would be advisable for a SOA architecture with a WCF. Using message headers and a messagecontract or perhaps using the IClientMessageInspector and IDispatchMessageInspector interfaces ?

I would consider reshaping the entity class or other classes from LLBLGen as bad practice (or am I wrong) and would like a hint how to inject an auditinfo object in the communication stream on a “channel” level, compared to using each operationcontract with an extra parameter for the auditinfo object.

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 05-Apr-2010 15:17:31   

In SOA, I think you should pass a user Token (e.g. his ID) in the message header.

Check this: WCF Custom Message Headers

dotprof
User
Posts: 20
Joined: 19-Feb-2010
# Posted on: 05-Apr-2010 19:47:58   

Thanks Walaa, After some trial and error I managed to pass a user string, using the WCF example from LLBLGen (see Example download page for WCF using C# and adapter model).. In the client project I added the following to the Main method:

 // Open a channel with the WCF service endpoint, and keep it alive till the end of the program.
            ChannelFactory<INorthwindService> channelFactory = new ChannelFactory<INorthwindService>("WCFServer");
            INorthwindService service = channelFactory.CreateChannel();
            string username = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
            MessageHeader userHeader = new MessageHeader<string>(username).GetUntypedHeader("userToken", "ns");
            OperationContextScope scope = new OperationContextScope((IContextChannel)service);
            OperationContext.Current.OutgoingMessageHeaders.Add(userHeader);

I now can read the domainname\username from the client program in every method of the CustomerService project e.g. :

string user = OperationContext.Current.IncomingMessageHeaders.GetHeader<string>("userToken", "ns");

For adding more info or complex types you have to make a class and inherit the MessageHeader type so you can serialize all the data required.

I am not sure how this works with encryption or signing of the soapheader using WCF .